blob: b64cc54640c4871aa12292a9c79d9b96c2eb1dd9 [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]a93bb842010-02-16 23:03:4755#include "gpu/command_buffer/service/texture_manager.h"
[email protected]944b62f32012-09-27 02:20:4656#include "gpu/command_buffer/service/vertex_array_manager.h"
[email protected]f4390962013-06-11 07:29:2257#include "gpu/command_buffer/service/vertex_attrib_manager.h"
[email protected]d8bc3ec2013-03-07 06:28:4058#include "ui/gl/gl_bindings.h"
[email protected]5a36dc132013-07-23 23:17:5559#include "ui/gl/gl_fence.h"
[email protected]09d50362012-10-18 20:54:3760#include "ui/gl/gl_image.h"
[email protected]c9e2cbbb2012-05-12 21:17:2761#include "ui/gl/gl_implementation.h"
62#include "ui/gl/gl_surface.h"
[email protected]423e644f2013-06-19 00:48:2763
[email protected]e51bdf32011-11-23 22:21:4664#if defined(OS_MACOSX)
[email protected]423e644f2013-06-19 00:48:2765#include "ui/gl/io_surface_support_mac.h"
[email protected]e51bdf32011-11-23 22:21:4666#endif
[email protected]de17df392010-04-23 21:09:4167
[email protected]6eb775352013-08-27 05:57:1668#if defined(OS_WIN)
69#include "base/win/win_util.h"
70#endif
71
[email protected]693ca512012-11-13 18:09:1372// TODO(zmo): we can't include "City.h" due to type def conflicts.
73extern uint64 CityHash64(const char*, size_t);
74
[email protected]a7a27ace2009-12-12 00:11:2575namespace gpu {
[email protected]96449d2c2009-11-25 00:01:3276namespace gles2 {
77
[email protected]f0d74742011-10-03 16:31:0478namespace {
[email protected]693ca512012-11-13 18:09:1379
[email protected]f0d74742011-10-03 16:31:0480static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
[email protected]70dc60932013-06-04 03:33:4981static const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
[email protected]aff39ac82013-06-08 04:53:1382static const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
[email protected]693ca512012-11-13 18:09:1383
[email protected]3d944a82013-02-12 19:09:0284#if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
[email protected]693ca512012-11-13 18:09:1385khronos_uint64_t CityHashForAngle(const char* name, unsigned int len) {
86 return static_cast<khronos_uint64_t>(
87 CityHash64(name, static_cast<size_t>(len)));
88}
[email protected]3d944a82013-02-12 19:09:0289#endif
[email protected]693ca512012-11-13 18:09:1390
[email protected]448e459e2013-06-12 17:00:4191static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
92 GLint rangeMax,
93 GLint precision) {
94 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
95}
96
[email protected]8dc1bf92013-03-12 03:58:2197static void GetShaderPrecisionFormatImpl(GLenum shader_type,
98 GLenum precision_type,
99 GLint *range, GLint *precision) {
100 switch (precision_type) {
101 case GL_LOW_INT:
102 case GL_MEDIUM_INT:
103 case GL_HIGH_INT:
104 // These values are for a 32-bit twos-complement integer format.
105 range[0] = 31;
106 range[1] = 30;
107 *precision = 0;
108 break;
109 case GL_LOW_FLOAT:
110 case GL_MEDIUM_FLOAT:
111 case GL_HIGH_FLOAT:
112 // These values are for an IEEE single-precision floating-point format.
113 range[0] = 127;
114 range[1] = 127;
115 *precision = 23;
116 break;
117 default:
118 NOTREACHED();
119 break;
120 }
121
[email protected]8af4d5e2013-03-15 23:55:33122 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
123 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) {
[email protected]8dc1bf92013-03-12 03:58:21124 // This function is sometimes defined even though it's really just
125 // a stub, so we need to set range and precision as if it weren't
126 // defined before calling it.
[email protected]501b57402013-03-14 22:21:44127 // On Mac OS with some GPUs, calling this generates a
128 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
129 // platforms.
[email protected]8dc1bf92013-03-12 03:58:21130 glGetShaderPrecisionFormat(shader_type, precision_type,
131 range, precision);
[email protected]448e459e2013-06-12 17:00:41132
133 // TODO(brianderson): Make the following official workarounds.
134
135 // Some drivers have bugs where they report the ranges as a negative number.
136 // Taking the absolute value here shouldn't hurt because negative numbers
137 // aren't expected anyway.
138 range[0] = abs(range[0]);
139 range[1] = abs(range[1]);
140
141 // If the driver reports a precision for highp float that isn't actually
142 // highp, don't pretend like it's supported because shader compilation will
143 // fail anyway.
144 if (precision_type == GL_HIGH_FLOAT &&
145 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
146 range[0] = 0;
147 range[1] = 0;
148 *precision = 0;
149 }
[email protected]8dc1bf92013-03-12 03:58:21150 }
151}
152
[email protected]b04e24c2013-01-08 18:35:25153} // namespace
[email protected]f0d74742011-10-03 16:31:04154
[email protected]6217d392010-03-25 22:08:35155class GLES2DecoderImpl;
156
[email protected]ab09b612013-03-11 22:11:51157// Local versions of the SET_GL_ERROR macros
158#define LOCAL_SET_GL_ERROR(error, function_name, msg) \
[email protected]d3eba342013-04-18 21:11:50159 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
[email protected]ab09b612013-03-11 22:11:51160#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
[email protected]d3eba342013-04-18 21:11:50161 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
162 function_name, value, label)
[email protected]ab09b612013-03-11 22:11:51163#define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \
[email protected]d3eba342013-04-18 21:11:50164 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \
165 function_name, pname)
[email protected]ab09b612013-03-11 22:11:51166#define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
[email protected]d3eba342013-04-18 21:11:50167 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \
168 function_name)
[email protected]ab09b612013-03-11 22:11:51169#define LOCAL_PEEK_GL_ERROR(function_name) \
[email protected]d3eba342013-04-18 21:11:50170 ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51171#define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
[email protected]d3eba342013-04-18 21:11:50172 ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51173#define LOCAL_PERFORMANCE_WARNING(msg) \
174 PerformanceWarning(__FILE__, __LINE__, msg)
175#define LOCAL_RENDER_WARNING(msg) \
176 RenderWarning(__FILE__, __LINE__, msg)
177
[email protected]07f54fcc2009-12-22 02:46:30178// Check that certain assumptions the code makes are true. There are places in
179// the code where shared memory is passed direclty to GL. Example, glUniformiv,
180// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
181// a few others) are 32bits. If they are not 32bits the code will have to change
182// to call those GL functions with service side memory and then copy the results
183// to shared memory, converting the sizes.
184COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT
185 GLint_not_same_size_as_uint32);
186COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT
187 GLint_not_same_size_as_uint32);
[email protected]f7b85372010-02-03 01:11:37188COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT
189 GLfloat_not_same_size_as_float);
[email protected]07f54fcc2009-12-22 02:46:30190
[email protected]43f28f832010-02-03 02:28:48191// TODO(kbr): the use of this anonymous namespace core dumps the
192// linker on Mac OS X 10.6 when the symbol ordering file is used
193// namespace {
[email protected]96449d2c2009-11-25 00:01:32194
195// Returns the address of the first byte after a struct.
196template <typename T>
197const void* AddressAfterStruct(const T& pod) {
198 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
199}
200
[email protected]07f54fcc2009-12-22 02:46:30201// Returns the address of the frst byte after the struct or NULL if size >
202// immediate_data_size.
[email protected]96449d2c2009-11-25 00:01:32203template <typename RETURN_TYPE, typename COMMAND_TYPE>
[email protected]07f54fcc2009-12-22 02:46:30204RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
205 uint32 size,
206 uint32 immediate_data_size) {
207 return (size <= immediate_data_size) ?
208 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
209 NULL;
[email protected]96449d2c2009-11-25 00:01:32210}
211
[email protected]07f54fcc2009-12-22 02:46:30212// Computes the data size for certain gl commands like glUniform.
[email protected]a76b0052010-03-05 00:33:18213bool ComputeDataSize(
[email protected]96449d2c2009-11-25 00:01:32214 GLuint count,
215 size_t size,
[email protected]a76b0052010-03-05 00:33:18216 unsigned int elements_per_unit,
217 uint32* dst) {
218 uint32 value;
219 if (!SafeMultiplyUint32(count, size, &value)) {
220 return false;
221 }
222 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
223 return false;
224 }
225 *dst = value;
226 return true;
[email protected]96449d2c2009-11-25 00:01:32227}
228
229// A struct to hold info about each command.
230struct CommandInfo {
[email protected]cac16542014-01-15 17:53:51231 uint8 arg_flags; // How to handle the arguments for this command
232 uint8 cmd_flags; // How to handle this command
233 uint16 arg_count; // How many arguments are expected for this command.
[email protected]96449d2c2009-11-25 00:01:32234};
235
[email protected]cac16542014-01-15 17:53:51236// cmds::name::cmd_flags,
[email protected]96449d2c2009-11-25 00:01:32237// A table of CommandInfo for all the commands.
238const CommandInfo g_command_info[] = {
[email protected]ed9f9cd2013-02-27 21:12:35239 #define GLES2_CMD_OP(name) { \
240 cmds::name::kArgFlags, \
[email protected]cac16542014-01-15 17:53:51241 cmds::name::cmd_flags, \
242 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */
[email protected]96449d2c2009-11-25 00:01:32243
244 GLES2_COMMAND_LIST(GLES2_CMD_OP)
245
246 #undef GLES2_CMD_OP
247};
248
[email protected]258a3313f2011-10-18 20:13:57249// Return true if a character belongs to the ASCII subset as defined in
250// GLSL ES 1.0 spec section 3.1.
251static bool CharacterIsValidForGLES(unsigned char c) {
252 // Printing characters are valid except " $ ` @ \ ' DEL.
253 if (c >= 32 && c <= 126 &&
254 c != '"' &&
255 c != '$' &&
256 c != '`' &&
257 c != '@' &&
258 c != '\\' &&
259 c != '\'') {
260 return true;
261 }
262 // Horizontal tab, line feed, vertical tab, form feed, carriage return
263 // are also valid.
264 if (c >= 9 && c <= 13) {
265 return true;
266 }
267
268 return false;
269}
270
271static bool StringIsValidForGLES(const char* str) {
272 for (; *str; ++str) {
273 if (!CharacterIsValidForGLES(*str)) {
274 return false;
275 }
276 }
277 return true;
278}
279
[email protected]297ca1c2011-06-20 23:08:46280// Wrapper for glEnable/glDisable that doesn't suck.
281static void EnableDisable(GLenum pname, bool enable) {
282 if (enable) {
283 glEnable(pname);
284 } else {
285 glDisable(pname);
286 }
287}
288
[email protected]6217d392010-03-25 22:08:35289// This class prevents any GL errors that occur when it is in scope from
290// being reported to the client.
291class ScopedGLErrorSuppressor {
292 public:
[email protected]ab09b612013-03-11 22:11:51293 explicit ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:30294 const char* function_name, ErrorState* error_state);
[email protected]6217d392010-03-25 22:08:35295 ~ScopedGLErrorSuppressor();
296 private:
[email protected]ab09b612013-03-11 22:11:51297 const char* function_name_;
[email protected]40621eb52013-10-08 15:40:30298 ErrorState* error_state_;
[email protected]6217d392010-03-25 22:08:35299 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
300};
301
[email protected]2b10c02d2014-01-29 16:43:02302// Temporarily changes a decoder's bound texture and restore it when this
[email protected]6217d392010-03-25 22:08:35303// object goes out of scope. Also temporarily switches to using active texture
304// unit zero in case the client has changed that to something invalid.
[email protected]2b10c02d2014-01-29 16:43:02305class ScopedTextureBinder {
[email protected]6217d392010-03-25 22:08:35306 public:
[email protected]2b10c02d2014-01-29 16:43:02307 ScopedTextureBinder(ContextState* state, GLuint id, GLenum target);
308 ~ScopedTextureBinder();
[email protected]6217d392010-03-25 22:08:35309
310 private:
[email protected]ce296892013-10-24 22:04:36311 ContextState* state_;
[email protected]2b10c02d2014-01-29 16:43:02312 GLenum target_;
313 DISALLOW_COPY_AND_ASSIGN(ScopedTextureBinder);
[email protected]6217d392010-03-25 22:08:35314};
315
316// Temporarily changes a decoder's bound render buffer and restore it when this
317// object goes out of scope.
318class ScopedRenderBufferBinder {
319 public:
[email protected]18e785a2013-10-09 03:29:41320 ScopedRenderBufferBinder(ContextState* state, GLuint id);
[email protected]6217d392010-03-25 22:08:35321 ~ScopedRenderBufferBinder();
322
323 private:
[email protected]18e785a2013-10-09 03:29:41324 ContextState* state_;
[email protected]6217d392010-03-25 22:08:35325 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
326};
327
328// Temporarily changes a decoder's bound frame buffer and restore it when this
329// object goes out of scope.
330class ScopedFrameBufferBinder {
331 public:
332 ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
333 ~ScopedFrameBufferBinder();
334
335 private:
336 GLES2DecoderImpl* decoder_;
337 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
338};
339
[email protected]34ff8b0c2010-10-01 20:06:02340// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52341// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27342// if it is bound or enforce_internal_framebuffer is true. If internal is
343// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02344class ScopedResolvedFrameBufferBinder {
345 public:
[email protected]e7e38032011-07-26 17:25:25346 ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
[email protected]de26b3c2011-08-03 21:54:27347 bool enforce_internal_framebuffer,
348 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02349 ~ScopedResolvedFrameBufferBinder();
350
351 private:
352 GLES2DecoderImpl* decoder_;
353 bool resolve_and_bind_;
354 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
355};
356
[email protected]6217d392010-03-25 22:08:35357// Encapsulates an OpenGL texture.
[email protected]ed9f9cd2013-02-27 21:12:35358class BackTexture {
[email protected]6217d392010-03-25 22:08:35359 public:
[email protected]ce296892013-10-24 22:04:36360 explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35361 ~BackTexture();
[email protected]6217d392010-03-25 22:08:35362
363 // Create a new render texture.
364 void Create();
365
366 // Set the initial size and format of a render texture or resize it.
[email protected]678a73f2012-12-19 19:22:09367 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
[email protected]6217d392010-03-25 22:08:35368
369 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58370 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35371
372 // Destroy the render texture. This must be explicitly called before
373 // destroying this object.
374 void Destroy();
375
[email protected]97872062010-11-03 19:07:05376 // Invalidate the texture. This can be used when a context is lost and it is
377 // not possible to make it current in order to free the resource.
378 void Invalidate();
379
[email protected]6217d392010-03-25 22:08:35380 GLuint id() const {
381 return id_;
382 }
383
[email protected]d37231fa2010-04-09 21:16:02384 gfx::Size size() const {
385 return size_;
386 }
387
[email protected]6217d392010-03-25 22:08:35388 private:
[email protected]ff6493f2012-07-31 19:52:25389 MemoryTypeTracker memory_tracker_;
[email protected]ce296892013-10-24 22:04:36390 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48391 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35392 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02393 gfx::Size size_;
[email protected]ed9f9cd2013-02-27 21:12:35394 DISALLOW_COPY_AND_ASSIGN(BackTexture);
[email protected]6217d392010-03-25 22:08:35395};
396
397// Encapsulates an OpenGL render buffer of any format.
[email protected]ed9f9cd2013-02-27 21:12:35398class BackRenderbuffer {
[email protected]6217d392010-03-25 22:08:35399 public:
[email protected]d5a28e452013-10-10 01:01:40400 explicit BackRenderbuffer(
401 RenderbufferManager* renderbuffer_manager,
402 MemoryTracker* memory_tracker,
403 ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35404 ~BackRenderbuffer();
[email protected]6217d392010-03-25 22:08:35405
406 // Create a new render buffer.
407 void Create();
408
409 // Set the initial size and format of a render buffer or resize it.
[email protected]f42f05b2013-11-15 21:46:18410 bool AllocateStorage(const FeatureInfo* feature_info,
411 const gfx::Size& size,
412 GLenum format,
413 GLsizei samples);
[email protected]6217d392010-03-25 22:08:35414
415 // Destroy the render buffer. This must be explicitly called before destroying
416 // this object.
417 void Destroy();
418
[email protected]97872062010-11-03 19:07:05419 // Invalidate the render buffer. This can be used when a context is lost and
420 // it is not possible to make it current in order to free the resource.
421 void Invalidate();
422
[email protected]6217d392010-03-25 22:08:35423 GLuint id() const {
424 return id_;
425 }
426
427 private:
[email protected]d5a28e452013-10-10 01:01:40428 RenderbufferManager* renderbuffer_manager_;
[email protected]ff6493f2012-07-31 19:52:25429 MemoryTypeTracker memory_tracker_;
[email protected]d5a28e452013-10-10 01:01:40430 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48431 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35432 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35433 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
[email protected]6217d392010-03-25 22:08:35434};
435
436// Encapsulates an OpenGL frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35437class BackFramebuffer {
[email protected]6217d392010-03-25 22:08:35438 public:
[email protected]ed9f9cd2013-02-27 21:12:35439 explicit BackFramebuffer(GLES2DecoderImpl* decoder);
440 ~BackFramebuffer();
[email protected]6217d392010-03-25 22:08:35441
442 // Create a new frame buffer.
443 void Create();
444
445 // Attach a color render buffer to a frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35446 void AttachRenderTexture(BackTexture* texture);
[email protected]6217d392010-03-25 22:08:35447
[email protected]b9363b22010-06-09 22:06:15448 // Attach a render buffer to a frame buffer. Note that this unbinds any
449 // currently bound frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35450 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35451
[email protected]6217d392010-03-25 22:08:35452 // Destroy the frame buffer. This must be explicitly called before destroying
453 // this object.
454 void Destroy();
455
[email protected]97872062010-11-03 19:07:05456 // Invalidate the frame buffer. This can be used when a context is lost and it
457 // is not possible to make it current in order to free the resource.
458 void Invalidate();
459
[email protected]6217d392010-03-25 22:08:35460 // See glCheckFramebufferStatusEXT.
461 GLenum CheckStatus();
462
463 GLuint id() const {
464 return id_;
465 }
466
467 private:
468 GLES2DecoderImpl* decoder_;
469 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35470 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
[email protected]6217d392010-03-25 22:08:35471};
[email protected]34ff8b0c2010-10-01 20:06:02472
[email protected]5a36dc132013-07-23 23:17:55473struct FenceCallback {
474 explicit FenceCallback()
475 : fence(gfx::GLFence::Create()) {
476 DCHECK(fence);
477 }
[email protected]5a36dc132013-07-23 23:17:55478 std::vector<base::Closure> callbacks;
479 scoped_ptr<gfx::GLFence> fence;
480};
481
[email protected]43f28f832010-02-03 02:28:48482// } // anonymous namespace.
[email protected]96449d2c2009-11-25 00:01:32483
[email protected]ddb1e5a2010-12-13 20:10:45484bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
485 uint32* service_texture_id) {
486 return false;
487}
488
[email protected]a3ded6d2010-10-19 06:44:39489GLES2Decoder::GLES2Decoder()
[email protected]55e136f2013-04-03 18:50:06490 : initialized_(false),
491 debug_(false),
[email protected]1d82e822013-04-10 21:32:32492 log_commands_(false) {
[email protected]96449d2c2009-11-25 00:01:32493}
494
[email protected]3916c97e2010-02-25 03:20:50495GLES2Decoder::~GLES2Decoder() {
496}
497
[email protected]cac16542014-01-15 17:53:51498void GLES2Decoder::BeginDecoding() {}
499
500void GLES2Decoder::EndDecoding() {}
501
[email protected]f39f4b3f2010-05-12 17:04:08502// This class implements GLES2Decoder so we don't have to expose all the GLES2
503// cmd stuff to outside this class.
[email protected]91c94eb2013-10-22 10:32:54504class GLES2DecoderImpl : public GLES2Decoder,
505 public FramebufferManager::TextureDetachObserver {
[email protected]f39f4b3f2010-05-12 17:04:08506 public:
[email protected]476ccb72012-12-06 15:52:52507 // Used by PrepForSetUniformByLocation to validate types.
508 struct BaseUniformInfo {
509 const GLenum* const valid_types;
510 size_t num_valid_types;
511 };
512
[email protected]aa7666122011-09-02 19:45:52513 explicit GLES2DecoderImpl(ContextGroup* group);
[email protected]b8e97b62012-09-30 15:09:00514 virtual ~GLES2DecoderImpl();
[email protected]f39f4b3f2010-05-12 17:04:08515
[email protected]96449d2c2009-11-25 00:01:32516 // Overridden from AsyncAPIInterface.
[email protected]f7a64ee2010-02-01 22:24:14517 virtual Error DoCommand(unsigned int command,
[email protected]3916c97e2010-02-25 03:20:50518 unsigned int arg_count,
[email protected]b8e97b62012-09-30 15:09:00519 const void* args) OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32520
521 // Overridden from AsyncAPIInterface.
[email protected]b8e97b62012-09-30 15:09:00522 virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32523
524 // Overridden from GLES2Decoder.
[email protected]fbe20372011-06-01 01:46:38525 virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
526 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:23527 bool offscreen,
[email protected]6217d392010-03-25 22:08:35528 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:29529 const DisallowedFeatures& disallowed_features,
[email protected]b8e97b62012-09-30 15:09:00530 const std::vector<int32>& attribs) OVERRIDE;
531 virtual void Destroy(bool have_context) OVERRIDE;
[email protected]63c9b052012-05-17 18:27:38532 virtual void SetSurface(
533 const scoped_refptr<gfx::GLSurface>& surface) OVERRIDE;
[email protected]aba551b2014-02-08 03:38:32534 virtual void ProduceFrontBuffer(const Mailbox& mailbox) OVERRIDE;
[email protected]b8e97b62012-09-30 15:09:00535 virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) OVERRIDE;
[email protected]9a5afa432011-07-22 18:16:39536 void UpdateParentTextureInfo();
[email protected]b8e97b62012-09-30 15:09:00537 virtual bool MakeCurrent() OVERRIDE;
[email protected]b8e97b62012-09-30 15:09:00538 virtual GLES2Util* GetGLES2Util() OVERRIDE { return &util_; }
539 virtual gfx::GLContext* GetGLContext() OVERRIDE { return context_.get(); }
540 virtual ContextGroup* GetContextGroup() OVERRIDE { return group_.get(); }
[email protected]6d668892013-12-04 21:37:12541 virtual Capabilities GetCapabilities() OVERRIDE;
[email protected]5baa86bc2014-01-16 04:33:16542 virtual void RestoreState(const ContextState* prev_state) const OVERRIDE;
[email protected]29a4d902013-02-26 20:18:06543
544 virtual void RestoreActiveTexture() const OVERRIDE {
545 state_.RestoreActiveTexture();
546 }
[email protected]5baa86bc2014-01-16 04:33:16547 virtual void RestoreAllTextureUnitBindings(
548 const ContextState* prev_state) const OVERRIDE {
549 state_.RestoreAllTextureUnitBindings(prev_state);
[email protected]217004512013-05-10 21:25:55550 }
[email protected]29a4d902013-02-26 20:18:06551 virtual void RestoreAttribute(unsigned index) const OVERRIDE {
552 state_.RestoreAttribute(index);
553 }
554 virtual void RestoreBufferBindings() const OVERRIDE {
555 state_.RestoreBufferBindings();
556 }
557 virtual void RestoreGlobalState() const OVERRIDE {
558 state_.RestoreGlobalState();
559 }
560 virtual void RestoreProgramBindings() const OVERRIDE {
561 state_.RestoreProgramBindings();
562 }
[email protected]29a4d902013-02-26 20:18:06563 virtual void RestoreTextureUnitBindings(unsigned unit) const OVERRIDE {
[email protected]5baa86bc2014-01-16 04:33:16564 state_.RestoreTextureUnitBindings(unit, NULL);
[email protected]29a4d902013-02-26 20:18:06565 }
566 virtual void RestoreFramebufferBindings() const OVERRIDE;
567 virtual void RestoreTextureState(unsigned service_id) const OVERRIDE;
568
[email protected]cd2ef752014-02-12 23:16:03569 virtual void ClearAllAttributes() const OVERRIDE;
570 virtual void RestoreAllAttributes() const OVERRIDE;
571
[email protected]b8e97b62012-09-30 15:09:00572 virtual QueryManager* GetQueryManager() OVERRIDE {
573 return query_manager_.get();
574 }
575 virtual VertexArrayManager* GetVertexArrayManager() OVERRIDE {
[email protected]944b62f32012-09-27 02:20:46576 return vertex_array_manager_.get();
577 }
[email protected]b8e97b62012-09-30 15:09:00578 virtual bool ProcessPendingQueries() OVERRIDE;
[email protected]2b1767cf2013-03-16 09:25:05579 virtual bool HasMoreIdleWork() OVERRIDE;
580 virtual void PerformIdleWork() OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48581
[email protected]5a36dc132013-07-23 23:17:55582 virtual void WaitForReadPixels(base::Closure callback) OVERRIDE;
583
[email protected]9d37f062011-11-22 01:24:52584 virtual void SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:07585 const base::Callback<void(gfx::Size, float)>& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00586
[email protected]1d82e822013-04-10 21:32:32587 virtual Logger* GetLogger() OVERRIDE;
[email protected]cac16542014-01-15 17:53:51588
589 virtual void BeginDecoding() OVERRIDE;
590 virtual void EndDecoding() OVERRIDE;
591
[email protected]d3eba342013-04-18 21:11:50592 virtual ErrorState* GetErrorState() OVERRIDE;
[email protected]5baa86bc2014-01-16 04:33:16593 virtual const ContextState* GetContextState() OVERRIDE { return &state_; }
[email protected]1d82e822013-04-10 21:32:32594
[email protected]e3932abb2013-03-13 00:01:37595 virtual void SetShaderCacheCallback(
596 const ShaderCacheCallback& callback) OVERRIDE;
[email protected]840a7e462013-02-27 01:29:51597 virtual void SetWaitSyncPointCallback(
598 const WaitSyncPointCallback& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00599
[email protected]85a4ac22013-05-31 01:58:47600 virtual AsyncPixelTransferManager*
601 GetAsyncPixelTransferManager() OVERRIDE;
602 virtual void ResetAsyncPixelTransferManagerForTest() OVERRIDE;
[email protected]498b5c072013-06-04 19:30:07603 virtual void SetAsyncPixelTransferManagerForTest(
604 AsyncPixelTransferManager* manager) OVERRIDE;
[email protected]69a8701e2013-03-07 21:31:09605 void ProcessFinishedAsyncTransfers();
[email protected]32145a92012-12-17 09:01:59606
[email protected]1318e922010-09-17 22:03:16607 virtual bool GetServiceTextureId(uint32 client_texture_id,
[email protected]b8e97b62012-09-30 15:09:00608 uint32* service_texture_id) OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48609
[email protected]63b465922012-09-06 02:04:52610 virtual uint32 GetTextureUploadCount() OVERRIDE;
611 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE;
612 virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE;
[email protected]dc25dda2012-09-27 21:36:30613 virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE;
[email protected]63b465922012-09-06 02:04:52614
[email protected]8e3e0662010-08-23 18:46:30615 // Restores the current state to the user's settings.
616 void RestoreCurrentFramebufferBindings();
[email protected]8e3e0662010-08-23 18:46:30617
[email protected]297ca1c2011-06-20 23:08:46618 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
619 void ApplyDirtyState();
620
621 // These check the state of the currently bound framebuffer or the
622 // backbuffer if no framebuffer is bound.
[email protected]f3b191b2013-06-19 03:43:54623 // If all_draw_buffers is false, only check with COLOR_ATTACHMENT0, otherwise
624 // check with all attached and enabled color attachments.
625 bool BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers);
[email protected]297ca1c2011-06-20 23:08:46626 bool BoundFramebufferHasDepthAttachment();
627 bool BoundFramebufferHasStencilAttachment();
628
[email protected]b8e97b62012-09-30 15:09:00629 virtual error::ContextLostReason GetContextLostReason() OVERRIDE;
[email protected]38d139d2011-07-14 00:38:43630
[email protected]91c94eb2013-10-22 10:32:54631 // Overridden from FramebufferManager::TextureDetachObserver:
632 virtual void OnTextureRefDetachedFromFramebuffer(
633 TextureRef* texture) OVERRIDE;
634
[email protected]f42f05b2013-11-15 21:46:18635 // Helpers to facilitate calling into compatible extensions.
636 static void RenderbufferStorageMultisampleHelper(
637 const FeatureInfo* feature_info,
638 GLenum target,
639 GLsizei samples,
640 GLenum internal_format,
641 GLsizei width,
642 GLsizei height);
643
644 void BlitFramebufferHelper(GLint srcX0,
645 GLint srcY0,
646 GLint srcX1,
647 GLint srcY1,
648 GLint dstX0,
649 GLint dstY0,
650 GLint dstX1,
651 GLint dstY1,
652 GLbitfield mask,
653 GLenum filter);
[email protected]345ba902013-11-14 21:39:00654
[email protected]96449d2c2009-11-25 00:01:32655 private:
[email protected]70d34263c2013-01-09 00:27:45656 friend class ScopedFrameBufferBinder;
[email protected]34ff8b0c2010-10-01 20:06:02657 friend class ScopedResolvedFrameBufferBinder;
[email protected]ed9f9cd2013-02-27 21:12:35658 friend class BackFramebuffer;
[email protected]6217d392010-03-25 22:08:35659
[email protected]c2f8c8402010-12-06 18:07:24660 // Initialize or re-initialize the shader translator.
661 bool InitializeShaderTranslator();
662
[email protected]302ce6d2011-07-07 23:28:11663 void UpdateCapabilities();
664
[email protected]ae51d192010-04-27 00:48:03665 // Helpers for the glGen and glDelete functions.
666 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
667 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
668 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
669 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
670 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
671 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
672 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
673 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53674 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
675 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46676 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
677 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47678
[email protected]70d34263c2013-01-09 00:27:45679 // Workarounds
680 void OnFboChanged() const;
[email protected]28718a92013-04-04 12:12:51681 void OnUseFramebuffer() const;
[email protected]70d34263c2013-01-09 00:27:45682
[email protected]3916c97e2010-02-25 03:20:50683 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50684 BufferManager* buffer_manager() {
685 return group_->buffer_manager();
686 }
687
[email protected]a25fa872010-03-25 02:57:58688 RenderbufferManager* renderbuffer_manager() {
689 return group_->renderbuffer_manager();
690 }
691
692 FramebufferManager* framebuffer_manager() {
693 return group_->framebuffer_manager();
694 }
695
[email protected]3916c97e2010-02-25 03:20:50696 ProgramManager* program_manager() {
697 return group_->program_manager();
698 }
699
700 ShaderManager* shader_manager() {
701 return group_->shader_manager();
702 }
703
[email protected]29a4d902013-02-26 20:18:06704 const TextureManager* texture_manager() const {
705 return group_->texture_manager();
706 }
707
[email protected]3916c97e2010-02-25 03:20:50708 TextureManager* texture_manager() {
709 return group_->texture_manager();
710 }
711
[email protected]78b514b2012-05-01 21:50:59712 MailboxManager* mailbox_manager() {
713 return group_->mailbox_manager();
714 }
715
[email protected]09d50362012-10-18 20:54:37716 ImageManager* image_manager() {
717 return group_->image_manager();
718 }
719
[email protected]944b62f32012-09-27 02:20:46720 VertexArrayManager* vertex_array_manager() {
721 return vertex_array_manager_.get();
722 }
723
[email protected]7989c9e2013-01-23 06:39:26724 MemoryTracker* memory_tracker() {
725 return group_->memory_tracker();
726 }
727
728 bool EnsureGPUMemoryAvailable(size_t estimated_size) {
729 MemoryTracker* tracker = memory_tracker();
730 if (tracker) {
731 return tracker->EnsureGPUMemoryAvailable(estimated_size);
732 }
733 return true;
734 }
735
[email protected]34ff8b0c2010-10-01 20:06:02736 bool IsOffscreenBufferMultisampled() const {
737 return offscreen_target_samples_ > 1;
738 }
739
[email protected]ed9f9cd2013-02-27 21:12:35740 // Creates a Texture for the given texture.
[email protected]370eaf12013-05-18 09:19:49741 TextureRef* CreateTexture(
[email protected]ae51d192010-04-27 00:48:03742 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35743 return texture_manager()->CreateTexture(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47744 }
745
746 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]370eaf12013-05-18 09:19:49747 TextureRef* GetTexture(GLuint client_id) const {
[email protected]02965c22013-03-09 02:40:07748 return texture_manager()->GetTexture(client_id);
[email protected]a93bb842010-02-16 23:03:47749 }
750
751 // Deletes the texture info for the given texture.
[email protected]ed9f9cd2013-02-27 21:12:35752 void RemoveTexture(GLuint client_id) {
753 texture_manager()->RemoveTexture(client_id);
[email protected]3916c97e2010-02-25 03:20:50754 }
[email protected]a93bb842010-02-16 23:03:47755
[email protected]d37231fa2010-04-09 21:16:02756 // Get the size (in pixels) of the currently bound frame buffer (either FBO
757 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30758 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02759
[email protected]9edc6b22010-12-23 02:00:26760 // Get the format of the currently bound frame buffer (either FBO or regular
761 // back buffer)
[email protected]68586372013-12-11 01:27:59762 GLenum GetBoundReadFrameBufferTextureType();
[email protected]9edc6b22010-12-23 02:00:26763 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46764 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26765
[email protected]a93bb842010-02-16 23:03:47766 // Wrapper for CompressedTexImage2D commands.
767 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37768 GLenum target,
769 GLint level,
770 GLenum internal_format,
771 GLsizei width,
772 GLsizei height,
773 GLint border,
774 GLsizei image_size,
775 const void* data);
[email protected]a93bb842010-02-16 23:03:47776
[email protected]cadde4a2010-07-31 17:10:43777 // Wrapper for CompressedTexSubImage2D.
778 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37779 GLenum target,
780 GLint level,
781 GLint xoffset,
782 GLint yoffset,
783 GLsizei width,
784 GLsizei height,
785 GLenum format,
786 GLsizei imageSize,
787 const void * data);
[email protected]cadde4a2010-07-31 17:10:43788
789 // Wrapper for CopyTexImage2D.
790 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37791 GLenum target,
792 GLint level,
793 GLenum internal_format,
794 GLint x,
795 GLint y,
796 GLsizei width,
797 GLsizei height,
798 GLint border);
[email protected]cadde4a2010-07-31 17:10:43799
[email protected]6d792ee12013-05-15 00:40:56800 // Wrapper for SwapBuffers.
801 void DoSwapBuffers();
802
[email protected]cadde4a2010-07-31 17:10:43803 // Wrapper for CopyTexSubImage2D.
804 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37805 GLenum target,
806 GLint level,
807 GLint xoffset,
808 GLint yoffset,
809 GLint x,
810 GLint y,
811 GLsizei width,
812 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43813
[email protected]f598f422012-12-07 08:30:03814 // Validation for TexSubImage2D.
815 bool ValidateTexSubImage2D(
816 error::Error* error,
817 const char* function_name,
818 GLenum target,
819 GLint level,
820 GLint xoffset,
821 GLint yoffset,
822 GLsizei width,
823 GLsizei height,
824 GLenum format,
825 GLenum type,
826 const void * data);
827
[email protected]cadde4a2010-07-31 17:10:43828 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03829 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37830 GLenum target,
831 GLint level,
832 GLint xoffset,
833 GLint yoffset,
834 GLsizei width,
835 GLsizei height,
836 GLenum format,
837 GLenum type,
838 const void * data);
[email protected]cadde4a2010-07-31 17:10:43839
[email protected]32145a92012-12-17 09:01:59840 // Extra validation for async tex(Sub)Image2D.
841 bool ValidateAsyncTransfer(
842 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:47843 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:59844 GLenum target,
845 GLint level,
846 const void * data);
847
[email protected]e51bdf32011-11-23 22:21:46848 // Wrapper for TexImageIOSurface2DCHROMIUM.
849 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37850 GLenum target,
851 GLsizei width,
852 GLsizei height,
853 GLuint io_surface_id,
854 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46855
[email protected]43410e92012-04-20 17:06:28856 void DoCopyTextureCHROMIUM(
[email protected]09d50362012-10-18 20:54:37857 GLenum target,
858 GLuint source_id,
859 GLuint target_id,
860 GLint level,
[email protected]a4a6bdd12013-04-19 20:46:54861 GLenum internal_format,
862 GLenum dest_type);
[email protected]43410e92012-04-20 17:06:28863
[email protected]97dc7cbe2011-12-06 17:26:17864 // Wrapper for TexStorage2DEXT.
865 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37866 GLenum target,
867 GLint levels,
868 GLenum internal_format,
869 GLsizei width,
870 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17871
[email protected]78b514b2012-05-01 21:50:59872 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
873 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
874
[email protected]09d50362012-10-18 20:54:37875 void DoBindTexImage2DCHROMIUM(
876 GLenum target,
877 GLint image_id);
878 void DoReleaseTexImage2DCHROMIUM(
879 GLenum target,
880 GLint image_id);
881
[email protected]94307712012-11-16 23:26:11882 void DoTraceEndCHROMIUM(void);
883
[email protected]2f143d482013-03-14 18:04:49884 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
885
[email protected]ed9f9cd2013-02-27 21:12:35886 // Creates a Program for the given program.
887 Program* CreateProgram(
[email protected]d685a682011-04-29 16:19:57888 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35889 return program_manager()->CreateProgram(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47890 }
891
[email protected]07f54fcc2009-12-22 02:46:30892 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35893 Program* GetProgram(GLuint client_id) {
894 return program_manager()->GetProgram(client_id);
[email protected]1d32bc82010-01-13 22:06:46895 }
[email protected]07f54fcc2009-12-22 02:46:30896
[email protected]cae20172012-12-07 00:06:19897#if defined(NDEBUG)
898 void LogClientServiceMapping(
899 const char* /* function_name */,
900 GLuint /* client_id */,
901 GLuint /* service_id */) {
902 }
903 template<typename T>
904 void LogClientServiceForInfo(
905 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
906 }
907#else
908 void LogClientServiceMapping(
909 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:26910 if (service_logging_) {
[email protected]65f7efe2013-11-28 03:11:47911 VLOG(1) << "[" << logger_.GetLogPrefix() << "] " << function_name
912 << ": client_id = " << client_id
913 << ", service_id = " << service_id;
[email protected]2a22fe72012-12-07 04:21:26914 }
[email protected]cae20172012-12-07 00:06:19915 }
916 template<typename T>
917 void LogClientServiceForInfo(
918 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:26919 if (info) {
[email protected]cae20172012-12-07 00:06:19920 LogClientServiceMapping(function_name, client_id, info->service_id());
921 }
922 }
923#endif
924
[email protected]6b8cf1a2010-05-06 16:13:58925 // Gets the program info for the given program. If it's not a program
926 // generates a GL error. Returns NULL if not program.
[email protected]ed9f9cd2013-02-27 21:12:35927 Program* GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:58928 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:42929 Program* program = GetProgram(client_id);
930 if (!program) {
[email protected]ed9f9cd2013-02-27 21:12:35931 if (GetShader(client_id)) {
[email protected]ab09b612013-03-11 22:11:51932 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43933 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:58934 } else {
[email protected]ab09b612013-03-11 22:11:51935 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:58936 }
937 }
[email protected]df37b9932013-03-08 05:21:42938 LogClientServiceForInfo(program, client_id, function_name);
939 return program;
[email protected]6b8cf1a2010-05-06 16:13:58940 }
941
942
[email protected]ed9f9cd2013-02-27 21:12:35943 // Creates a Shader for the given shader.
944 Shader* CreateShader(
[email protected]d685a682011-04-29 16:19:57945 GLuint client_id,
946 GLuint service_id,
947 GLenum shader_type) {
[email protected]ed9f9cd2013-02-27 21:12:35948 return shader_manager()->CreateShader(
[email protected]d685a682011-04-29 16:19:57949 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:31950 }
951
952 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35953 Shader* GetShader(GLuint client_id) {
954 return shader_manager()->GetShader(client_id);
[email protected]45bf5152010-02-12 00:11:31955 }
956
[email protected]6b8cf1a2010-05-06 16:13:58957 // Gets the shader info for the given shader. If it's not a shader generates a
958 // GL error. Returns NULL if not shader.
[email protected]ed9f9cd2013-02-27 21:12:35959 Shader* GetShaderInfoNotProgram(
[email protected]6b8cf1a2010-05-06 16:13:58960 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:42961 Shader* shader = GetShader(client_id);
962 if (!shader) {
[email protected]ed9f9cd2013-02-27 21:12:35963 if (GetProgram(client_id)) {
[email protected]ab09b612013-03-11 22:11:51964 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43965 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:58966 } else {
[email protected]ab09b612013-03-11 22:11:51967 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43968 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:58969 }
970 }
[email protected]df37b9932013-03-08 05:21:42971 LogClientServiceForInfo(shader, client_id, function_name);
972 return shader;
[email protected]6b8cf1a2010-05-06 16:13:58973 }
974
[email protected]a93bb842010-02-16 23:03:47975 // Creates a buffer info for the given buffer.
[email protected]ed9f9cd2013-02-27 21:12:35976 void CreateBuffer(GLuint client_id, GLuint service_id) {
977 return buffer_manager()->CreateBuffer(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47978 }
979
[email protected]07f54fcc2009-12-22 02:46:30980 // Gets the buffer info for the given buffer.
[email protected]16ccec12013-02-28 03:40:21981 Buffer* GetBuffer(GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:07982 Buffer* buffer = buffer_manager()->GetBuffer(client_id);
983 return buffer;
[email protected]1d32bc82010-01-13 22:06:46984 }
[email protected]07f54fcc2009-12-22 02:46:30985
[email protected]a93bb842010-02-16 23:03:47986 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
987 // on glDeleteBuffers so we can make sure the user does not try to render
988 // with deleted buffers.
[email protected]ed9f9cd2013-02-27 21:12:35989 void RemoveBuffer(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:47990
[email protected]a25fa872010-03-25 02:57:58991 // Creates a framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:35992 void CreateFramebuffer(GLuint client_id, GLuint service_id) {
993 return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:58994 }
995
996 // Gets the framebuffer info for the given framebuffer.
[email protected]4d8f0dd2013-03-09 14:37:06997 Framebuffer* GetFramebuffer(GLuint client_id) {
998 return framebuffer_manager()->GetFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:58999 }
1000
1001 // Removes the framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351002 void RemoveFramebuffer(GLuint client_id) {
1003 framebuffer_manager()->RemoveFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581004 }
1005
1006 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351007 void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
1008 return renderbuffer_manager()->CreateRenderbuffer(
[email protected]ae51d192010-04-27 00:48:031009 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581010 }
1011
1012 // Gets the renderbuffer info for the given renderbuffer.
[email protected]ee2a79c32013-03-10 03:50:271013 Renderbuffer* GetRenderbuffer(GLuint client_id) {
1014 return renderbuffer_manager()->GetRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581015 }
1016
1017 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351018 void RemoveRenderbuffer(GLuint client_id) {
1019 renderbuffer_manager()->RemoveRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581020 }
1021
[email protected]944b62f32012-09-27 02:20:461022 // Gets the vertex attrib manager for the given vertex array.
1023 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1024 VertexAttribManager* info =
1025 vertex_array_manager()->GetVertexAttribManager(client_id);
1026 return info;
1027 }
1028
1029 // Removes the vertex attrib manager for the given vertex array.
1030 void RemoveVertexAttribManager(GLuint client_id) {
1031 vertex_array_manager()->RemoveVertexAttribManager(client_id);
1032 }
1033
1034 // Creates a vertex attrib manager for the given vertex array.
1035 void CreateVertexAttribManager(GLuint client_id, GLuint service_id) {
1036 return vertex_array_manager()->CreateVertexAttribManager(
1037 client_id, service_id, group_->max_vertex_attribs());
1038 }
1039
[email protected]258a3313f2011-10-18 20:13:571040 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:331041 void DoBindUniformLocationCHROMIUM(
1042 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571043
[email protected]558847a2010-03-24 07:02:541044 error::Error GetAttribLocationHelper(
1045 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1046 const std::string& name_str);
1047
1048 error::Error GetUniformLocationHelper(
1049 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1050 const std::string& name_str);
1051
[email protected]3916c97e2010-02-25 03:20:501052 // Helper for glShaderSource.
1053 error::Error ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:031054 GLuint client_id, const char* data, uint32 data_size);
[email protected]07f54fcc2009-12-22 02:46:301055
[email protected]0d6bfdc2011-11-02 01:32:201056 // Clear any textures used by the current program.
1057 bool ClearUnclearedTextures();
1058
[email protected]0d6bfdc2011-11-02 01:32:201059 // Clears any uncleared attachments attached to the given frame buffer.
1060 // Returns false if there was a generated GL error.
[email protected]4d8f0dd2013-03-09 14:37:061061 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
[email protected]3a2e7c7b2010-08-06 01:12:281062
[email protected]0d6bfdc2011-11-02 01:32:201063 // overridden from GLES2Decoder
[email protected]b8e97b62012-09-30 15:09:001064 virtual bool ClearLevel(unsigned service_id,
1065 unsigned bind_target,
1066 unsigned target,
1067 int level,
[email protected]d8e6c9242014-02-20 16:56:251068 unsigned internal_format,
[email protected]b8e97b62012-09-30 15:09:001069 unsigned format,
1070 unsigned type,
1071 int width,
1072 int height,
1073 bool is_texture_immutable) OVERRIDE;
[email protected]0d6bfdc2011-11-02 01:32:201074
[email protected]c007aa02010-09-02 22:22:401075 // Restore all GL state that affects clearing.
1076 void RestoreClearState();
1077
[email protected]3a2e7c7b2010-08-06 01:12:281078 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461079 // Returns: true if glEnable/glDisable should actually be called.
1080 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281081
[email protected]0d6bfdc2011-11-02 01:32:201082 // Check that the currently bound framebuffers are valid.
1083 // Generates GL error if not.
1084 bool CheckBoundFramebuffersValid(const char* func_name);
1085
1086 // Check if a framebuffer meets our requirements.
1087 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351088 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201089 GLenum target,
1090 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271091
[email protected]939e7362010-05-13 20:49:101092 // Checks if the current program exists and is valid. If not generates the
1093 // appropriate GL error. Returns true if the current program is in a usable
1094 // state.
1095 bool CheckCurrentProgram(const char* function_name);
1096
1097 // Checks if the current program exists and is valid and that location is not
1098 // -1. If the current program is not valid generates the appropriate GL
1099 // error. Returns true if the current program is in a usable state and
1100 // location is not -1.
1101 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1102
1103 // Gets the type of a uniform for a location in the current program. Sets GL
1104 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361105 // program is valid and the location exists. Adjusts count so it
1106 // does not overflow the uniform.
1107 bool PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:121108 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:521109 const BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:121110 GLint* real_location, GLenum* type, GLsizei* count);
[email protected]939e7362010-05-13 20:49:101111
[email protected]b177ae22011-11-01 03:29:111112 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021113 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111114
[email protected]b273e432010-04-12 17:23:581115 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1116 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1117
[email protected]ac77603c72013-03-08 13:52:061118 // Helper for glGetVertexAttrib
1119 void GetVertexAttribHelper(
1120 const VertexAttrib* attrib, GLenum pname, GLint* param);
1121
[email protected]96449d2c2009-11-25 00:01:321122 // Wrapper for glCreateProgram
[email protected]ae51d192010-04-27 00:48:031123 bool CreateProgramHelper(GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321124
1125 // Wrapper for glCreateShader
[email protected]ae51d192010-04-27 00:48:031126 bool CreateShaderHelper(GLenum type, GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321127
[email protected]3916c97e2010-02-25 03:20:501128 // Wrapper for glActiveTexture
1129 void DoActiveTexture(GLenum texture_unit);
1130
[email protected]ae51d192010-04-27 00:48:031131 // Wrapper for glAttachShader
1132 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1133
[email protected]96449d2c2009-11-25 00:01:321134 // Wrapper for glBindBuffer since we need to track the current targets.
1135 void DoBindBuffer(GLenum target, GLuint buffer);
1136
[email protected]86093972010-03-11 00:13:561137 // Wrapper for glBindFramebuffer since we need to track the current targets.
1138 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1139
1140 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1141 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1142
[email protected]a93bb842010-02-16 23:03:471143 // Wrapper for glBindTexture since we need to track the current targets.
1144 void DoBindTexture(GLenum target, GLuint texture);
1145
[email protected]944b62f32012-09-27 02:20:461146 // Wrapper for glBindVertexArrayOES
1147 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571148 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461149
[email protected]49cabed2013-11-13 18:15:181150 // Wrapper for glBlitFramebufferCHROMIUM.
1151 void DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301152 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1153 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1154 GLbitfield mask, GLenum filter);
1155
[email protected]36cef8ce2010-03-16 07:34:451156 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111157 void DoBufferSubData(
1158 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1159
[email protected]36cef8ce2010-03-16 07:34:451160 // Wrapper for glCheckFramebufferStatus
1161 GLenum DoCheckFramebufferStatus(GLenum target);
1162
[email protected]3a03a8f2011-03-19 00:51:271163 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081164 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271165
[email protected]88a61bf2012-10-27 13:00:421166 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421167 void DoDepthRangef(GLclampf znear, GLclampf zfar);
[email protected]b04e24c2013-01-08 18:35:251168 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281169
[email protected]45bf5152010-02-12 00:11:311170 // Wrapper for glCompileShader.
1171 void DoCompileShader(GLuint shader);
1172
[email protected]269200b12010-11-18 22:53:061173 // Helper for DeleteSharedIdsCHROMIUM commands.
1174 void DoDeleteSharedIdsCHROMIUM(
1175 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101176
[email protected]ae51d192010-04-27 00:48:031177 // Wrapper for glDetachShader
1178 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1179
[email protected]3a2e7c7b2010-08-06 01:12:281180 // Wrapper for glDisable
1181 void DoDisable(GLenum cap);
1182
[email protected]07f54fcc2009-12-22 02:46:301183 // Wrapper for glDisableVertexAttribArray.
1184 void DoDisableVertexAttribArray(GLuint index);
1185
[email protected]60f22d32012-12-12 00:31:581186 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1187 // attachments.
1188 void DoDiscardFramebufferEXT(GLenum target,
1189 GLsizei numAttachments,
1190 const GLenum* attachments);
1191
[email protected]3a2e7c7b2010-08-06 01:12:281192 // Wrapper for glEnable
1193 void DoEnable(GLenum cap);
1194
[email protected]07f54fcc2009-12-22 02:46:301195 // Wrapper for glEnableVertexAttribArray.
1196 void DoEnableVertexAttribArray(GLuint index);
1197
[email protected]882ba1e22012-03-08 19:02:531198 // Wrapper for glFinish.
1199 void DoFinish();
1200
1201 // Wrapper for glFlush.
1202 void DoFlush();
1203
[email protected]36cef8ce2010-03-16 07:34:451204 // Wrapper for glFramebufferRenderbufffer.
1205 void DoFramebufferRenderbuffer(
1206 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1207 GLuint renderbuffer);
1208
1209 // Wrapper for glFramebufferTexture2D.
1210 void DoFramebufferTexture2D(
1211 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1212 GLint level);
1213
[email protected]7d3c36e2013-07-12 14:13:161214 // Wrapper for glFramebufferTexture2DMultisampleEXT.
1215 void DoFramebufferTexture2DMultisample(
1216 GLenum target, GLenum attachment, GLenum textarget,
1217 GLuint texture, GLint level, GLsizei samples);
1218
1219 // Common implementation for both DoFramebufferTexture2D wrappers.
1220 void DoFramebufferTexture2DCommon(const char* name,
1221 GLenum target, GLenum attachment, GLenum textarget,
1222 GLuint texture, GLint level, GLsizei samples);
1223
[email protected]a93bb842010-02-16 23:03:471224 // Wrapper for glGenerateMipmap
1225 void DoGenerateMipmap(GLenum target);
1226
[email protected]269200b12010-11-18 22:53:061227 // Helper for GenSharedIdsCHROMIUM commands.
1228 void DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:101229 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids);
1230
[email protected]7d3c36e2013-07-12 14:13:161231 // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname
1232 // to account for different pname values defined in different extension
1233 // variants.
1234 GLenum AdjustGetPname(GLenum pname);
1235
[email protected]b273e432010-04-12 17:23:581236 // Wrapper for DoGetBooleanv.
1237 void DoGetBooleanv(GLenum pname, GLboolean* params);
1238
1239 // Wrapper for DoGetFloatv.
1240 void DoGetFloatv(GLenum pname, GLfloat* params);
1241
[email protected]36cef8ce2010-03-16 07:34:451242 // Wrapper for glGetFramebufferAttachmentParameteriv.
1243 void DoGetFramebufferAttachmentParameteriv(
1244 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1245
[email protected]a0c3e972010-04-21 00:49:131246 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581247 void DoGetIntegerv(GLenum pname, GLint* params);
1248
[email protected]29a9eb52010-04-13 09:04:231249 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061250 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231251 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1252
[email protected]17cfbe0e2013-03-07 01:26:081253 // Wrapper for glGetBufferParameteriv.
1254 void DoGetBufferParameteriv(
1255 GLenum target, GLenum pname, GLint* params);
1256
[email protected]a0c3e972010-04-21 00:49:131257 // Wrapper for glGetProgramiv.
1258 void DoGetProgramiv(
1259 GLuint program_id, GLenum pname, GLint* params);
1260
[email protected]36cef8ce2010-03-16 07:34:451261 // Wrapper for glRenderbufferParameteriv.
1262 void DoGetRenderbufferParameteriv(
1263 GLenum target, GLenum pname, GLint* params);
1264
[email protected]ddd968b82010-03-02 00:44:291265 // Wrapper for glGetShaderiv
1266 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1267
[email protected]b1122982010-05-17 23:04:241268 // Wrappers for glGetVertexAttrib.
1269 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1270 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1271
[email protected]1958e0e2010-04-22 05:17:151272 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241273 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151274 bool DoIsBuffer(GLuint client_id);
1275 bool DoIsFramebuffer(GLuint client_id);
1276 bool DoIsProgram(GLuint client_id);
1277 bool DoIsRenderbuffer(GLuint client_id);
1278 bool DoIsShader(GLuint client_id);
1279 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461280 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151281
[email protected]07f54fcc2009-12-22 02:46:301282 // Wrapper for glLinkProgram
1283 void DoLinkProgram(GLuint program);
1284
[email protected]269200b12010-11-18 22:53:061285 // Helper for RegisterSharedIdsCHROMIUM.
1286 void DoRegisterSharedIdsCHROMIUM(
1287 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101288
[email protected]36cef8ce2010-03-16 07:34:451289 // Wrapper for glRenderbufferStorage.
1290 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031291 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451292
[email protected]49cabed2013-11-13 18:15:181293 // Handler for glRenderbufferStorageMultisampleCHROMIUM.
1294 void DoRenderbufferStorageMultisampleCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301295 GLenum target, GLsizei samples, GLenum internalformat,
1296 GLsizei width, GLsizei height);
1297
[email protected]49cabed2013-11-13 18:15:181298 // Handler for glRenderbufferStorageMultisampleEXT
1299 // (multisampled_render_to_texture).
1300 void DoRenderbufferStorageMultisampleEXT(
1301 GLenum target, GLsizei samples, GLenum internalformat,
1302 GLsizei width, GLsizei height);
1303
1304 // Common validation for multisample extensions.
1305 bool ValidateRenderbufferStorageMultisample(GLsizei samples,
1306 GLenum internalformat,
1307 GLsizei width,
1308 GLsizei height);
1309
[email protected]4a4c18b2013-09-13 22:50:101310 // Verifies that the currently bound multisample renderbuffer is valid
1311 // Very slow! Only done on platforms with driver bugs that return invalid
1312 // buffers under memory pressure
1313 bool VerifyMultisampleRenderbufferIntegrity(
1314 GLuint renderbuffer, GLenum format);
1315
[email protected]b273e432010-04-12 17:23:581316 // Wrapper for glReleaseShaderCompiler.
1317 void DoReleaseShaderCompiler() { }
1318
[email protected]3916c97e2010-02-25 03:20:501319 // Wrappers for glTexParameter functions.
1320 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1321 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1322 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1323 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1324
1325 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1326 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121327 void DoUniform1i(GLint fake_location, GLint v0);
1328 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1329 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1330 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1331 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101332
1333 // Wrappers for glUniformfv because some drivers don't correctly accept
1334 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121335 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1336 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1337 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1338 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501339
[email protected]43c2f1f2011-03-25 18:35:361340 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121341 GLint fake_location, GLsizei count, GLboolean transpose,
1342 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361343 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121344 GLint fake_location, GLsizei count, GLboolean transpose,
1345 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361346 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121347 GLint fake_location, GLsizei count, GLboolean transpose,
1348 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361349
[email protected]af6380962012-11-29 23:24:131350 bool SetVertexAttribValue(
1351 const char* function_name, GLuint index, const GLfloat* value);
1352
[email protected]b1122982010-05-17 23:04:241353 // Wrappers for glVertexAttrib??
1354 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1355 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1356 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1357 void DoVertexAttrib4f(
1358 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1359 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1360 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1361 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1362 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1363
[email protected]43410e92012-04-20 17:06:281364 // Wrapper for glViewport
1365 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1366
[email protected]07f54fcc2009-12-22 02:46:301367 // Wrapper for glUseProgram
1368 void DoUseProgram(GLuint program);
1369
[email protected]ae51d192010-04-27 00:48:031370 // Wrapper for glValidateProgram.
1371 void DoValidateProgram(GLuint program_client_id);
1372
[email protected]d2a0e1a2012-08-12 02:25:011373 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1374 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1375 void DoPopGroupMarkerEXT(void);
1376
[email protected]4e8a5b122010-05-08 22:00:101377 // Gets the number of values that will be returned by glGetXXX. Returns
1378 // false if pname is unknown.
1379 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1380
[email protected]07f54fcc2009-12-22 02:46:301381 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431382 bool IsDrawValid(
1383 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301384
[email protected]c13e1da62011-09-09 21:48:301385 // Returns true if successful, simulated will be true if attrib0 was
1386 // simulated.
[email protected]c6aef902012-02-14 03:31:421387 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431388 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]43410e92012-04-20 17:06:281389 void RestoreStateForAttrib(GLuint attrib);
[email protected]b1122982010-05-17 23:04:241390
[email protected]91c94eb2013-10-22 10:32:541391 // If an image is bound to texture, this will call Will/DidUseTexImage
1392 // if needed.
1393 void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1394 void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1395
1396 // Returns false if textures were replaced.
[email protected]e56131d22013-07-28 16:14:111397 bool PrepareTexturesForRender();
[email protected]91c94eb2013-10-22 10:32:541398 void RestoreStateForTextures();
[email protected]3916c97e2010-02-25 03:20:501399
[email protected]8fbedc02010-11-18 18:43:401400 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421401 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431402 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421403 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401404 void RestoreStateForSimulatedFixedAttribs();
1405
[email protected]c6aef902012-02-14 03:31:421406 // Handle DrawArrays and DrawElements for both instanced and non-instanced
1407 // cases (primcount is 0 for non-instanced).
1408 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431409 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421410 bool instanced, GLenum mode, GLint first, GLsizei count,
1411 GLsizei primcount);
1412 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431413 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421414 bool instanced, GLenum mode, GLsizei count, GLenum type,
1415 int32 offset, GLsizei primcount);
1416
[email protected]61eeb33f2011-07-26 15:30:311417 GLenum GetBindTargetForSamplerType(GLenum type) {
1418 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461419 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1420 switch (type) {
1421 case GL_SAMPLER_2D:
1422 return GL_TEXTURE_2D;
1423 case GL_SAMPLER_CUBE:
1424 return GL_TEXTURE_CUBE_MAP;
1425 case GL_SAMPLER_EXTERNAL_OES:
1426 return GL_TEXTURE_EXTERNAL_OES;
1427 case GL_SAMPLER_2D_RECT_ARB:
1428 return GL_TEXTURE_RECTANGLE_ARB;
1429 }
1430
1431 NOTREACHED();
1432 return 0;
[email protected]61eeb33f2011-07-26 15:30:311433 }
1434
[email protected]8e3e0662010-08-23 18:46:301435 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061436 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1437 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301438 switch (target) {
1439 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451440 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341441 framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301442 break;
[email protected]ebfb73c2012-08-15 02:37:451443 case GL_READ_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341444 framebuffer = framebuffer_state_.bound_read_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301445 break;
1446 default:
1447 NOTREACHED();
1448 break;
1449 }
[email protected]4d8f0dd2013-03-09 14:37:061450 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301451 }
1452
[email protected]ed9f9cd2013-02-27 21:12:351453 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201454 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271455 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201456 switch (target) {
1457 case GL_RENDERBUFFER:
[email protected]7cd76fd2013-06-02 21:11:111458 renderbuffer = state_.bound_renderbuffer.get();
[email protected]0d6bfdc2011-11-02 01:32:201459 break;
1460 default:
1461 NOTREACHED();
1462 break;
1463 }
[email protected]ee2a79c32013-03-10 03:50:271464 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201465 }
1466
[email protected]f7b85372010-02-03 01:11:371467 // Validates the program and location for a glGetUniform call and returns
1468 // a SizeResult setup to receive the result. Returns true if glGetUniform
1469 // should be called.
1470 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121471 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371472 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121473 error::Error* error, GLint* real_location, GLuint* service_id,
1474 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371475
[email protected]a10b4a02012-11-26 23:09:501476 virtual bool WasContextLost() OVERRIDE;
[email protected]93a7d98f2013-07-11 00:04:221477 virtual bool WasContextLostByRobustnessExtension() OVERRIDE;
[email protected]c4485aad62012-12-17 10:19:091478 virtual void LoseContext(uint32 reset_status) OVERRIDE;
[email protected]38d139d2011-07-14 00:38:431479
[email protected]e51bdf32011-11-23 22:21:461480#if defined(OS_MACOSX)
1481 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1482#endif
1483
[email protected]ad84a3a2012-06-08 21:42:431484 bool ValidateCompressedTexDimensions(
1485 const char* function_name,
1486 GLint level, GLsizei width, GLsizei height, GLenum format);
1487 bool ValidateCompressedTexFuncData(
1488 const char* function_name,
1489 GLsizei width, GLsizei height, GLenum format, size_t size);
1490 bool ValidateCompressedTexSubDimensions(
1491 const char* function_name,
1492 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1493 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351494 Texture* texture);
[email protected]ad84a3a2012-06-08 21:42:431495
[email protected]ab09b612013-03-11 22:11:511496 void RenderWarning(const char* filename, int line, const std::string& msg);
1497 void PerformanceWarning(
1498 const char* filename, int line, const std::string& msg);
[email protected]0f8afe82012-05-14 23:43:011499
[email protected]62e155e2012-10-23 22:43:151500 const FeatureInfo::FeatureFlags& features() const {
1501 return feature_info_->feature_flags();
1502 }
1503
1504 const FeatureInfo::Workarounds& workarounds() const {
1505 return feature_info_->workarounds();
1506 }
1507
[email protected]a7266a92012-06-28 02:11:081508 bool ShouldDeferDraws() {
1509 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341510 framebuffer_state_.bound_draw_framebuffer.get() == NULL &&
[email protected]a7266a92012-06-28 02:11:081511 surface_->DeferDraws();
1512 }
1513
[email protected]09e17272012-11-30 10:30:441514 bool ShouldDeferReads() {
1515 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341516 framebuffer_state_.bound_read_framebuffer.get() == NULL &&
[email protected]09e17272012-11-30 10:30:441517 surface_->DeferDraws();
1518 }
1519
[email protected]c76fe672013-12-13 23:30:221520 error::Error WillAccessBoundFramebufferForDraw() {
1521 if (ShouldDeferDraws())
1522 return error::kDeferCommandUntilLater;
1523 if (!offscreen_target_frame_buffer_.get() &&
1524 !framebuffer_state_.bound_draw_framebuffer.get() &&
1525 !surface_->SetBackbufferAllocation(true))
1526 return error::kLostContext;
1527 return error::kNoError;
1528 }
1529
1530 error::Error WillAccessBoundFramebufferForRead() {
1531 if (ShouldDeferReads())
1532 return error::kDeferCommandUntilLater;
1533 if (!offscreen_target_frame_buffer_.get() &&
1534 !framebuffer_state_.bound_read_framebuffer.get() &&
1535 !surface_->SetBackbufferAllocation(true))
1536 return error::kLostContext;
1537 return error::kNoError;
1538 }
1539
[email protected]5a36dc132013-07-23 23:17:551540 void ProcessPendingReadPixels();
1541 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
1542
[email protected]96449d2c2009-11-25 00:01:321543 // Generate a member function prototype for each command in an automated and
1544 // typesafe way.
1545 #define GLES2_CMD_OP(name) \
[email protected]f7a64ee2010-02-01 22:24:141546 Error Handle ## name( \
[email protected]ed9f9cd2013-02-27 21:12:351547 uint32 immediate_data_size, \
1548 const cmds::name& args); \
[email protected]96449d2c2009-11-25 00:01:321549
1550 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1551
1552 #undef GLES2_CMD_OP
1553
[email protected]2f2d7042010-04-14 21:45:581554 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381555 scoped_refptr<gfx::GLSurface> surface_;
1556 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021557
[email protected]a3ded6d2010-10-19 06:44:391558 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351559 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391560
[email protected]1d82e822013-04-10 21:32:321561 DebugMarkerManager debug_marker_manager_;
1562 Logger logger_;
1563
[email protected]e259eb412012-10-13 05:47:241564 // All the state for this context.
1565 ContextState state_;
1566
[email protected]34ff8b0c2010-10-01 20:06:021567 // Current width and height of the offscreen frame buffer.
1568 gfx::Size offscreen_size_;
1569
[email protected]96449d2c2009-11-25 00:01:321570 // Util to help with GL.
1571 GLES2Util util_;
1572
[email protected]43410e92012-04-20 17:06:281573 // unpack flip y as last set by glPixelStorei
1574 bool unpack_flip_y_;
1575
[email protected]6c75c712012-06-19 15:43:171576 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281577 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171578 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281579
[email protected]944b62f32012-09-27 02:20:461580 // Default vertex attribs manager, used when no VAOs are bound.
[email protected]ed9f9cd2013-02-27 21:12:351581 scoped_refptr<VertexAttribManager> default_vertex_attrib_manager_;
[email protected]07f54fcc2009-12-22 02:46:301582
[email protected]b1122982010-05-17 23:04:241583 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1584 GLuint attrib_0_buffer_id_;
1585
1586 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131587 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241588
[email protected]fc753442011-02-04 19:49:491589 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1590 bool attrib_0_buffer_matches_value_;
1591
[email protected]b1122982010-05-17 23:04:241592 // The size of attrib 0.
1593 GLsizei attrib_0_size_;
1594
[email protected]8fbedc02010-11-18 18:43:401595 // The buffer used to simulate GL_FIXED attribs.
1596 GLuint fixed_attrib_buffer_id_;
1597
1598 // The size of fiixed attrib buffer.
1599 GLsizei fixed_attrib_buffer_size_;
1600
[email protected]b9363b22010-06-09 22:06:151601 // The offscreen frame buffer that the client renders to. With EGL, the
1602 // depth and stencil buffers are separate. With regular GL there is a single
1603 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1604 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351605 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1606 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1607 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1608 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1609 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021610 GLenum offscreen_target_color_format_;
1611 GLenum offscreen_target_depth_format_;
1612 GLenum offscreen_target_stencil_format_;
1613 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561614 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351615
[email protected]de26b3c2011-08-03 21:54:271616 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351617 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1618 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
[email protected]370eaf12013-05-18 09:19:491619 scoped_refptr<TextureRef>
[email protected]ed9f9cd2013-02-27 21:12:351620 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271621
1622 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351623 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1624 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051625 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351626
[email protected]882ba1e22012-03-08 19:02:531627 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531628
[email protected]944b62f32012-09-27 02:20:461629 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1630
[email protected]729c0b42013-05-26 02:05:071631 base::Callback<void(gfx::Size, float)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001632
[email protected]840a7e462013-02-27 01:29:511633 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481634
[email protected]e3932abb2013-03-13 00:01:371635 ShaderCacheCallback shader_cache_callback_;
1636
[email protected]85a4ac22013-05-31 01:58:471637 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
[email protected]b0af4f52011-09-28 22:04:421638
[email protected]32fe9aa2011-01-21 23:47:131639 // The format of the back buffer_
1640 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461641 bool back_buffer_has_depth_;
1642 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131643
[email protected]60f22d32012-12-12 00:31:581644 // Backbuffer attachments that are currently undefined.
1645 uint32 backbuffer_needs_clear_bits_;
1646
[email protected]a3a93e7b2010-08-28 00:48:561647 // The current decoder error.
1648 error::Error current_decoder_error_;
1649
[email protected]b1d2dcb2010-05-17 19:24:181650 bool use_shader_translator_;
[email protected]87fb6ab2012-06-13 22:28:041651 scoped_refptr<ShaderTranslator> vertex_translator_;
1652 scoped_refptr<ShaderTranslator> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181653
[email protected]e82fb792011-09-22 00:33:291654 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411655
[email protected]915a59a12010-09-30 21:29:111656 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051657 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351658 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051659
[email protected]65225772011-05-12 21:10:241660 int frame_number_;
1661
[email protected]706b69f2012-07-27 04:59:301662 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431663 GLenum reset_status_;
[email protected]93a7d98f2013-07-11 00:04:221664 bool reset_by_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431665
[email protected]f0d74742011-10-03 16:31:041666 // These flags are used to override the state of the shared feature_info_
1667 // member. Because the same FeatureInfo instance may be shared among many
1668 // contexts, the assumptions on the availablity of extensions in WebGL
1669 // contexts may be broken. These flags override the shared state to preserve
1670 // WebGL semantics.
1671 bool force_webgl_glsl_validation_;
1672 bool derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:491673 bool frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:131674 bool draw_buffers_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:041675
[email protected]062c38b2012-01-18 03:25:101676 bool compile_shader_always_succeeds_;
1677
[email protected]cae20172012-12-07 00:06:191678 // Log extra info.
1679 bool service_logging_;
1680
[email protected]e51bdf32011-11-23 22:21:461681#if defined(OS_MACOSX)
1682 typedef std::map<GLuint, CFTypeRef> TextureToIOSurfaceMap;
1683 TextureToIOSurfaceMap texture_to_io_surface_map_;
1684#endif
1685
[email protected]43410e92012-04-20 17:06:281686 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
1687
[email protected]1868a342012-11-07 15:56:021688 // Cached values of the currently assigned viewport dimensions.
1689 GLsizei viewport_max_width_;
1690 GLsizei viewport_max_height_;
1691
[email protected]63b465922012-09-06 02:04:521692 // Command buffer stats.
[email protected]63b465922012-09-06 02:04:521693 base::TimeDelta total_processing_commands_time_;
1694
[email protected]c986af502013-08-14 01:04:441695 // States related to each manager.
1696 DecoderTextureState texture_state_;
1697 DecoderFramebufferState framebuffer_state_;
1698
[email protected]fb97b662013-02-20 23:02:141699 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]8f9b8dd2013-09-12 18:05:131700 scoped_ptr<GPUStateTracer> gpu_state_tracer_;
[email protected]cac16542014-01-15 17:53:511701 int gpu_trace_level_;
1702 bool gpu_trace_commands_;
[email protected]94307712012-11-16 23:26:111703
[email protected]5a36dc132013-07-23 23:17:551704 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_;
1705
[email protected]4a4c18b2013-09-13 22:50:101706 // Used to validate multisample renderbuffers if needed
1707 GLuint validation_texture_;
1708 GLuint validation_fbo_multisample_;
1709 GLuint validation_fbo_;
1710
[email protected]96449d2c2009-11-25 00:01:321711 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1712};
1713
[email protected]ab09b612013-03-11 22:11:511714ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:301715 const char* function_name, ErrorState* error_state)
[email protected]ab09b612013-03-11 22:11:511716 : function_name_(function_name),
[email protected]40621eb52013-10-08 15:40:301717 error_state_(error_state) {
1718 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351719}
1720
1721ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]40621eb52013-10-08 15:40:301722 ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351723}
1724
[email protected]2b10c02d2014-01-29 16:43:021725static void RestoreCurrentTextureBindings(ContextState* state, GLenum target) {
[email protected]ce296892013-10-24 22:04:361726 TextureUnit& info = state->texture_units[0];
1727 GLuint last_id;
[email protected]2b10c02d2014-01-29 16:43:021728 scoped_refptr<TextureRef> texture_ref;
1729 switch (target) {
1730 case GL_TEXTURE_2D:
1731 texture_ref = info.bound_texture_2d;
1732 break;
1733 case GL_TEXTURE_CUBE_MAP:
1734 texture_ref = info.bound_texture_cube_map;
1735 break;
1736 case GL_TEXTURE_EXTERNAL_OES:
1737 texture_ref = info.bound_texture_external_oes;
1738 break;
1739 case GL_TEXTURE_RECTANGLE_ARB:
1740 texture_ref = info.bound_texture_rectangle_arb;
1741 break;
1742 default:
1743 NOTREACHED();
1744 break;
1745 }
1746 if (texture_ref.get()) {
1747 last_id = texture_ref->service_id();
[email protected]ce296892013-10-24 22:04:361748 } else {
1749 last_id = 0;
1750 }
1751
[email protected]2b10c02d2014-01-29 16:43:021752 glBindTexture(target, last_id);
[email protected]ce296892013-10-24 22:04:361753 glActiveTexture(GL_TEXTURE0 + state->active_texture_unit);
1754}
1755
[email protected]2b10c02d2014-01-29 16:43:021756ScopedTextureBinder::ScopedTextureBinder(ContextState* state,
1757 GLuint id,
1758 GLenum target)
1759 : state_(state),
1760 target_(target) {
[email protected]ab09b612013-03-11 22:11:511761 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021762 "ScopedTextureBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351763
1764 // TODO(apatrick): Check if there are any other states that need to be reset
1765 // before binding a new texture.
1766 glActiveTexture(GL_TEXTURE0);
[email protected]2b10c02d2014-01-29 16:43:021767 glBindTexture(target, id);
[email protected]6217d392010-03-25 22:08:351768}
1769
[email protected]2b10c02d2014-01-29 16:43:021770ScopedTextureBinder::~ScopedTextureBinder() {
[email protected]ab09b612013-03-11 22:11:511771 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021772 "ScopedTextureBinder::dtor", state_->GetErrorState());
1773 RestoreCurrentTextureBindings(state_, target_);
[email protected]6217d392010-03-25 22:08:351774}
1775
[email protected]18e785a2013-10-09 03:29:411776ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state,
[email protected]6217d392010-03-25 22:08:351777 GLuint id)
[email protected]18e785a2013-10-09 03:29:411778 : state_(state) {
[email protected]ab09b612013-03-11 22:11:511779 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411780 "ScopedRenderBufferBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351781 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1782}
1783
1784ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511785 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411786 "ScopedRenderBufferBinder::dtor", state_->GetErrorState());
1787 state_->RestoreRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:351788}
1789
1790ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1791 GLuint id)
1792 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511793 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301794 "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351795 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:451796 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:351797}
1798
1799ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511800 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301801 "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]8e3e0662010-08-23 18:46:301802 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:351803}
1804
[email protected]34ff8b0c2010-10-01 20:06:021805ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:271806 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:521807 : decoder_(decoder) {
[email protected]9d3b2e12013-10-02 01:04:341808 resolve_and_bind_ = (
1809 decoder_->offscreen_target_frame_buffer_.get() &&
1810 decoder_->IsOffscreenBufferMultisampled() &&
1811 (!decoder_->framebuffer_state_.bound_read_framebuffer.get() ||
1812 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:021813 if (!resolve_and_bind_)
1814 return;
1815
[email protected]ab09b612013-03-11 22:11:511816 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301817 "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:021818 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
1819 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:271820 GLuint targetid;
1821 if (internal) {
1822 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
1823 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:351824 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:271825 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:351826 decoder_->offscreen_resolved_color_texture_.reset(
[email protected]ce296892013-10-24 22:04:361827 new BackTexture(decoder->memory_tracker(), &decoder->state_));
[email protected]de26b3c2011-08-03 21:54:271828 decoder_->offscreen_resolved_color_texture_->Create();
1829
1830 DCHECK(decoder_->offscreen_saved_color_format_);
1831 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:091832 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
1833 false);
[email protected]de26b3c2011-08-03 21:54:271834 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
1835 decoder_->offscreen_resolved_color_texture_.get());
1836 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
1837 GL_FRAMEBUFFER_COMPLETE) {
1838 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
1839 << "because offscreen resolved FBO was incomplete.";
1840 return;
1841 }
1842 }
1843 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
1844 } else {
1845 targetid = decoder_->offscreen_saved_frame_buffer_->id();
1846 }
1847 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021848 const int width = decoder_->offscreen_size_.width();
1849 const int height = decoder_->offscreen_size_.height();
[email protected]8c3e68782010-10-27 16:41:181850 glDisable(GL_SCISSOR_TEST);
[email protected]f42f05b2013-11-15 21:46:181851 decoder->BlitFramebufferHelper(0,
1852 0,
1853 width,
1854 height,
1855 0,
1856 0,
1857 width,
1858 height,
1859 GL_COLOR_BUFFER_BIT,
1860 GL_NEAREST);
[email protected]de26b3c2011-08-03 21:54:271861 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021862}
1863
1864ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
1865 if (!resolve_and_bind_)
1866 return;
1867
[email protected]ab09b612013-03-11 22:11:511868 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301869 "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:021870 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:221871 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]8c3e68782010-10-27 16:41:181872 glEnable(GL_SCISSOR_TEST);
1873 }
[email protected]34ff8b0c2010-10-01 20:06:021874}
1875
[email protected]ce296892013-10-24 22:04:361876BackTexture::BackTexture(
1877 MemoryTracker* memory_tracker,
1878 ContextState* state)
1879 : memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
1880 state_(state),
[email protected]68e81a4a62012-12-13 01:16:481881 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:251882 id_(0) {
[email protected]6217d392010-03-25 22:08:351883}
1884
[email protected]ed9f9cd2013-02-27 21:12:351885BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:351886 // This does not destroy the render texture because that would require that
1887 // the associated GL context was current. Just check that it was explicitly
1888 // destroyed.
1889 DCHECK_EQ(id_, 0u);
1890}
1891
[email protected]ed9f9cd2013-02-27 21:12:351892void BackTexture::Create() {
[email protected]40621eb52013-10-08 15:40:301893 ScopedGLErrorSuppressor suppressor("BackTexture::Create",
[email protected]ce296892013-10-24 22:04:361894 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351895 Destroy();
1896 glGenTextures(1, &id_);
[email protected]2b10c02d2014-01-29 16:43:021897 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]3a4d0c52011-06-29 23:11:581898 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1899 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1900 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1901 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:161902
1903 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
1904 // never called on an offscreen context, no data will ever be uploaded to the
1905 // saved offscreen color texture (it is deferred until to when SwapBuffers
1906 // is called). My idea is that some nvidia drivers might have a bug where
1907 // deleting a texture that has never been populated might cause a
1908 // crash.
1909 glTexImage2D(
1910 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:481911
1912 bytes_allocated_ = 16u * 16u * 4u;
1913 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:351914}
1915
[email protected]ed9f9cd2013-02-27 21:12:351916bool BackTexture::AllocateStorage(
1917 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:351918 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:301919 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage",
[email protected]ce296892013-10-24 22:04:361920 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:021921 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]678a73f2012-12-19 19:22:091922 uint32 image_size = 0;
1923 GLES2Util::ComputeImageDataSizes(
1924 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size,
1925 NULL, NULL);
1926
[email protected]7989c9e2013-01-23 06:39:261927 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
1928 return false;
1929 }
1930
[email protected]40d90a22013-04-09 03:39:551931 scoped_ptr<char[]> zero_data;
[email protected]678a73f2012-12-19 19:22:091932 if (zero) {
1933 zero_data.reset(new char[image_size]);
1934 memset(zero_data.get(), 0, image_size);
1935 }
[email protected]6217d392010-03-25 22:08:351936
[email protected]8f1d2aa2013-05-10 23:45:381937 glTexImage2D(GL_TEXTURE_2D,
1938 0, // mip level
1939 format,
1940 size.width(),
1941 size.height(),
1942 0, // border
1943 format,
1944 GL_UNSIGNED_BYTE,
1945 zero_data.get());
[email protected]6217d392010-03-25 22:08:351946
[email protected]d37231fa2010-04-09 21:16:021947 size_ = size;
1948
[email protected]1078f912011-12-23 13:12:141949 bool success = glGetError() == GL_NO_ERROR;
1950 if (success) {
[email protected]68e81a4a62012-12-13 01:16:481951 memory_tracker_.TrackMemFree(bytes_allocated_);
1952 bytes_allocated_ = image_size;
1953 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:141954 }
1955 return success;
[email protected]6217d392010-03-25 22:08:351956}
1957
[email protected]ed9f9cd2013-02-27 21:12:351958void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:351959 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:301960 ScopedGLErrorSuppressor suppressor("BackTexture::Copy",
[email protected]ce296892013-10-24 22:04:361961 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:021962 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]6217d392010-03-25 22:08:351963 glCopyTexImage2D(GL_TEXTURE_2D,
1964 0, // level
[email protected]3a4d0c52011-06-29 23:11:581965 format,
[email protected]6217d392010-03-25 22:08:351966 0, 0,
1967 size.width(),
1968 size.height(),
1969 0); // border
1970}
1971
[email protected]ed9f9cd2013-02-27 21:12:351972void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:351973 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:301974 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy",
[email protected]ce296892013-10-24 22:04:361975 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351976 glDeleteTextures(1, &id_);
1977 id_ = 0;
1978 }
[email protected]68e81a4a62012-12-13 01:16:481979 memory_tracker_.TrackMemFree(bytes_allocated_);
1980 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:351981}
1982
[email protected]ed9f9cd2013-02-27 21:12:351983void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:051984 id_ = 0;
1985}
1986
[email protected]d5a28e452013-10-10 01:01:401987BackRenderbuffer::BackRenderbuffer(
1988 RenderbufferManager* renderbuffer_manager,
1989 MemoryTracker* memory_tracker,
1990 ContextState* state)
1991 : renderbuffer_manager_(renderbuffer_manager),
1992 memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
1993 state_(state),
[email protected]68e81a4a62012-12-13 01:16:481994 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:251995 id_(0) {
[email protected]6217d392010-03-25 22:08:351996}
1997
[email protected]ed9f9cd2013-02-27 21:12:351998BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:351999 // This does not destroy the render buffer because that would require that
2000 // the associated GL context was current. Just check that it was explicitly
2001 // destroyed.
2002 DCHECK_EQ(id_, 0u);
2003}
2004
[email protected]ed9f9cd2013-02-27 21:12:352005void BackRenderbuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302006 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create",
[email protected]d5a28e452013-10-10 01:01:402007 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352008 Destroy();
2009 glGenRenderbuffersEXT(1, &id_);
2010}
2011
[email protected]f42f05b2013-11-15 21:46:182012bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info,
2013 const gfx::Size& size,
2014 GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:352015 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:512016 ScopedGLErrorSuppressor suppressor(
[email protected]d5a28e452013-10-10 01:01:402017 "BackRenderbuffer::AllocateStorage", state_->GetErrorState());
2018 ScopedRenderBufferBinder binder(state_, id_);
[email protected]7989c9e2013-01-23 06:39:262019
2020 uint32 estimated_size = 0;
[email protected]d5a28e452013-10-10 01:01:402021 if (!renderbuffer_manager_->ComputeEstimatedRenderbufferSize(
[email protected]8e102e102013-09-20 22:50:232022 size.width(), size.height(), samples, format, &estimated_size)) {
[email protected]7989c9e2013-01-23 06:39:262023 return false;
2024 }
2025
2026 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
2027 return false;
2028 }
2029
[email protected]34ff8b0c2010-10-01 20:06:022030 if (samples <= 1) {
2031 glRenderbufferStorageEXT(GL_RENDERBUFFER,
2032 format,
2033 size.width(),
2034 size.height());
2035 } else {
[email protected]f42f05b2013-11-15 21:46:182036 GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info,
2037 GL_RENDERBUFFER,
2038 samples,
2039 format,
2040 size.width(),
2041 size.height());
[email protected]34ff8b0c2010-10-01 20:06:022042 }
[email protected]1078f912011-12-23 13:12:142043 bool success = glGetError() == GL_NO_ERROR;
2044 if (success) {
[email protected]d5a28e452013-10-10 01:01:402045 // Mark the previously allocated bytes as free.
[email protected]68e81a4a62012-12-13 01:16:482046 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:262047 bytes_allocated_ = estimated_size;
[email protected]d5a28e452013-10-10 01:01:402048 // Track the newly allocated bytes.
[email protected]68e81a4a62012-12-13 01:16:482049 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142050 }
2051 return success;
[email protected]6217d392010-03-25 22:08:352052}
2053
[email protected]ed9f9cd2013-02-27 21:12:352054void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352055 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302056 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy",
[email protected]d5a28e452013-10-10 01:01:402057 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352058 glDeleteRenderbuffersEXT(1, &id_);
2059 id_ = 0;
2060 }
[email protected]68e81a4a62012-12-13 01:16:482061 memory_tracker_.TrackMemFree(bytes_allocated_);
2062 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352063}
2064
[email protected]ed9f9cd2013-02-27 21:12:352065void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052066 id_ = 0;
2067}
2068
[email protected]ed9f9cd2013-02-27 21:12:352069BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352070 : decoder_(decoder),
2071 id_(0) {
2072}
2073
[email protected]ed9f9cd2013-02-27 21:12:352074BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:352075 // This does not destroy the frame buffer because that would require that
2076 // the associated GL context was current. Just check that it was explicitly
2077 // destroyed.
2078 DCHECK_EQ(id_, 0u);
2079}
2080
[email protected]ed9f9cd2013-02-27 21:12:352081void BackFramebuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302082 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create",
2083 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352084 Destroy();
2085 glGenFramebuffersEXT(1, &id_);
2086}
2087
[email protected]ed9f9cd2013-02-27 21:12:352088void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:352089 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512090 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302091 "BackFramebuffer::AttachRenderTexture", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352092 ScopedFrameBufferBinder binder(decoder_, id_);
2093 GLuint attach_id = texture ? texture->id() : 0;
2094 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2095 GL_COLOR_ATTACHMENT0,
2096 GL_TEXTURE_2D,
2097 attach_id,
2098 0);
2099}
2100
[email protected]ed9f9cd2013-02-27 21:12:352101void BackFramebuffer::AttachRenderBuffer(GLenum target,
2102 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352103 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512104 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302105 "BackFramebuffer::AttachRenderBuffer", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352106 ScopedFrameBufferBinder binder(decoder_, id_);
2107 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2108 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152109 target,
[email protected]6217d392010-03-25 22:08:352110 GL_RENDERBUFFER,
2111 attach_id);
2112}
2113
[email protected]ed9f9cd2013-02-27 21:12:352114void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352115 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302116 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy",
2117 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352118 glDeleteFramebuffersEXT(1, &id_);
2119 id_ = 0;
2120 }
2121}
2122
[email protected]ed9f9cd2013-02-27 21:12:352123void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052124 id_ = 0;
2125}
2126
[email protected]ed9f9cd2013-02-27 21:12:352127GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352128 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302129 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus",
2130 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352131 ScopedFrameBufferBinder binder(decoder_, id_);
2132 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2133}
2134
[email protected]aa7666122011-09-02 19:45:522135GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2136 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322137}
2138
[email protected]aa7666122011-09-02 19:45:522139GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392140 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572141 group_(group),
[email protected]1d82e822013-04-10 21:32:322142 logger_(&debug_marker_manager_),
[email protected]d3eba342013-04-18 21:11:502143 state_(group_->feature_info(), &logger_),
[email protected]43410e92012-04-20 17:06:282144 unpack_flip_y_(false),
2145 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172146 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242147 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492148 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242149 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402150 fixed_attrib_buffer_id_(0),
2151 fixed_attrib_buffer_size_(0),
[email protected]34ff8b0c2010-10-01 20:06:022152 offscreen_target_color_format_(0),
2153 offscreen_target_depth_format_(0),
2154 offscreen_target_stencil_format_(0),
2155 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562156 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052157 offscreen_saved_color_format_(0),
[email protected]32fe9aa2011-01-21 23:47:132158 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462159 back_buffer_has_depth_(false),
2160 back_buffer_has_stencil_(false),
[email protected]60f22d32012-12-12 00:31:582161 backbuffer_needs_clear_bits_(0),
[email protected]a3a93e7b2010-08-28 00:48:562162 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052163 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112164 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002165 feature_info_(group_->feature_info()),
[email protected]38d139d2011-07-14 00:38:432166 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302167 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512168 reset_status_(GL_NO_ERROR),
[email protected]93a7d98f2013-07-11 00:04:222169 reset_by_robustness_extension_(false),
[email protected]f0d74742011-10-03 16:31:042170 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102171 derivatives_explicitly_enabled_(false),
[email protected]70dc60932013-06-04 03:33:492172 frag_depth_explicitly_enabled_(false),
[email protected]aff39ac82013-06-08 04:53:132173 draw_buffers_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282174 compile_shader_always_succeeds_(false),
[email protected]cae20172012-12-07 00:06:192175 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch(
2176 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022177 viewport_max_width_(0),
[email protected]4a4c18b2013-09-13 22:50:102178 viewport_max_height_(0),
[email protected]345ba902013-11-14 21:39:002179 texture_state_(group_->feature_info()
2180 ->workarounds()
2181 .texsubimage2d_faster_than_teximage2d),
[email protected]4a4c18b2013-09-13 22:50:102182 validation_texture_(0),
2183 validation_fbo_multisample_(0),
2184 validation_fbo_(0) {
[email protected]3b1ecc262011-08-03 22:49:572185 DCHECK(group);
2186
[email protected]b1122982010-05-17 23:04:242187 attrib_0_value_.v[0] = 0.0f;
2188 attrib_0_value_.v[1] = 0.0f;
2189 attrib_0_value_.v[2] = 0.0f;
2190 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152191
[email protected]c2f8c8402010-12-06 18:07:242192 // The shader translator is used for WebGL even when running on EGL
2193 // because additional restrictions are needed (like only enabling
2194 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562195 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2196 // the empty string to CompileShader and this is not a valid shader.
2197 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
[email protected]39ba4f02012-03-26 01:16:002198 CommandLine::ForCurrentProcess()->HasSwitch(
2199 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152200 use_shader_translator_ = false;
2201 }
[email protected]96449d2c2009-11-25 00:01:322202}
2203
[email protected]80eb6b52012-01-19 00:14:412204GLES2DecoderImpl::~GLES2DecoderImpl() {
2205}
2206
[email protected]c410da802011-03-14 19:17:412207bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382208 const scoped_refptr<gfx::GLSurface>& surface,
2209 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232210 bool offscreen,
[email protected]c410da802011-03-14 19:17:412211 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:292212 const DisallowedFeatures& disallowed_features,
[email protected]3c644d82011-06-20 19:58:242213 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322214 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382215 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302216 DCHECK(!context_.get());
2217
[email protected]55e136f2013-04-03 18:50:062218 set_initialized();
[email protected]bccc0f32014-01-10 03:18:082219 gpu_tracer_ = GPUTracer::Create(this);
[email protected]8f9b8dd2013-09-12 18:05:132220 gpu_state_tracer_ = GPUStateTracer::Create(&state_);
[email protected]cac16542014-01-15 17:53:512221 // TODO(vmiura): Enable changing gpu_trace_level_ at runtime
2222 gpu_trace_level_ = 2;
2223 gpu_trace_commands_ = false;
[email protected]fb97b662013-02-20 23:02:142224
[email protected]e844ae22012-01-14 03:36:262225 if (CommandLine::ForCurrentProcess()->HasSwitch(
2226 switches::kEnableGPUDebugging)) {
2227 set_debug(true);
2228 }
2229
[email protected]39ba4f02012-03-26 01:16:002230 if (CommandLine::ForCurrentProcess()->HasSwitch(
2231 switches::kEnableGPUCommandLogging)) {
2232 set_log_commands(true);
2233 }
2234
[email protected]062c38b2012-01-18 03:25:102235 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch(
2236 switches::kCompileShaderAlwaysSucceeds);
2237
[email protected]f62a5ab2011-05-23 20:34:152238
[email protected]63c9b052012-05-17 18:27:382239 // Take ownership of the context and surface. The surface can be replaced with
2240 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382241 context_ = context;
[email protected]63c9b052012-05-17 18:27:382242 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182243
[email protected]65f7efe2013-11-28 03:11:472244 ContextCreationAttribHelper attrib_parser;
2245 if (!attrib_parser.Parse(attribs))
2246 return false;
2247
2248 // If the failIfMajorPerformanceCaveat context creation attribute was true
2249 // and we are using a software renderer, fail.
2250 if (attrib_parser.fail_if_major_perf_caveat_ &&
2251 feature_info_->feature_flags().is_swiftshader) {
2252 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
2253 Destroy(true);
2254 return false;
2255 }
2256
[email protected]956aec52013-09-05 15:41:192257 if (!group_->Initialize(this, disallowed_features)) {
[email protected]09ddb91f2011-04-14 23:16:222258 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392259 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422260 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382261 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032262 return false;
[email protected]a3ded6d2010-10-19 06:44:392263 }
[email protected]b64c24952012-04-19 03:20:272264 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282265
[email protected]e82fb792011-09-22 00:33:292266 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502267
[email protected]af6380962012-11-29 23:24:132268 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]944b62f32012-09-27 02:20:462269 default_vertex_attrib_manager_ = new VertexAttribManager();
2270 default_vertex_attrib_manager_->Initialize(group_->max_vertex_attribs());
2271
[email protected]ab4fd7282012-10-12 16:25:572272 // vertex_attrib_manager is set to default_vertex_attrib_manager_ by this call
2273 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322274
[email protected]7cd76fd2013-06-02 21:11:112275 query_manager_.reset(new QueryManager(this, feature_info_.get()));
[email protected]944b62f32012-09-27 02:20:462276 vertex_array_manager_.reset(new VertexArrayManager());
[email protected]882ba1e22012-03-08 19:02:532277
[email protected]302ce6d2011-07-07 23:28:112278 util_.set_num_compressed_texture_formats(
2279 validators_->compressed_texture_format.GetValues().size());
2280
[email protected]1071e572011-02-09 20:00:122281 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2282 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2283 // OpenGL ES 2.0 does not have this issue.
2284 glEnableVertexAttribArray(0);
2285 }
[email protected]b1122982010-05-17 23:04:242286 glGenBuffersARB(1, &attrib_0_buffer_id_);
2287 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2288 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2289 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402290 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082291
[email protected]1868a342012-11-07 15:56:022292 state_.texture_units.resize(group_->max_texture_units());
2293 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492294 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312295 // We want the last bind to be 2D.
[email protected]370eaf12013-05-18 09:19:492296 TextureRef* ref;
[email protected]62e155e2012-10-23 22:43:152297 if (features().oes_egl_image_external) {
[email protected]370eaf12013-05-18 09:19:492298 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072299 GL_TEXTURE_EXTERNAL_OES);
[email protected]370eaf12013-05-18 09:19:492300 state_.texture_units[tt].bound_texture_external_oes = ref;
2301 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref->service_id());
[email protected]61eeb33f2011-07-26 15:30:312302 }
[email protected]62e155e2012-10-23 22:43:152303 if (features().arb_texture_rectangle) {
[email protected]370eaf12013-05-18 09:19:492304 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072305 GL_TEXTURE_RECTANGLE_ARB);
[email protected]370eaf12013-05-18 09:19:492306 state_.texture_units[tt].bound_texture_rectangle_arb = ref;
2307 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref->service_id());
[email protected]e51bdf32011-11-23 22:21:462308 }
[email protected]370eaf12013-05-18 09:19:492309 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2310 state_.texture_units[tt].bound_texture_cube_map = ref;
2311 glBindTexture(GL_TEXTURE_CUBE_MAP, ref->service_id());
2312 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2313 state_.texture_units[tt].bound_texture_2d = ref;
2314 glBindTexture(GL_TEXTURE_2D, ref->service_id());
[email protected]1958e0e2010-04-22 05:17:152315 }
[email protected]00f893d2010-08-24 18:55:492316 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502317 CHECK_GL_ERROR();
2318
[email protected]069944672012-04-25 20:52:232319 if (offscreen) {
[email protected]34ff8b0c2010-10-01 20:06:022320 if (attrib_parser.samples_ > 0 && attrib_parser.sample_buffers_ > 0 &&
[email protected]b0609652012-12-14 07:24:542321 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022322 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432323 // max_sample_count must be initialized to a sane value. If
2324 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2325 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022326 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
2327 offscreen_target_samples_ = std::min(attrib_parser.samples_,
2328 max_sample_count);
2329 } else {
2330 offscreen_target_samples_ = 1;
2331 }
[email protected]8a61d872012-01-20 12:43:562332 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved_;
[email protected]34ff8b0c2010-10-01 20:06:022333
2334 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2335 const bool rgb8_supported =
2336 context_->HasExtension("GL_OES_rgb8_rgba8");
2337 // The only available default render buffer formats in GLES2 have very
2338 // little precision. Don't enable multisampling unless 8-bit render
2339 // buffer formats are available--instead fall back to 8-bit textures.
2340 if (rgb8_supported && offscreen_target_samples_ > 1) {
2341 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2342 GL_RGBA8 : GL_RGB8;
2343 } else {
2344 offscreen_target_samples_ = 1;
2345 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2346 GL_RGBA : GL_RGB;
2347 }
2348
2349 // ANGLE only supports packed depth/stencil formats, so use it if it is
2350 // available.
2351 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182352 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272353 VLOG(1) << "GL_OES_packed_depth_stencil "
2354 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]71ee3642010-10-14 18:08:002355 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2356 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022357 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2358 offscreen_target_stencil_format_ = 0;
2359 } else {
2360 // It may be the case that this depth/stencil combination is not
2361 // supported, but this will be checked later by CheckFramebufferStatus.
2362 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2363 GL_DEPTH_COMPONENT16 : 0;
2364 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2365 GL_STENCIL_INDEX8 : 0;
2366 }
2367 } else {
2368 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2369 GL_RGBA : GL_RGB;
2370
2371 // If depth is requested at all, use the packed depth stencil format if
2372 // it's available, as some desktop GL drivers don't support any non-packed
2373 // formats for depth attachments.
2374 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182375 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272376 VLOG(1) << "GL_EXT_packed_depth_stencil "
2377 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022378
[email protected]71ee3642010-10-14 18:08:002379 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2380 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022381 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2382 offscreen_target_stencil_format_ = 0;
2383 } else {
2384 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2385 GL_DEPTH_COMPONENT : 0;
2386 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2387 GL_STENCIL_INDEX : 0;
2388 }
2389 }
2390
[email protected]97872062010-11-03 19:07:052391 offscreen_saved_color_format_ = attrib_parser.alpha_size_ > 0 ?
2392 GL_RGBA : GL_RGB;
2393
[email protected]6217d392010-03-25 22:08:352394 // Create the target frame buffer. This is the one that the client renders
2395 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352396 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352397 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022398 // Due to GLES2 format limitations, either the color texture (for
2399 // non-multisampling) or the color render buffer (for multisampling) will be
2400 // attached to the offscreen frame buffer. The render buffer has more
2401 // limited formats available to it, but the texture can't do multisampling.
2402 if (IsOffscreenBufferMultisampled()) {
[email protected]d5a28e452013-10-10 01:01:402403 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(
2404 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022405 offscreen_target_color_render_buffer_->Create();
2406 } else {
[email protected]ce296892013-10-24 22:04:362407 offscreen_target_color_texture_.reset(new BackTexture(
2408 memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022409 offscreen_target_color_texture_->Create();
2410 }
[email protected]d5a28e452013-10-10 01:01:402411 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(
2412 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152413 offscreen_target_depth_render_buffer_->Create();
[email protected]d5a28e452013-10-10 01:01:402414 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(
2415 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152416 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352417
2418 // Create the saved offscreen texture. The target frame buffer is copied
2419 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352420 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022421 offscreen_saved_frame_buffer_->Create();
2422 //
[email protected]ce296892013-10-24 22:04:362423 offscreen_saved_color_texture_.reset(new BackTexture(
2424 memory_tracker(), &state_));
[email protected]6217d392010-03-25 22:08:352425 offscreen_saved_color_texture_->Create();
2426
[email protected]6217d392010-03-25 22:08:352427 // Allocate the render buffers at their initial size and check the status
2428 // of the frame buffers is okay.
[email protected]799b4b22011-08-22 17:09:592429 if (!ResizeOffscreenFrameBuffer(size)) {
[email protected]d0498742010-09-20 20:27:012430 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382431 Destroy(true);
[email protected]6217d392010-03-25 22:08:352432 return false;
2433 }
2434
[email protected]678a73f2012-12-19 19:22:092435 // Allocate the offscreen saved color texture.
2436 DCHECK(offscreen_saved_color_format_);
2437 offscreen_saved_color_texture_->AllocateStorage(
2438 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2439
2440 offscreen_saved_frame_buffer_->AttachRenderTexture(
2441 offscreen_saved_color_texture_.get());
2442 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2443 GL_FRAMEBUFFER_COMPLETE) {
2444 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2445 Destroy(true);
2446 return false;
2447 }
2448
[email protected]6217d392010-03-25 22:08:352449 // Bind to the new default frame buffer (the offscreen target frame buffer).
2450 // This should now be associated with ID zero.
2451 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
[email protected]62e65f02013-05-29 22:28:102452 } else {
2453 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
2454 // These are NOT if the back buffer has these proprorties. They are
2455 // if we want the command buffer to enforce them regardless of what
2456 // the real backbuffer is assuming the real back buffer gives us more than
2457 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2458 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2459 // can't do anything about that.
2460
2461 GLint v = 0;
2462 glGetIntegerv(GL_ALPHA_BITS, &v);
2463 // This checks if the user requested RGBA and we have RGBA then RGBA. If the
2464 // user requested RGB then RGB. If the user did not specify a preference
2465 // than use whatever we were given. Same for DEPTH and STENCIL.
2466 back_buffer_color_format_ =
2467 (attrib_parser.alpha_size_ != 0 && v > 0) ? GL_RGBA : GL_RGB;
2468 glGetIntegerv(GL_DEPTH_BITS, &v);
2469 back_buffer_has_depth_ = attrib_parser.depth_size_ != 0 && v > 0;
2470 glGetIntegerv(GL_STENCIL_BITS, &v);
2471 back_buffer_has_stencil_ = attrib_parser.stencil_size_ != 0 && v > 0;
[email protected]6217d392010-03-25 22:08:352472 }
2473
[email protected]76a0ee102010-04-07 21:03:042474 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2475 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2476 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372477 // mailing list archives. It also implicitly enables the desktop GL
2478 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2479 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152480 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2481 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372482 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152483 }
[email protected]de17df392010-04-23 21:09:412484
[email protected]706b69f2012-07-27 04:59:302485 has_robustness_extension_ =
2486 context->HasExtension("GL_ARB_robustness") ||
2487 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432488
[email protected]c2f8c8402010-12-06 18:07:242489 if (!InitializeShaderTranslator()) {
2490 return false;
[email protected]de17df392010-04-23 21:09:412491 }
[email protected]76a0ee102010-04-07 21:03:042492
[email protected]e259eb412012-10-13 05:47:242493 state_.viewport_width = size.width();
2494 state_.viewport_height = size.height();
[email protected]43410e92012-04-20 17:06:282495
[email protected]5904806b2012-05-08 18:10:222496 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282497 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022498 viewport_max_width_ = viewport_params[0];
2499 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282500
[email protected]88a61bf2012-10-27 13:00:422501 state_.scissor_width = state_.viewport_width;
2502 state_.scissor_height = state_.viewport_height;
2503
[email protected]11f3e702012-06-19 19:00:012504 // Set all the default state because some GL drivers get it wrong.
[email protected]f731b9462012-10-30 00:35:222505 state_.InitCapabilities();
2506 state_.InitState();
[email protected]e259eb412012-10-13 05:47:242507 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]11f3e702012-06-19 19:00:012508
2509 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2510 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2511 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2512 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
2513
[email protected]88cfd132013-07-11 00:59:002514 bool call_gl_clear = true;
2515#if defined(OS_ANDROID)
2516 // Temporary workaround for Android WebView because this clear ignores the
2517 // clip and corrupts that external UI of the App. Not calling glClear is ok
2518 // because the system already clears the buffer before each draw. Proper
2519 // fix might be setting the scissor clip properly before initialize. See
2520 // crbug.com/259023 for details.
2521 call_gl_clear = surface_->GetHandle();
2522#endif
2523 if (call_gl_clear) {
2524 // Clear the backbuffer.
2525 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2526 }
[email protected]561cc0a62013-05-07 18:34:452527
[email protected]62e155e2012-10-23 22:43:152528 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462529 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2530 }
[email protected]dd289a5d62012-06-30 22:05:462531
[email protected]9b753992013-04-27 02:04:412532 if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2533 context_->SetUnbindFboOnMakeCurrent();
[email protected]85cb4682013-04-20 00:54:242534 }
[email protected]85cb4682013-04-20 00:54:242535
[email protected]40245ccf2013-11-13 04:00:492536 if (feature_info_->workarounds().release_image_after_use) {
2537 image_manager()->SetReleaseAfterUse();
2538 }
2539
[email protected]97419c02013-04-10 02:52:382540 // Only compositor contexts are known to use only the subset of GL
2541 // that can be safely migrated between the iGPU and the dGPU. Mark
2542 // those contexts as safe to forcibly transition between the GPUs.
2543 // http://crbug.com/180876, http://crbug.com/227228
2544 if (!offscreen)
2545 context_->SetSafeToForceGpuSwitch();
2546
[email protected]85a4ac22013-05-31 01:58:472547 async_pixel_transfer_manager_.reset(
[email protected]498b5c072013-06-04 19:30:072548 AsyncPixelTransferManager::Create(context.get()));
2549 async_pixel_transfer_manager_->Initialize(texture_manager());
[email protected]32145a92012-12-17 09:01:592550
[email protected]91c94eb2013-10-22 10:32:542551 framebuffer_manager()->AddObserver(this);
2552
[email protected]246a70452010-03-05 21:53:502553 return true;
[email protected]96449d2c2009-11-25 00:01:322554}
2555
[email protected]6d668892013-12-04 21:37:122556Capabilities GLES2DecoderImpl::GetCapabilities() {
2557 DCHECK(initialized());
2558
2559 Capabilities caps;
2560
2561 caps.fast_npot_mo8_textures =
2562 feature_info_->workarounds().enable_chromium_fast_npot_mo8_textures;
2563 caps.egl_image_external =
2564 feature_info_->feature_flags().oes_egl_image_external;
2565 caps.texture_format_bgra8888 =
2566 feature_info_->feature_flags().ext_texture_format_bgra8888;
2567 caps.texture_format_etc1 =
2568 feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture;
2569 caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle;
2570 caps.texture_usage = feature_info_->feature_flags().angle_texture_usage;
2571 caps.texture_storage = feature_info_->feature_flags().ext_texture_storage;
2572 caps.discard_framebuffer =
2573 feature_info_->feature_flags().ext_discard_framebuffer;
2574
2575#if defined(OS_MACOSX)
2576 // This is unconditionally true on mac, no need to test for it at runtime.
2577 caps.iosurface = true;
2578#endif
2579
[email protected]35387b3b2014-01-11 22:50:112580 caps.post_sub_buffer = surface_->HasExtension("GL_CHROMIUM_post_sub_buffer");
[email protected]6d668892013-12-04 21:37:122581
2582 return caps;
2583}
2584
[email protected]302ce6d2011-07-07 23:28:112585void GLES2DecoderImpl::UpdateCapabilities() {
2586 util_.set_num_compressed_texture_formats(
2587 validators_->compressed_texture_format.GetValues().size());
2588 util_.set_num_shader_binary_formats(
2589 validators_->shader_binary_format.GetValues().size());
2590}
2591
[email protected]c2f8c8402010-12-06 18:07:242592bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442593 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2594
[email protected]c2f8c8402010-12-06 18:07:242595 if (!use_shader_translator_) {
2596 return true;
2597 }
2598 ShBuiltInResources resources;
2599 ShInitBuiltInResources(&resources);
2600 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2601 resources.MaxVertexUniformVectors =
2602 group_->max_vertex_uniform_vectors();
2603 resources.MaxVaryingVectors = group_->max_varying_vectors();
2604 resources.MaxVertexTextureImageUnits =
2605 group_->max_vertex_texture_image_units();
2606 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2607 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2608 resources.MaxFragmentUniformVectors =
2609 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:492610 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]a0b78142013-05-23 00:47:242611 resources.MaxExpressionComplexity = 256;
2612 resources.MaxCallStackDepth = 256;
[email protected]f0d74742011-10-03 16:31:042613
[email protected]9e98f61b2013-03-05 02:21:142614#if (ANGLE_SH_VERSION >= 110)
[email protected]46c86752013-05-21 05:08:392615 GLint range[2] = { 0, 0 };
[email protected]8dc1bf92013-03-12 03:58:212616 GLint precision = 0;
2617 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
2618 range, &precision);
[email protected]448e459e2013-06-12 17:00:412619 resources.FragmentPrecisionHigh =
2620 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
[email protected]9e98f61b2013-03-05 02:21:142621#endif
2622
[email protected]f0d74742011-10-03 16:31:042623 if (force_webgl_glsl_validation_) {
2624 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:492625 resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:132626 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
[email protected]cd8f1892013-09-05 00:14:442627 if (!draw_buffers_explicitly_enabled_)
2628 resources.MaxDrawBuffers = 1;
[email protected]f0d74742011-10-03 16:31:042629 } else {
2630 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152631 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462632 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152633 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062634 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152635 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:492636 resources.EXT_draw_buffers =
2637 features().ext_draw_buffers ? 1 : 0;
[email protected]70dc60932013-06-04 03:33:492638 resources.EXT_frag_depth =
2639 features().ext_frag_depth ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:042640 }
2641
[email protected]26b61442013-03-17 16:12:012642 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC
2643 : SH_GLES2_SPEC;
[email protected]6aedcdc2013-01-24 01:25:052644 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:022645#if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
[email protected]6aedcdc2013-01-24 01:25:052646 resources.HashFunction = &CityHashForAngle;
[email protected]3d944a82013-02-12 19:09:022647#else
2648 resources.HashFunction = &CityHash64;
2649#endif
[email protected]6aedcdc2013-01-24 01:25:052650 else
2651 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:122652 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2653 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2654 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
[email protected]a6739bc2013-09-07 04:45:212655 int driver_bug_workarounds = 0;
2656 if (workarounds().needs_glsl_built_in_function_emulation)
2657 driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS;
[email protected]81187c62013-09-09 23:54:542658 if (workarounds().init_gl_position_in_vertex_shader)
2659 driver_bug_workarounds |= SH_INIT_GL_POSITION;
[email protected]f0c87602013-10-17 19:34:112660 if (workarounds().unfold_short_circuit_as_ternary_operation)
2661 driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT;
[email protected]b03219d2014-02-12 11:17:052662 if (workarounds().init_varyings_without_static_use)
2663 driver_bug_workarounds |= SH_INIT_VARYINGS_WITHOUT_STATIC_USE;
[email protected]87fb6ab2012-06-13 22:28:042664
2665 ShaderTranslatorCache* cache = ShaderTranslatorCache::GetInstance();
2666 vertex_translator_ = cache->GetTranslator(
2667 SH_VERTEX_SHADER, shader_spec, &resources,
[email protected]a6739bc2013-09-07 04:45:212668 implementation_type,
2669 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042670 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242671 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:382672 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242673 return false;
2674 }
[email protected]87fb6ab2012-06-13 22:28:042675
2676 fragment_translator_ = cache->GetTranslator(
2677 SH_FRAGMENT_SHADER, shader_spec, &resources,
[email protected]a6739bc2013-09-07 04:45:212678 implementation_type,
2679 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042680 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242681 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:382682 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242683 return false;
2684 }
2685 return true;
2686}
2687
[email protected]ae51d192010-04-27 00:48:032688bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:472689 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352690 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032691 return false;
2692 }
2693 }
[email protected]40d90a22013-04-09 03:39:552694 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032695 glGenBuffersARB(n, service_ids.get());
2696 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352697 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032698 }
2699 return true;
2700}
2701
2702bool GLES2DecoderImpl::GenFramebuffersHelper(
2703 GLsizei n, const GLuint* client_ids) {
2704 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352705 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032706 return false;
2707 }
2708 }
[email protected]40d90a22013-04-09 03:39:552709 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032710 glGenFramebuffersEXT(n, service_ids.get());
2711 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352712 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032713 }
2714 return true;
2715}
2716
2717bool GLES2DecoderImpl::GenRenderbuffersHelper(
2718 GLsizei n, const GLuint* client_ids) {
2719 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352720 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032721 return false;
2722 }
2723 }
[email protected]40d90a22013-04-09 03:39:552724 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032725 glGenRenderbuffersEXT(n, service_ids.get());
2726 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352727 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032728 }
2729 return true;
2730}
2731
2732bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
2733 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352734 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032735 return false;
2736 }
2737 }
[email protected]40d90a22013-04-09 03:39:552738 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032739 glGenTextures(n, service_ids.get());
2740 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352741 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032742 }
2743 return true;
2744}
2745
2746void GLES2DecoderImpl::DeleteBuffersHelper(
2747 GLsizei n, const GLuint* client_ids) {
2748 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:212749 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102750 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242751 state_.vertex_attrib_manager->Unbind(buffer);
[email protected]7cd76fd2013-06-02 21:11:112752 if (state_.bound_array_buffer.get() == buffer) {
[email protected]e259eb412012-10-13 05:47:242753 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102754 }
[email protected]ed9f9cd2013-02-27 21:12:352755 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032756 }
[email protected]a93bb842010-02-16 23:03:472757 }
[email protected]07f54fcc2009-12-22 02:46:302758}
2759
[email protected]ae51d192010-04-27 00:48:032760void GLES2DecoderImpl::DeleteFramebuffersHelper(
2761 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452762 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152763 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:112764
[email protected]a25fa872010-03-25 02:57:582765 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352766 Framebuffer* framebuffer =
2767 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102768 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]9d3b2e12013-10-02 01:04:342769 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
2770 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]c986af502013-08-14 01:04:442771 framebuffer_state_.clear_state_dirty = true;
[email protected]ebfb73c2012-08-15 02:37:452772 GLenum target = supports_separate_framebuffer_binds ?
2773 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112774 glBindFramebufferEXT(target, GetBackbufferServiceId());
2775 }
[email protected]9d3b2e12013-10-02 01:04:342776 if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) {
2777 framebuffer_state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:452778 GLenum target = supports_separate_framebuffer_binds ?
2779 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112780 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:462781 }
[email protected]70d34263c2013-01-09 00:27:452782 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:352783 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032784 }
[email protected]a25fa872010-03-25 02:57:582785 }
[email protected]07f54fcc2009-12-22 02:46:302786}
2787
[email protected]ae51d192010-04-27 00:48:032788void GLES2DecoderImpl::DeleteRenderbuffersHelper(
2789 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452790 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152791 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:582792 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352793 Renderbuffer* renderbuffer =
2794 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102795 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:112796 if (state_.bound_renderbuffer.get() == renderbuffer) {
[email protected]e259eb412012-10-13 05:47:242797 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102798 }
2799 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452800 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:342801 if (framebuffer_state_.bound_read_framebuffer.get()) {
2802 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112803 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102804 }
[email protected]9d3b2e12013-10-02 01:04:342805 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2806 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112807 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102808 }
2809 } else {
[email protected]9d3b2e12013-10-02 01:04:342810 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2811 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112812 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102813 }
2814 }
[email protected]c986af502013-08-14 01:04:442815 framebuffer_state_.clear_state_dirty = true;
[email protected]ed9f9cd2013-02-27 21:12:352816 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032817 }
[email protected]a25fa872010-03-25 02:57:582818 }
[email protected]07f54fcc2009-12-22 02:46:302819}
2820
[email protected]ae51d192010-04-27 00:48:032821void GLES2DecoderImpl::DeleteTexturesHelper(
2822 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452823 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152824 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:472825 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]370eaf12013-05-18 09:19:492826 TextureRef* texture_ref = GetTexture(client_ids[ii]);
2827 if (texture_ref) {
2828 Texture* texture = texture_ref->texture();
[email protected]a0b78dc2011-11-11 10:43:102829 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:442830 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:462831 }
[email protected]370eaf12013-05-18 09:19:492832 // Unbind texture_ref from texture_ref units.
[email protected]1868a342012-11-07 15:56:022833 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]370eaf12013-05-18 09:19:492834 state_.texture_units[jj].Unbind(texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102835 }
2836 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452837 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:342838 if (framebuffer_state_.bound_read_framebuffer.get()) {
2839 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112840 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102841 }
[email protected]9d3b2e12013-10-02 01:04:342842 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2843 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112844 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102845 }
2846 } else {
[email protected]9d3b2e12013-10-02 01:04:342847 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2848 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112849 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102850 }
2851 }
[email protected]e51bdf32011-11-23 22:21:462852#if defined(OS_MACOSX)
[email protected]4f9958142013-07-02 03:58:072853 GLuint service_id = texture->service_id();
[email protected]e51bdf32011-11-23 22:21:462854 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
2855 ReleaseIOSurfaceForTexture(service_id);
2856 }
2857#endif
[email protected]ed9f9cd2013-02-27 21:12:352858 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032859 }
[email protected]a93bb842010-02-16 23:03:472860 }
[email protected]07f54fcc2009-12-22 02:46:302861}
2862
[email protected]43f28f832010-02-03 02:28:482863// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:322864
[email protected]eb54a562010-01-20 21:55:182865bool GLES2DecoderImpl::MakeCurrent() {
[email protected]177d1342013-12-07 04:20:342866 if (!context_.get())
[email protected]63c9b052012-05-17 18:27:382867 return false;
2868
[email protected]177d1342013-12-07 04:20:342869 if (!context_->MakeCurrent(surface_.get()) || WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:432870 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]e9f0ca82013-04-01 23:52:292871
2872 // Some D3D drivers cannot recover from device lost in the GPU process
2873 // sandbox. Allow a new GPU process to launch.
2874 if (workarounds().exit_on_context_lost) {
2875 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
2876 << " a D3D device in the Chrome GPU process sandbox.";
[email protected]6eb775352013-08-27 05:57:162877#if defined(OS_WIN)
2878 base::win::SetShouldCrashOnProcessDetach(false);
2879#endif
[email protected]e9f0ca82013-04-01 23:52:292880 exit(0);
2881 }
2882
[email protected]63c9b052012-05-17 18:27:382883 return false;
[email protected]38d139d2011-07-14 00:38:432884 }
2885
[email protected]69a8701e2013-03-07 21:31:092886 ProcessFinishedAsyncTransfers();
[email protected]69a8701e2013-03-07 21:31:092887
[email protected]9b753992013-04-27 02:04:412888 // Rebind the FBO if it was unbound by the context.
2889 if (workarounds().unbind_fbo_on_context_switch)
2890 RestoreFramebufferBindings();
2891
[email protected]c986af502013-08-14 01:04:442892 framebuffer_state_.clear_state_dirty = true;
[email protected]370eaf12013-05-18 09:19:492893
[email protected]69a8701e2013-03-07 21:31:092894 return true;
2895}
2896
2897void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]5a36dc132013-07-23 23:17:552898 ProcessPendingReadPixels();
[email protected]fe8d73c2013-02-16 22:37:322899 if (engine() && query_manager_.get())
2900 query_manager_->ProcessPendingTransferQueries();
2901
[email protected]5b3a8e02013-03-13 05:36:442902 // TODO(epenner): Is there a better place to do this?
2903 // This needs to occur before we execute any batch of commands
2904 // from the client, as the client may have recieved an async
2905 // completion while issuing those commands.
2906 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]b68b100752013-06-05 08:34:482907 async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
[email protected]eb54a562010-01-20 21:55:182908}
2909
[email protected]8e3e0662010-08-23 18:46:302910static void RebindCurrentFramebuffer(
2911 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:062912 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:242913 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:062914 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:462915
[email protected]a3783712012-01-20 22:18:242916 if (framebuffer_id == 0) {
2917 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:302918 }
[email protected]297ca1c2011-06-20 23:08:462919
[email protected]8e3e0662010-08-23 18:46:302920 glBindFramebufferEXT(target, framebuffer_id);
2921}
2922
2923void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]c986af502013-08-14 01:04:442924 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:462925
[email protected]62e155e2012-10-23 22:43:152926 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:302927 RebindCurrentFramebuffer(
2928 GL_FRAMEBUFFER,
[email protected]9d3b2e12013-10-02 01:04:342929 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242930 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302931 } else {
2932 RebindCurrentFramebuffer(
2933 GL_READ_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:342934 framebuffer_state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242935 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302936 RebindCurrentFramebuffer(
2937 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:342938 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242939 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302940 }
[email protected]70d34263c2013-01-09 00:27:452941 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:302942}
2943
[email protected]0d6bfdc2011-11-02 01:32:202944bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:352945 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:202946 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:102947 if (!framebuffer) {
[email protected]60f22d32012-12-12 00:31:582948 if (backbuffer_needs_clear_bits_) {
2949 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
2950 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
2951 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2952 glClearStencil(0);
2953 glStencilMask(-1);
2954 glClearDepth(1.0f);
2955 glDepthMask(true);
2956 glDisable(GL_SCISSOR_TEST);
2957 glClear(backbuffer_needs_clear_bits_);
2958 backbuffer_needs_clear_bits_ = 0;
2959 RestoreClearState();
2960 }
[email protected]0d6bfdc2011-11-02 01:32:202961 return true;
2962 }
2963
[email protected]968351b2011-12-20 08:26:512964 if (framebuffer_manager()->IsComplete(framebuffer)) {
2965 return true;
2966 }
2967
[email protected]0d6bfdc2011-11-02 01:32:202968 GLenum completeness = framebuffer->IsPossiblyComplete();
2969 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512970 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432971 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:272972 return false;
2973 }
[email protected]0d6bfdc2011-11-02 01:32:202974
2975 // Are all the attachments cleared?
2976 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
2977 texture_manager()->HaveUnclearedMips()) {
2978 if (!framebuffer->IsCleared()) {
2979 // Can we clear them?
[email protected]73276522012-11-09 05:50:202980 if (framebuffer->GetStatus(texture_manager(), target) !=
2981 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512982 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432983 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
2984 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:202985 return false;
2986 }
2987 ClearUnclearedAttachments(target, framebuffer);
2988 }
2989 }
2990
[email protected]968351b2011-12-20 08:26:512991 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:202992 if (framebuffer->GetStatus(texture_manager(), target) !=
2993 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512994 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432995 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
2996 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:512997 return false;
2998 }
2999 framebuffer_manager()->MarkAsComplete(framebuffer);
3000 }
3001
[email protected]0d6bfdc2011-11-02 01:32:203002 // NOTE: At this point we don't know if the framebuffer is complete but
3003 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:273004 return true;
3005}
3006
[email protected]0d6bfdc2011-11-02 01:32:203007bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:153008 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:513009 bool valid = CheckFramebufferValid(
[email protected]9d3b2e12013-10-02 01:04:343010 framebuffer_state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT,
3011 func_name);
[email protected]28718a92013-04-04 12:12:513012
3013 if (valid)
3014 OnUseFramebuffer();
3015
3016 return valid;
[email protected]0d6bfdc2011-11-02 01:32:203017 }
[email protected]9d3b2e12013-10-02 01:04:343018 return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113019 GL_DRAW_FRAMEBUFFER_EXT,
3020 func_name) &&
[email protected]9d3b2e12013-10-02 01:04:343021 CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113022 GL_READ_FRAMEBUFFER_EXT,
3023 func_name);
[email protected]0d6bfdc2011-11-02 01:32:203024}
3025
[email protected]8e3e0662010-08-23 18:46:303026gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:353027 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453028 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203029 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:353030 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:203031 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:263032 if (attachment) {
3033 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:503034 }
[email protected]9edc6b22010-12-23 02:00:263035 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:023036 } else if (offscreen_target_frame_buffer_.get()) {
3037 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:353038 } else {
[email protected]f62a5ab2011-05-23 20:34:153039 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:023040 }
[email protected]246a70452010-03-05 21:53:503041}
3042
[email protected]68586372013-12-11 01:27:593043GLenum GLES2DecoderImpl::GetBoundReadFrameBufferTextureType() {
3044 Framebuffer* framebuffer =
3045 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
3046 if (framebuffer != NULL) {
3047 return framebuffer->GetColorAttachmentTextureType();
3048 } else {
3049 return GL_UNSIGNED_BYTE;
3050 }
3051}
3052
[email protected]9edc6b22010-12-23 02:00:263053GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353054 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453055 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203056 if (framebuffer != NULL) {
3057 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:463058 } else if (offscreen_target_frame_buffer_.get()) {
3059 return offscreen_target_color_format_;
3060 } else {
3061 return back_buffer_color_format_;
3062 }
3063}
3064
3065GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353066 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453067 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203068 if (framebuffer != NULL) {
3069 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:263070 } else if (offscreen_target_frame_buffer_.get()) {
3071 return offscreen_target_color_format_;
3072 } else {
[email protected]32fe9aa2011-01-21 23:47:133073 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:263074 }
3075}
3076
[email protected]9a5afa432011-07-22 18:16:393077void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]2ad674132013-06-05 07:48:513078 if (!offscreen_saved_color_texture_info_.get())
3079 return;
3080 GLenum target = offscreen_saved_color_texture_info_->texture()->target();
3081 glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
3082 texture_manager()->SetLevelInfo(
3083 offscreen_saved_color_texture_info_.get(),
3084 GL_TEXTURE_2D,
3085 0, // level
3086 GL_RGBA,
3087 offscreen_size_.width(),
3088 offscreen_size_.height(),
3089 1, // depth
3090 0, // border
3091 GL_RGBA,
3092 GL_UNSIGNED_BYTE,
3093 true);
3094 texture_manager()->SetParameter(
3095 "UpdateParentTextureInfo",
3096 GetErrorState(),
3097 offscreen_saved_color_texture_info_.get(),
3098 GL_TEXTURE_MAG_FILTER,
3099 GL_NEAREST);
3100 texture_manager()->SetParameter(
3101 "UpdateParentTextureInfo",
3102 GetErrorState(),
3103 offscreen_saved_color_texture_info_.get(),
3104 GL_TEXTURE_MIN_FILTER,
3105 GL_NEAREST);
3106 texture_manager()->SetParameter(
3107 "UpdateParentTextureInfo",
3108 GetErrorState(),
3109 offscreen_saved_color_texture_info_.get(),
3110 GL_TEXTURE_WRAP_S,
3111 GL_CLAMP_TO_EDGE);
3112 texture_manager()->SetParameter(
3113 "UpdateParentTextureInfo",
3114 GetErrorState(),
3115 offscreen_saved_color_texture_info_.get(),
3116 GL_TEXTURE_WRAP_T,
3117 GL_CLAMP_TO_EDGE);
[email protected]c986af502013-08-14 01:04:443118 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
3119 &state_, target);
[email protected]2ad674132013-06-05 07:48:513120 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
[email protected]6217d392010-03-25 22:08:353121}
3122
[email protected]799b4b22011-08-22 17:09:593123void GLES2DecoderImpl::SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:073124 const base::Callback<void(gfx::Size, float)>& callback) {
[email protected]9d37f062011-11-22 01:24:523125 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:003126}
3127
[email protected]1d82e822013-04-10 21:32:323128Logger* GLES2DecoderImpl::GetLogger() {
3129 return &logger_;
[email protected]6b6e7ee2011-12-13 08:04:523130}
3131
[email protected]cac16542014-01-15 17:53:513132void GLES2DecoderImpl::BeginDecoding() {
3133 gpu_tracer_->BeginDecoding();
3134 gpu_trace_commands_ = gpu_tracer_->IsTracing();
3135}
3136
3137void GLES2DecoderImpl::EndDecoding() {
3138 gpu_tracer_->EndDecoding();
3139}
3140
[email protected]d3eba342013-04-18 21:11:503141ErrorState* GLES2DecoderImpl::GetErrorState() {
3142 return state_.GetErrorState();
3143}
3144
[email protected]e3932abb2013-03-13 00:01:373145void GLES2DecoderImpl::SetShaderCacheCallback(
3146 const ShaderCacheCallback& callback) {
3147 shader_cache_callback_ = callback;
3148}
3149
[email protected]840a7e462013-02-27 01:29:513150void GLES2DecoderImpl::SetWaitSyncPointCallback(
3151 const WaitSyncPointCallback& callback) {
3152 wait_sync_point_callback_ = callback;
3153}
3154
[email protected]85a4ac22013-05-31 01:58:473155AsyncPixelTransferManager*
3156 GLES2DecoderImpl::GetAsyncPixelTransferManager() {
3157 return async_pixel_transfer_manager_.get();
3158}
3159
3160void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
3161 async_pixel_transfer_manager_.reset();
[email protected]32145a92012-12-17 09:01:593162}
3163
[email protected]498b5c072013-06-04 19:30:073164void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest(
3165 AsyncPixelTransferManager* manager) {
3166 async_pixel_transfer_manager_ = make_scoped_ptr(manager);
3167}
3168
[email protected]1318e922010-09-17 22:03:163169bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3170 uint32* service_texture_id) {
[email protected]370eaf12013-05-18 09:19:493171 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3172 if (texture_ref) {
3173 *service_texture_id = texture_ref->service_id();
[email protected]1318e922010-09-17 22:03:163174 return true;
3175 }
3176 return false;
3177}
3178
[email protected]63b465922012-09-06 02:04:523179uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]c986af502013-08-14 01:04:443180 return texture_state_.texture_upload_count +
[email protected]b68b100752013-06-05 08:34:483181 async_pixel_transfer_manager_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523182}
3183
3184base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]c986af502013-08-14 01:04:443185 return texture_state_.total_texture_upload_time +
[email protected]b68b100752013-06-05 08:34:483186 async_pixel_transfer_manager_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523187}
3188
3189base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3190 return total_processing_commands_time_;
3191}
3192
[email protected]dc25dda2012-09-27 21:36:303193void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3194 total_processing_commands_time_ += time;
3195}
3196
[email protected]63c9b052012-05-17 18:27:383197void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063198 if (!initialized())
3199 return;
3200
[email protected]63c9b052012-05-17 18:27:383201 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053202
[email protected]80eb6b52012-01-19 00:14:413203 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243204 state_.vertex_attrib_manager = NULL;
[email protected]944b62f32012-09-27 02:20:463205 default_vertex_attrib_manager_ = NULL;
[email protected]1868a342012-11-07 15:56:023206 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243207 state_.bound_array_buffer = NULL;
[email protected]8ebd46c2014-01-08 12:06:133208 state_.current_queries.clear();
[email protected]9d3b2e12013-10-02 01:04:343209 framebuffer_state_.bound_read_framebuffer = NULL;
3210 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]e259eb412012-10-13 05:47:243211 state_.bound_renderbuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413212
[email protected]cadac622013-06-11 16:46:363213 if (offscreen_saved_color_texture_info_.get()) {
[email protected]2ad674132013-06-05 07:48:513214 DCHECK(offscreen_target_color_texture_);
3215 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
3216 offscreen_saved_color_texture_->id());
3217 offscreen_saved_color_texture_->Invalidate();
3218 offscreen_saved_color_texture_info_ = NULL;
3219 }
[email protected]eadc96792010-10-27 19:39:393220 if (have_context) {
[email protected]c322e882012-05-23 18:06:183221 if (copy_texture_CHROMIUM_.get()) {
3222 copy_texture_CHROMIUM_->Destroy();
3223 copy_texture_CHROMIUM_.reset();
3224 }
[email protected]43410e92012-04-20 17:06:283225
[email protected]7cd76fd2013-06-02 21:11:113226 if (state_.current_program.get()) {
3227 program_manager()->UnuseProgram(shader_manager(),
3228 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:143229 }
3230
[email protected]b1122982010-05-17 23:04:243231 if (attrib_0_buffer_id_) {
3232 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3233 }
[email protected]8fbedc02010-11-18 18:43:403234 if (fixed_attrib_buffer_id_) {
3235 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3236 }
[email protected]b1122982010-05-17 23:04:243237
[email protected]4a4c18b2013-09-13 22:50:103238 if (validation_texture_) {
3239 glDeleteTextures(1, &validation_texture_);
3240 glDeleteFramebuffersEXT(1, &validation_fbo_multisample_);
3241 glDeleteFramebuffersEXT(1, &validation_fbo_);
3242 }
3243
[email protected]97872062010-11-03 19:07:053244 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543245 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053246 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543247 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053248 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023249 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053250 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153251 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053252 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153253 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053254 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023255 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053256 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543257 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273258 if (offscreen_resolved_frame_buffer_.get())
3259 offscreen_resolved_frame_buffer_->Destroy();
3260 if (offscreen_resolved_color_texture_.get())
3261 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053262 } else {
3263 if (offscreen_target_frame_buffer_.get())
3264 offscreen_target_frame_buffer_->Invalidate();
3265 if (offscreen_target_color_texture_.get())
3266 offscreen_target_color_texture_->Invalidate();
3267 if (offscreen_target_color_render_buffer_.get())
3268 offscreen_target_color_render_buffer_->Invalidate();
3269 if (offscreen_target_depth_render_buffer_.get())
3270 offscreen_target_depth_render_buffer_->Invalidate();
3271 if (offscreen_target_stencil_render_buffer_.get())
3272 offscreen_target_stencil_render_buffer_->Invalidate();
3273 if (offscreen_saved_frame_buffer_.get())
3274 offscreen_saved_frame_buffer_->Invalidate();
3275 if (offscreen_saved_color_texture_.get())
3276 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273277 if (offscreen_resolved_frame_buffer_.get())
3278 offscreen_resolved_frame_buffer_->Invalidate();
3279 if (offscreen_resolved_color_texture_.get())
3280 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023281 }
[email protected]83a52d032013-07-24 10:30:373282
3283 // Current program must be cleared after calling ProgramManager::UnuseProgram.
3284 // Otherwise, we can leak objects. http://crbug.com/258772.
3285 // state_.current_program must be reset before group_ is reset because
3286 // the later deletes the ProgramManager object that referred by
3287 // state_.current_program object.
3288 state_.current_program = NULL;
3289
[email protected]43410e92012-04-20 17:06:283290 copy_texture_CHROMIUM_.reset();
[email protected]97872062010-11-03 19:07:053291
[email protected]882ba1e22012-03-08 19:02:533292 if (query_manager_.get()) {
3293 query_manager_->Destroy(have_context);
3294 query_manager_.reset();
3295 }
3296
[email protected]944b62f32012-09-27 02:20:463297 if (vertex_array_manager_ .get()) {
3298 vertex_array_manager_->Destroy(have_context);
3299 vertex_array_manager_.reset();
3300 }
3301
[email protected]97872062010-11-03 19:07:053302 offscreen_target_frame_buffer_.reset();
3303 offscreen_target_color_texture_.reset();
3304 offscreen_target_color_render_buffer_.reset();
3305 offscreen_target_depth_render_buffer_.reset();
3306 offscreen_target_stencil_render_buffer_.reset();
3307 offscreen_saved_frame_buffer_.reset();
3308 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273309 offscreen_resolved_frame_buffer_.reset();
3310 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463311
[email protected]85a4ac22013-05-31 01:58:473312 // Should destroy the transfer manager before the texture manager held
3313 // by the context group.
3314 async_pixel_transfer_manager_.reset();
3315
[email protected]7cd76fd2013-06-02 21:11:113316 if (group_.get()) {
[email protected]ac5e4022014-01-24 12:44:393317 framebuffer_manager()->RemoveObserver(this);
[email protected]2d9d3b92013-01-18 01:07:233318 group_->Destroy(this, have_context);
3319 group_ = NULL;
3320 }
3321
3322 if (context_.get()) {
3323 context_->ReleaseCurrent(NULL);
3324 context_ = NULL;
3325 }
3326
[email protected]e51bdf32011-11-23 22:21:463327#if defined(OS_MACOSX)
3328 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3329 it != texture_to_io_surface_map_.end(); ++it) {
3330 CFRelease(it->second);
3331 }
3332 texture_to_io_surface_map_.clear();
3333#endif
[email protected]96449d2c2009-11-25 00:01:323334}
3335
[email protected]63c9b052012-05-17 18:27:383336void GLES2DecoderImpl::SetSurface(
3337 const scoped_refptr<gfx::GLSurface>& surface) {
3338 DCHECK(context_->IsCurrent(NULL));
3339 DCHECK(surface_.get());
3340 surface_ = surface;
3341 RestoreCurrentFramebufferBindings();
3342}
3343
[email protected]aba551b2014-02-08 03:38:323344void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
3345 if (!offscreen_saved_color_texture_.get()) {
3346 LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context";
3347 return;
3348 }
[email protected]2ad674132013-06-05 07:48:513349 if (!offscreen_saved_color_texture_info_.get()) {
[email protected]3c644d82011-06-20 19:58:243350 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]f46476932013-06-08 05:36:073351 offscreen_saved_color_texture_info_ = TextureRef::Create(
3352 texture_manager(), 0, service_id);
[email protected]2ad674132013-06-05 07:48:513353 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(),
3354 GL_TEXTURE_2D);
[email protected]9a5afa432011-07-22 18:16:393355 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243356 }
[email protected]aba551b2014-02-08 03:38:323357 mailbox_manager()->ProduceTexture(
3358 GL_TEXTURE_2D, mailbox, offscreen_saved_color_texture_info_->texture());
[email protected]3c644d82011-06-20 19:58:243359}
3360
[email protected]799b4b22011-08-22 17:09:593361bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3362 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3363 if (!is_offscreen) {
3364 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3365 << " with an onscreen framebuffer.";
3366 return false;
3367 }
3368
3369 if (offscreen_size_ == size)
3370 return true;
3371
3372 offscreen_size_ = size;
3373 int w = offscreen_size_.width();
3374 int h = offscreen_size_.height();
3375 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3376 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3377 << "to allocate storage due to excessive dimensions.";
3378 return false;
3379 }
3380
3381 // Reallocate the offscreen target buffers.
3382 DCHECK(offscreen_target_color_format_);
3383 if (IsOffscreenBufferMultisampled()) {
3384 if (!offscreen_target_color_render_buffer_->AllocateStorage(
[email protected]f42f05b2013-11-15 21:46:183385 feature_info_, offscreen_size_, offscreen_target_color_format_,
[email protected]799b4b22011-08-22 17:09:593386 offscreen_target_samples_)) {
3387 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3388 << "to allocate storage for offscreen target color buffer.";
3389 return false;
3390 }
3391 } else {
3392 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093393 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593394 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3395 << "to allocate storage for offscreen target color texture.";
3396 return false;
3397 }
3398 }
3399 if (offscreen_target_depth_format_ &&
3400 !offscreen_target_depth_render_buffer_->AllocateStorage(
[email protected]f42f05b2013-11-15 21:46:183401 feature_info_, offscreen_size_, offscreen_target_depth_format_,
[email protected]799b4b22011-08-22 17:09:593402 offscreen_target_samples_)) {
3403 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3404 << "to allocate storage for offscreen target depth buffer.";
3405 return false;
3406 }
3407 if (offscreen_target_stencil_format_ &&
3408 !offscreen_target_stencil_render_buffer_->AllocateStorage(
[email protected]f42f05b2013-11-15 21:46:183409 feature_info_, offscreen_size_, offscreen_target_stencil_format_,
[email protected]799b4b22011-08-22 17:09:593410 offscreen_target_samples_)) {
3411 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3412 << "to allocate storage for offscreen target stencil buffer.";
3413 return false;
3414 }
3415
3416 // Attach the offscreen target buffers to the target frame buffer.
3417 if (IsOffscreenBufferMultisampled()) {
3418 offscreen_target_frame_buffer_->AttachRenderBuffer(
3419 GL_COLOR_ATTACHMENT0,
3420 offscreen_target_color_render_buffer_.get());
3421 } else {
3422 offscreen_target_frame_buffer_->AttachRenderTexture(
3423 offscreen_target_color_texture_.get());
3424 }
3425 if (offscreen_target_depth_format_) {
3426 offscreen_target_frame_buffer_->AttachRenderBuffer(
3427 GL_DEPTH_ATTACHMENT,
3428 offscreen_target_depth_render_buffer_.get());
3429 }
3430 const bool packed_depth_stencil =
3431 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3432 if (packed_depth_stencil) {
3433 offscreen_target_frame_buffer_->AttachRenderBuffer(
3434 GL_STENCIL_ATTACHMENT,
3435 offscreen_target_depth_render_buffer_.get());
3436 } else if (offscreen_target_stencil_format_) {
3437 offscreen_target_frame_buffer_->AttachRenderBuffer(
3438 GL_STENCIL_ATTACHMENT,
3439 offscreen_target_stencil_render_buffer_.get());
3440 }
3441
3442 if (offscreen_target_frame_buffer_->CheckStatus() !=
3443 GL_FRAMEBUFFER_COMPLETE) {
3444 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3445 << "because offscreen FBO was incomplete.";
3446 return false;
3447 }
3448
3449 // Clear the target frame buffer.
3450 {
3451 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3452 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
3453 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
3454 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3455 glClearStencil(0);
3456 glStencilMaskSeparate(GL_FRONT, -1);
3457 glStencilMaskSeparate(GL_BACK, -1);
3458 glClearDepth(0);
3459 glDepthMask(GL_TRUE);
3460 glDisable(GL_SCISSOR_TEST);
3461 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3462 RestoreClearState();
3463 }
[email protected]d85ef76d2011-09-08 22:21:433464
3465 // Destroy the offscreen resolved framebuffers.
3466 if (offscreen_resolved_frame_buffer_.get())
3467 offscreen_resolved_frame_buffer_->Destroy();
3468 if (offscreen_resolved_color_texture_.get())
3469 offscreen_resolved_color_texture_->Destroy();
3470 offscreen_resolved_color_texture_.reset();
3471 offscreen_resolved_frame_buffer_.reset();
3472
[email protected]799b4b22011-08-22 17:09:593473 return true;
[email protected]6217d392010-03-25 22:08:353474}
3475
[email protected]799b4b22011-08-22 17:09:593476error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:353477 uint32 immediate_data_size, const cmds::ResizeCHROMIUM& c) {
[email protected]09e17272012-11-30 10:30:443478 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023479 return error::kDeferCommandUntilLater;
3480
[email protected]799b4b22011-08-22 17:09:593481 GLuint width = static_cast<GLuint>(c.width);
3482 GLuint height = static_cast<GLuint>(c.height);
[email protected]729c0b42013-05-26 02:05:073483 GLfloat scale_factor = c.scale_factor;
[email protected]799b4b22011-08-22 17:09:593484 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:413485
3486 width = std::max(1U, width);
3487 height = std::max(1U, height);
3488
[email protected]a0d989162011-11-22 13:15:073489#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3490 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003491 // Make sure that we are done drawing to the back buffer before resizing.
3492 glFinish();
3493#endif
[email protected]799b4b22011-08-22 17:09:593494 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3495 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493496 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3497 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3498 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593499 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493500 }
[email protected]7ff86b92010-11-25 17:50:003501 }
[email protected]799b4b22011-08-22 17:09:593502
[email protected]9d37f062011-11-22 01:24:523503 if (!resize_callback_.is_null()) {
[email protected]729c0b42013-05-26 02:05:073504 resize_callback_.Run(gfx::Size(width, height), scale_factor);
[email protected]0e9346b2013-03-16 16:35:443505 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493506 if (!context_->IsCurrent(surface_.get())) {
3507 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3508 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053509 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493510 }
[email protected]658f7562011-09-09 05:24:053511 }
[email protected]799b4b22011-08-22 17:09:593512
3513 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393514}
3515
[email protected]96449d2c2009-11-25 00:01:323516const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3517 if (command_id > kStartPoint && command_id < kNumCommands) {
3518 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3519 }
3520 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3521}
3522
3523// Decode command with its arguments, and call the corresponding GL function.
3524// Note: args is a pointer to the command buffer. As such, it could be changed
3525// by a (malicious) client at any time, so if validation has to happen, it
3526// should operate on a copy of them.
[email protected]f7a64ee2010-02-01 22:24:143527error::Error GLES2DecoderImpl::DoCommand(
[email protected]96449d2c2009-11-25 00:01:323528 unsigned int command,
3529 unsigned int arg_count,
3530 const void* cmd_data) {
[email protected]f7a64ee2010-02-01 22:24:143531 error::Error result = error::kNoError;
[email protected]e844ae22012-01-14 03:36:263532 if (log_commands()) {
[email protected]39ba4f02012-03-26 01:16:003533 // TODO(notme): Change this to a LOG/VLOG that works in release. Tried
[email protected]65f7efe2013-11-28 03:11:473534 // VLOG(1), no luck.
[email protected]1d82e822013-04-10 21:32:323535 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]" << "cmd: "
[email protected]d2a0e1a2012-08-12 02:25:013536 << GetCommandName(command);
[email protected]b9849abf2009-11-25 19:13:193537 }
[email protected]96449d2c2009-11-25 00:01:323538 unsigned int command_index = command - kStartPoint - 1;
3539 if (command_index < arraysize(g_command_info)) {
3540 const CommandInfo& info = g_command_info[command_index];
3541 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3542 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3543 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
[email protected]cac16542014-01-15 17:53:513544 bool doing_gpu_trace = false;
3545 if (gpu_trace_commands_) {
3546 if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) {
3547 doing_gpu_trace = true;
3548 gpu_tracer_->Begin(GetCommandName(command), kTraceDecoder);
3549 }
3550 }
3551
[email protected]b9849abf2009-11-25 19:13:193552 uint32 immediate_data_size =
3553 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:323554 switch (command) {
3555 #define GLES2_CMD_OP(name) \
[email protected]ed9f9cd2013-02-27 21:12:353556 case cmds::name::kCmdId: \
[email protected]b9849abf2009-11-25 19:13:193557 result = Handle ## name( \
3558 immediate_data_size, \
[email protected]ed9f9cd2013-02-27 21:12:353559 *static_cast<const gles2::cmds::name*>(cmd_data)); \
[email protected]b9849abf2009-11-25 19:13:193560 break; \
[email protected]96449d2c2009-11-25 00:01:323561
3562 GLES2_COMMAND_LIST(GLES2_CMD_OP)
[email protected]96449d2c2009-11-25 00:01:323563 #undef GLES2_CMD_OP
[email protected]bf0985e2009-12-17 03:04:383564 }
[email protected]cac16542014-01-15 17:53:513565
3566 if (doing_gpu_trace)
3567 gpu_tracer_->End(kTraceDecoder);
3568
[email protected]bf0985e2009-12-17 03:04:383569 if (debug()) {
[email protected]07f54fcc2009-12-22 02:46:303570 GLenum error;
3571 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]1d82e822013-04-10 21:32:323572 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
[email protected]39ba4f02012-03-26 01:16:003573 << "GL ERROR: " << GLES2Util::GetStringEnum(error) << " : "
3574 << GetCommandName(command);
[email protected]ab09b612013-03-11 22:11:513575 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
[email protected]b9849abf2009-11-25 19:13:193576 }
[email protected]96449d2c2009-11-25 00:01:323577 }
3578 } else {
[email protected]f7a64ee2010-02-01 22:24:143579 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:323580 }
[email protected]b9849abf2009-11-25 19:13:193581 } else {
3582 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:323583 }
[email protected]a3a93e7b2010-08-28 00:48:563584 if (result == error::kNoError && current_decoder_error_ != error::kNoError) {
3585 result = current_decoder_error_;
3586 current_decoder_error_ = error::kNoError;
3587 }
[email protected]b9849abf2009-11-25 19:13:193588 return result;
[email protected]96449d2c2009-11-25 00:01:323589}
3590
[email protected]ed9f9cd2013-02-27 21:12:353591void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
3592 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:503593}
3594
[email protected]ae51d192010-04-27 00:48:033595bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353596 if (GetProgram(client_id)) {
[email protected]ae51d192010-04-27 00:48:033597 return false;
3598 }
[email protected]96449d2c2009-11-25 00:01:323599 GLuint service_id = glCreateProgram();
[email protected]ae51d192010-04-27 00:48:033600 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353601 CreateProgram(client_id, service_id);
[email protected]96449d2c2009-11-25 00:01:323602 }
[email protected]ae51d192010-04-27 00:48:033603 return true;
[email protected]96449d2c2009-11-25 00:01:323604}
3605
[email protected]ae51d192010-04-27 00:48:033606bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353607 if (GetShader(client_id)) {
[email protected]ae51d192010-04-27 00:48:033608 return false;
[email protected]96449d2c2009-11-25 00:01:323609 }
[email protected]ae51d192010-04-27 00:48:033610 GLuint service_id = glCreateShader(type);
3611 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353612 CreateShader(client_id, service_id, type);
[email protected]ae51d192010-04-27 00:48:033613 }
3614 return true;
[email protected]96449d2c2009-11-25 00:01:323615}
3616
[email protected]882ba1e22012-03-08 19:02:533617void GLES2DecoderImpl::DoFinish() {
3618 glFinish();
[email protected]5a36dc132013-07-23 23:17:553619 ProcessPendingReadPixels();
[email protected]22e3f552012-03-13 01:54:193620 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533621}
3622
3623void GLES2DecoderImpl::DoFlush() {
3624 glFlush();
[email protected]22e3f552012-03-13 01:54:193625 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533626}
3627
[email protected]3916c97e2010-02-25 03:20:503628void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:453629 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:023630 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:513631 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:533632 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:503633 return;
3634 }
[email protected]e259eb412012-10-13 05:47:243635 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:453636 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:503637}
3638
[email protected]051b1372010-04-12 02:42:083639void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:073640 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:083641 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033642 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:073643 buffer = GetBuffer(client_id);
3644 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:353645 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:223646 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
3647 "glBindBuffer",
3648 "id not generated by glGenBuffers");
[email protected]bf5a8d132011-08-16 08:39:353649 return;
3650 }
3651
[email protected]b10492f2013-03-08 05:24:073652 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:033653 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353654 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:073655 buffer = GetBuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573656 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103657 group_->GetIdAllocator(id_namespaces::kBuffers);
3658 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033659 }
[email protected]051b1372010-04-12 02:42:083660 }
[email protected]b10492f2013-03-08 05:24:073661 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
3662 if (buffer) {
3663 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:513664 LOCAL_SET_GL_ERROR(
3665 GL_INVALID_OPERATION,
3666 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:473667 return;
3668 }
[email protected]b10492f2013-03-08 05:24:073669 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:473670 }
[email protected]96449d2c2009-11-25 00:01:323671 switch (target) {
3672 case GL_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073673 state_.bound_array_buffer = buffer;
[email protected]96449d2c2009-11-25 00:01:323674 break;
3675 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073676 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
[email protected]96449d2c2009-11-25 00:01:323677 break;
3678 default:
[email protected]a93bb842010-02-16 23:03:473679 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:323680 break;
3681 }
[email protected]051b1372010-04-12 02:42:083682 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:323683}
3684
[email protected]f3b191b2013-06-19 03:43:543685bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha(
3686 bool all_draw_buffers) {
3687 Framebuffer* framebuffer =
3688 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
3689 if (!all_draw_buffers || !framebuffer) {
3690 return (GLES2Util::GetChannelsForFormat(
3691 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
3692 }
3693 return framebuffer->HasAlphaMRT();
[email protected]297ca1c2011-06-20 23:08:463694}
3695
3696bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353697 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453698 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203699 if (framebuffer) {
3700 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:463701 }
3702 if (offscreen_target_frame_buffer_.get()) {
3703 return offscreen_target_depth_format_ != 0;
3704 }
3705 return back_buffer_has_depth_;
3706}
3707
3708bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353709 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453710 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203711 if (framebuffer) {
3712 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:463713 }
3714 if (offscreen_target_frame_buffer_.get()) {
3715 return offscreen_target_stencil_format_ != 0 ||
3716 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3717 }
3718 return back_buffer_has_stencil_;
3719}
3720
3721void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]c986af502013-08-14 01:04:443722 if (framebuffer_state_.clear_state_dirty) {
[email protected]297ca1c2011-06-20 23:08:463723 glColorMask(
[email protected]e259eb412012-10-13 05:47:243724 state_.color_mask_red, state_.color_mask_green, state_.color_mask_blue,
3725 state_.color_mask_alpha &&
[email protected]f3b191b2013-06-19 03:43:543726 BoundFramebufferHasColorAttachmentWithAlpha(true));
[email protected]297ca1c2011-06-20 23:08:463727 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]e259eb412012-10-13 05:47:243728 glDepthMask(state_.depth_mask && have_depth);
[email protected]f731b9462012-10-30 00:35:223729 EnableDisable(GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
[email protected]297ca1c2011-06-20 23:08:463730 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]e259eb412012-10-13 05:47:243731 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423732 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]e259eb412012-10-13 05:47:243733 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423734 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]f731b9462012-10-30 00:35:223735 EnableDisable(
3736 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
3737 EnableDisable(GL_CULL_FACE, state_.enable_flags.cull_face);
3738 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
3739 EnableDisable(GL_BLEND, state_.enable_flags.blend);
[email protected]c986af502013-08-14 01:04:443740 framebuffer_state_.clear_state_dirty = false;
[email protected]297ca1c2011-06-20 23:08:463741 }
3742}
3743
[email protected]1868a342012-11-07 15:56:023744GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]7cd76fd2013-06-02 21:11:113745 return (offscreen_target_frame_buffer_.get())
3746 ? offscreen_target_frame_buffer_->id()
3747 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0);
[email protected]1868a342012-11-07 15:56:023748}
3749
[email protected]5baa86bc2014-01-16 04:33:163750void GLES2DecoderImpl::RestoreState(const ContextState* prev_state) const {
[email protected]962bfbe72013-05-24 11:16:143751 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
3752 "context", logger_.GetLogPrefix());
[email protected]29a4d902013-02-26 20:18:063753 // Restore the Framebuffer first because of bugs in Intel drivers.
3754 // Intel drivers incorrectly clip the viewport settings to
3755 // the size of the current framebuffer object.
3756 RestoreFramebufferBindings();
[email protected]5baa86bc2014-01-16 04:33:163757 state_.RestoreState(prev_state);
[email protected]29a4d902013-02-26 20:18:063758}
3759
3760void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]9d3b2e12013-10-02 01:04:343761 GLuint service_id =
3762 framebuffer_state_.bound_draw_framebuffer.get()
3763 ? framebuffer_state_.bound_draw_framebuffer->service_id()
3764 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:063765 if (!features().chromium_framebuffer_multisample) {
3766 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
3767 } else {
3768 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
[email protected]9d3b2e12013-10-02 01:04:343769 service_id = framebuffer_state_.bound_read_framebuffer.get()
3770 ? framebuffer_state_.bound_read_framebuffer->service_id()
[email protected]7cd76fd2013-06-02 21:11:113771 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:063772 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
3773 }
[email protected]70d34263c2013-01-09 00:27:453774 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:063775}
3776
3777void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
[email protected]62e65f02013-05-29 22:28:103778 Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
3779 if (texture) {
[email protected]9bc9a2e82013-04-03 03:56:253780 GLenum target = texture->target();
3781 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:063782 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253783 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:063784 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253785 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:063786 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253787 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:063788 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253789 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:063790 RestoreTextureUnitBindings(state_.active_texture_unit);
3791 }
[email protected]70d34263c2013-01-09 00:27:453792}
3793
[email protected]cd2ef752014-02-12 23:16:033794void GLES2DecoderImpl::ClearAllAttributes() const {
3795 for (uint32 i = 0; i < group_->max_vertex_attribs(); ++i) {
3796 if (i != 0) // Never disable attribute 0
3797 glDisableVertexAttribArray(i);
3798 if(features().angle_instanced_arrays)
3799 glVertexAttribDivisorANGLE(i, 0);
3800 }
3801}
3802
3803void GLES2DecoderImpl::RestoreAllAttributes() const {
3804 for (uint32 i = 0; i < group_->max_vertex_attribs(); ++i)
3805 RestoreAttribute(i);
3806}
3807
[email protected]70d34263c2013-01-09 00:27:453808void GLES2DecoderImpl::OnFboChanged() const {
3809 if (workarounds().restore_scissor_on_fbo_change)
[email protected]28718a92013-04-04 12:12:513810 state_.fbo_binding_for_scissor_workaround_dirty_ = true;
3811}
3812
3813// Called after the FBO is checked for completeness.
3814void GLES2DecoderImpl::OnUseFramebuffer() const {
3815 if (state_.fbo_binding_for_scissor_workaround_dirty_) {
3816 state_.fbo_binding_for_scissor_workaround_dirty_ = false;
[email protected]81fc9d02013-03-14 23:53:323817 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:513818 glScissor(state_.scissor_x,
3819 state_.scissor_y,
3820 state_.scissor_width,
3821 state_.scissor_height);
3822
3823 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
3824 // it's unclear how this bug works.
3825 glFlush();
3826 }
[email protected]b177ae22011-11-01 03:29:113827}
3828
[email protected]051b1372010-04-12 02:42:083829void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:063830 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:083831 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033832 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:063833 framebuffer = GetFramebuffer(client_id);
3834 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:353835 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:223836 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
3837 "glBindFramebuffer",
3838 "id not generated by glGenFramebuffers");
3839 return;
[email protected]bf5a8d132011-08-16 08:39:353840 }
3841
[email protected]4d8f0dd2013-03-09 14:37:063842 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:033843 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353844 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:063845 framebuffer = GetFramebuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573846 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103847 group_->GetIdAllocator(id_namespaces::kFramebuffers);
3848 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033849 } else {
[email protected]4d8f0dd2013-03-09 14:37:063850 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:083851 }
[email protected]4d8f0dd2013-03-09 14:37:063852 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083853 }
[email protected]4d8f0dd2013-03-09 14:37:063854 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:303855
3856 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:343857 framebuffer_state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:303858 }
[email protected]cac16542014-01-15 17:53:513859
3860 // vmiura: This looks like dup code
[email protected]8e3e0662010-08-23 18:46:303861 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:343862 framebuffer_state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:303863 }
[email protected]6217d392010-03-25 22:08:353864
[email protected]c986af502013-08-14 01:04:443865 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463866
[email protected]b177ae22011-11-01 03:29:113867 // If we are rendering to the backbuffer get the FBO id for any simulated
3868 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:063869 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:113870 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:463871 }
[email protected]6217d392010-03-25 22:08:353872
[email protected]051b1372010-04-12 02:42:083873 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:453874 OnFboChanged();
[email protected]86093972010-03-11 00:13:563875}
3876
[email protected]051b1372010-04-12 02:42:083877void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:273878 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:083879 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033880 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:273881 renderbuffer = GetRenderbuffer(client_id);
3882 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:353883 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:223884 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
3885 "glBindRenderbuffer",
3886 "id not generated by glGenRenderbuffers");
[email protected]bf5a8d132011-08-16 08:39:353887 return;
3888 }
3889
[email protected]ee2a79c32013-03-10 03:50:273890 // It's a new id so make a renderbuffer renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:033891 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353892 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:273893 renderbuffer = GetRenderbuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573894 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103895 group_->GetIdAllocator(id_namespaces::kRenderbuffers);
3896 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033897 } else {
[email protected]ee2a79c32013-03-10 03:50:273898 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:083899 }
[email protected]ee2a79c32013-03-10 03:50:273900 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083901 }
[email protected]caa13ed2014-02-17 11:29:203902 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenderbuffer");
[email protected]ee2a79c32013-03-10 03:50:273903 state_.bound_renderbuffer = renderbuffer;
[email protected]051b1372010-04-12 02:42:083904 glBindRenderbufferEXT(target, service_id);
[email protected]86093972010-03-11 00:13:563905}
3906
[email protected]051b1372010-04-12 02:42:083907void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:493908 TextureRef* texture_ref = NULL;
[email protected]051b1372010-04-12 02:42:083909 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033910 if (client_id != 0) {
[email protected]370eaf12013-05-18 09:19:493911 texture_ref = GetTexture(client_id);
3912 if (!texture_ref) {
[email protected]bf5a8d132011-08-16 08:39:353913 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:223914 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
3915 "glBindTexture",
3916 "id not generated by glGenTextures");
3917 return;
[email protected]bf5a8d132011-08-16 08:39:353918 }
3919
[email protected]02965c22013-03-09 02:40:073920 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:033921 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:413922 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:353923 CreateTexture(client_id, service_id);
[email protected]370eaf12013-05-18 09:19:493924 texture_ref = GetTexture(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::kTextures);
3927 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033928 }
3929 } else {
[email protected]370eaf12013-05-18 09:19:493930 texture_ref = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:083931 }
[email protected]370eaf12013-05-18 09:19:493932 Texture* texture = texture_ref->texture();
[email protected]ae51d192010-04-27 00:48:033933
[email protected]1958e0e2010-04-22 05:17:153934 // Check the texture exists
3935 // Check that we are not trying to bind it to a different target.
[email protected]02965c22013-03-09 02:40:073936 if (texture->target() != 0 && texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:513937 LOCAL_SET_GL_ERROR(
3938 GL_INVALID_OPERATION,
3939 "glBindTexture", "texture bound to more than 1 target.");
[email protected]1958e0e2010-04-22 05:17:153940 return;
3941 }
[email protected]02965c22013-03-09 02:40:073942 LogClientServiceForInfo(texture, client_id, "glBindTexture");
3943 if (texture->target() == 0) {
[email protected]370eaf12013-05-18 09:19:493944 texture_manager()->SetTarget(texture_ref, target);
[email protected]a93bb842010-02-16 23:03:473945 }
[email protected]02965c22013-03-09 02:40:073946 glBindTexture(target, texture->service_id());
[email protected]32145a92012-12-17 09:01:593947
[email protected]e259eb412012-10-13 05:47:243948 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:503949 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:473950 switch (target) {
3951 case GL_TEXTURE_2D:
[email protected]370eaf12013-05-18 09:19:493952 unit.bound_texture_2d = texture_ref;
[email protected]a93bb842010-02-16 23:03:473953 break;
3954 case GL_TEXTURE_CUBE_MAP:
[email protected]370eaf12013-05-18 09:19:493955 unit.bound_texture_cube_map = texture_ref;
[email protected]a93bb842010-02-16 23:03:473956 break;
[email protected]61eeb33f2011-07-26 15:30:313957 case GL_TEXTURE_EXTERNAL_OES:
[email protected]370eaf12013-05-18 09:19:493958 unit.bound_texture_external_oes = texture_ref;
[email protected]61eeb33f2011-07-26 15:30:313959 break;
[email protected]e51bdf32011-11-23 22:21:463960 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]370eaf12013-05-18 09:19:493961 unit.bound_texture_rectangle_arb = texture_ref;
[email protected]e51bdf32011-11-23 22:21:463962 break;
[email protected]a93bb842010-02-16 23:03:473963 default:
3964 NOTREACHED(); // Validation should prevent us getting here.
3965 break;
3966 }
3967}
3968
[email protected]07f54fcc2009-12-22 02:46:303969void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:243970 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:123971 if (index != 0 ||
3972 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:243973 glDisableVertexAttribArray(index);
3974 }
[email protected]07f54fcc2009-12-22 02:46:303975 } else {
[email protected]ab09b612013-03-11 22:11:513976 LOCAL_SET_GL_ERROR(
3977 GL_INVALID_VALUE,
3978 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:303979 }
3980}
3981
[email protected]60f22d32012-12-12 00:31:583982void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
3983 GLsizei numAttachments,
3984 const GLenum* attachments) {
[email protected]680aa412013-10-31 18:08:013985 if (!features().ext_discard_framebuffer) {
3986 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
3987 "glDiscardFramebufferEXT",
3988 "function not available");
3989 return;
3990 }
3991
[email protected]ed9f9cd2013-02-27 21:12:353992 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:583993 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
3994
3995 // Validates the attachments. If one of them fails
3996 // the whole command fails.
3997 for (GLsizei i = 0; i < numAttachments; ++i) {
3998 if ((framebuffer &&
3999 !validators_->attachment.IsValid(attachments[i])) ||
4000 (!framebuffer &&
4001 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:514002 LOCAL_SET_GL_ERROR_INVALID_ENUM(
4003 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:584004 return;
4005 }
4006 }
4007
4008 // Marks each one of them as not cleared
4009 for (GLsizei i = 0; i < numAttachments; ++i) {
4010 if (framebuffer) {
4011 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
4012 texture_manager(),
4013 attachments[i],
4014 false);
4015 } else {
4016 switch (attachments[i]) {
4017 case GL_COLOR_EXT:
4018 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
4019 break;
4020 case GL_DEPTH_EXT:
4021 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
4022 case GL_STENCIL_EXT:
4023 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
4024 break;
4025 default:
4026 NOTREACHED();
4027 break;
4028 }
4029 }
4030 }
4031
[email protected]d49c5402013-09-11 15:39:024032 // If the default framebuffer is bound but we are still rendering to an
4033 // FBO, translate attachment names that refer to default framebuffer
4034 // channels to corresponding framebuffer attachments.
4035 scoped_ptr<GLenum[]> translated_attachments(new GLenum[numAttachments]);
4036 for (GLsizei i = 0; i < numAttachments; ++i) {
4037 GLenum attachment = attachments[i];
4038 if (!framebuffer && GetBackbufferServiceId()) {
4039 switch (attachment) {
4040 case GL_COLOR_EXT:
4041 attachment = GL_COLOR_ATTACHMENT0;
4042 break;
4043 case GL_DEPTH_EXT:
4044 attachment = GL_DEPTH_ATTACHMENT;
4045 break;
4046 case GL_STENCIL_EXT:
4047 attachment = GL_STENCIL_ATTACHMENT;
4048 break;
4049 default:
4050 NOTREACHED();
4051 return;
4052 }
4053 }
4054 translated_attachments[i] = attachment;
4055 }
4056
4057 glDiscardFramebufferEXT(target, numAttachments, translated_attachments.get());
[email protected]60f22d32012-12-12 00:31:584058}
4059
[email protected]07f54fcc2009-12-22 02:46:304060void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244061 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:304062 glEnableVertexAttribArray(index);
4063 } else {
[email protected]ab09b612013-03-11 22:11:514064 LOCAL_SET_GL_ERROR(
4065 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304066 }
4067}
4068
[email protected]a93bb842010-02-16 23:03:474069void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]c986af502013-08-14 01:04:444070 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
4071 &state_, target);
[email protected]370eaf12013-05-18 09:19:494072 if (!texture_ref ||
4073 !texture_manager()->CanGenerateMipmaps(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:514074 LOCAL_SET_GL_ERROR(
4075 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:474076 return;
4077 }
[email protected]38c0a972012-05-12 00:48:024078
[email protected]12d95352012-12-14 07:23:544079 if (target == GL_TEXTURE_CUBE_MAP) {
4080 for (int i = 0; i < 6; ++i) {
4081 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]370eaf12013-05-18 09:19:494082 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
[email protected]ab09b612013-03-11 22:11:514083 LOCAL_SET_GL_ERROR(
4084 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544085 return;
4086 }
4087 }
4088 } else {
[email protected]370eaf12013-05-18 09:19:494089 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
[email protected]ab09b612013-03-11 22:11:514090 LOCAL_SET_GL_ERROR(
4091 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544092 return;
4093 }
[email protected]7687479c2012-05-14 23:54:044094 }
4095
[email protected]ab09b612013-03-11 22:11:514096 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:194097 // Workaround for Mac driver bug. In the large scheme of things setting
4098 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:564099 // hit so there's probably no need to make this conditional. The bug appears
4100 // to be that if the filtering mode is set to something that doesn't require
4101 // mipmaps for rendering, or is never set to something other than the default,
4102 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:154103 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:194104 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4105 }
[email protected]a93bb842010-02-16 23:03:474106 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:154107 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]370eaf12013-05-18 09:19:494108 glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
4109 texture_ref->texture()->min_filter());
[email protected]c892a4e12012-05-08 18:20:194110 }
[email protected]ab09b612013-03-11 22:11:514111 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:024112 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:494113 texture_manager()->MarkMipmapsGenerated(texture_ref);
[email protected]38c0a972012-05-12 00:48:024114 }
[email protected]a93bb842010-02-16 23:03:474115}
4116
[email protected]b273e432010-04-12 17:23:584117bool GLES2DecoderImpl::GetHelper(
4118 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:584119 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:154120 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4121 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434122 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4123 *num_written = 1;
4124 if (params) {
[email protected]68586372013-12-11 01:27:594125 *params = GLES2Util::GetPreferredGLReadPixelsFormat(
4126 GetBoundReadFrameBufferInternalFormat());
[email protected]ad84a3a2012-06-08 21:42:434127 }
4128 return true;
4129 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4130 *num_written = 1;
4131 if (params) {
[email protected]68586372013-12-11 01:27:594132 *params = GLES2Util::GetPreferredGLReadPixelsType(
4133 GetBoundReadFrameBufferInternalFormat(),
4134 GetBoundReadFrameBufferTextureType());
[email protected]ad84a3a2012-06-08 21:42:434135 }
4136 return true;
4137 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4138 *num_written = 1;
4139 if (params) {
4140 *params = group_->max_fragment_uniform_vectors();
4141 }
4142 return true;
4143 case GL_MAX_VARYING_VECTORS:
4144 *num_written = 1;
4145 if (params) {
4146 *params = group_->max_varying_vectors();
4147 }
4148 return true;
4149 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4150 *num_written = 1;
4151 if (params) {
4152 *params = group_->max_vertex_uniform_vectors();
4153 }
4154 return true;
[email protected]4e8a5b122010-05-08 22:00:104155 }
[email protected]5cb735d2011-10-13 01:37:234156 }
4157 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:244158 case GL_MAX_VIEWPORT_DIMS:
4159 if (offscreen_target_frame_buffer_.get()) {
4160 *num_written = 2;
4161 if (params) {
4162 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4163 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4164 }
4165 return true;
4166 }
[email protected]5cb735d2011-10-13 01:37:234167 return false;
[email protected]84afefa2011-10-19 21:45:534168 case GL_MAX_SAMPLES:
4169 *num_written = 1;
4170 if (params) {
4171 params[0] = renderbuffer_manager()->max_samples();
4172 }
4173 return true;
4174 case GL_MAX_RENDERBUFFER_SIZE:
4175 *num_written = 1;
4176 if (params) {
4177 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4178 }
4179 return true;
[email protected]5cb735d2011-10-13 01:37:234180 case GL_MAX_TEXTURE_SIZE:
4181 *num_written = 1;
4182 if (params) {
4183 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4184 }
4185 return true;
4186 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4187 *num_written = 1;
4188 if (params) {
4189 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4190 }
4191 return true;
[email protected]2f143d482013-03-14 18:04:494192 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4193 *num_written = 1;
4194 if (params) {
4195 params[0] = group_->max_color_attachments();
4196 }
4197 return true;
4198 case GL_MAX_DRAW_BUFFERS_ARB:
4199 *num_written = 1;
4200 if (params) {
4201 params[0] = group_->max_draw_buffers();
4202 }
4203 return true;
[email protected]297ca1c2011-06-20 23:08:464204 case GL_ALPHA_BITS:
4205 *num_written = 1;
4206 if (params) {
4207 GLint v = 0;
4208 glGetIntegerv(GL_ALPHA_BITS, &v);
[email protected]f3b191b2013-06-19 03:43:544209 params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
[email protected]297ca1c2011-06-20 23:08:464210 }
4211 return true;
4212 case GL_DEPTH_BITS:
4213 *num_written = 1;
4214 if (params) {
4215 GLint v = 0;
4216 glGetIntegerv(GL_DEPTH_BITS, &v);
4217 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4218 }
4219 return true;
4220 case GL_STENCIL_BITS:
4221 *num_written = 1;
4222 if (params) {
4223 GLint v = 0;
4224 glGetIntegerv(GL_STENCIL_BITS, &v);
4225 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4226 }
4227 return true;
[email protected]656dcaad2010-05-07 17:18:374228 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114229 *num_written = validators_->compressed_texture_format.GetValues().size();
4230 if (params) {
4231 for (GLint ii = 0; ii < *num_written; ++ii) {
4232 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4233 }
4234 }
[email protected]656dcaad2010-05-07 17:18:374235 return true;
[email protected]b273e432010-04-12 17:23:584236 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4237 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104238 if (params) {
[email protected]302ce6d2011-07-07 23:28:114239 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104240 }
[email protected]b273e432010-04-12 17:23:584241 return true;
4242 case GL_NUM_SHADER_BINARY_FORMATS:
4243 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104244 if (params) {
[email protected]302ce6d2011-07-07 23:28:114245 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104246 }
[email protected]b273e432010-04-12 17:23:584247 return true;
4248 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114249 *num_written = validators_->shader_binary_format.GetValues().size();
4250 if (params) {
4251 for (GLint ii = 0; ii < *num_written; ++ii) {
4252 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4253 }
4254 }
4255 return true;
[email protected]b273e432010-04-12 17:23:584256 case GL_SHADER_COMPILER:
4257 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104258 if (params) {
4259 *params = GL_TRUE;
4260 }
[email protected]b273e432010-04-12 17:23:584261 return true;
[email protected]6b8cf1a2010-05-06 16:13:584262 case GL_ARRAY_BUFFER_BINDING:
4263 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104264 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114265 if (state_.bound_array_buffer.get()) {
[email protected]4e8a5b122010-05-08 22:00:104266 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:244267 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:104268 &client_id);
4269 *params = client_id;
4270 } else {
4271 *params = 0;
4272 }
[email protected]6b8cf1a2010-05-06 16:13:584273 }
4274 return true;
4275 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4276 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104277 if (params) {
[email protected]e259eb412012-10-13 05:47:244278 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:104279 GLuint client_id = 0;
4280 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:254281 state_.vertex_attrib_manager->element_array_buffer()->
4282 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104283 *params = client_id;
4284 } else {
4285 *params = 0;
4286 }
[email protected]6b8cf1a2010-05-06 16:13:584287 }
4288 return true;
4289 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304290 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584291 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104292 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354293 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454294 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204295 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104296 GLuint client_id = 0;
4297 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204298 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304299 *params = client_id;
4300 } else {
4301 *params = 0;
4302 }
4303 }
4304 return true;
[email protected]ebfb73c2012-08-15 02:37:454305 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304306 *num_written = 1;
4307 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354308 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454309 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204310 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304311 GLuint client_id = 0;
4312 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204313 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104314 *params = client_id;
4315 } else {
4316 *params = 0;
4317 }
[email protected]6b8cf1a2010-05-06 16:13:584318 }
4319 return true;
4320 case GL_RENDERBUFFER_BINDING:
4321 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104322 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354323 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204324 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4325 if (renderbuffer) {
[email protected]62e65f02013-05-29 22:28:104326 *params = renderbuffer->client_id();
[email protected]4e8a5b122010-05-08 22:00:104327 } else {
4328 *params = 0;
4329 }
[email protected]6b8cf1a2010-05-06 16:13:584330 }
4331 return true;
4332 case GL_CURRENT_PROGRAM:
4333 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104334 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114335 if (state_.current_program.get()) {
[email protected]4e8a5b122010-05-08 22:00:104336 GLuint client_id = 0;
4337 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244338 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104339 *params = client_id;
4340 } else {
4341 *params = 0;
4342 }
[email protected]6b8cf1a2010-05-06 16:13:584343 }
4344 return true;
[email protected]bf835842012-11-19 15:21:514345 case GL_VERTEX_ARRAY_BINDING_OES:
4346 *num_written = 1;
4347 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114348 if (state_.vertex_attrib_manager.get() !=
4349 default_vertex_attrib_manager_.get()) {
[email protected]bf835842012-11-19 15:21:514350 GLuint client_id = 0;
4351 vertex_array_manager_->GetClientId(
4352 state_.vertex_attrib_manager->service_id(), &client_id);
4353 *params = client_id;
4354 } else {
4355 *params = 0;
4356 }
4357 }
4358 return true;
[email protected]4e8a5b122010-05-08 22:00:104359 case GL_TEXTURE_BINDING_2D:
4360 *num_written = 1;
4361 if (params) {
[email protected]e259eb412012-10-13 05:47:244362 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114363 if (unit.bound_texture_2d.get()) {
[email protected]62e65f02013-05-29 22:28:104364 *params = unit.bound_texture_2d->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584365 } else {
4366 *params = 0;
4367 }
[email protected]6b8cf1a2010-05-06 16:13:584368 }
[email protected]4e8a5b122010-05-08 22:00:104369 return true;
4370 case GL_TEXTURE_BINDING_CUBE_MAP:
4371 *num_written = 1;
4372 if (params) {
[email protected]e259eb412012-10-13 05:47:244373 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114374 if (unit.bound_texture_cube_map.get()) {
[email protected]62e65f02013-05-29 22:28:104375 *params = unit.bound_texture_cube_map->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584376 } else {
4377 *params = 0;
4378 }
[email protected]6b8cf1a2010-05-06 16:13:584379 }
[email protected]4e8a5b122010-05-08 22:00:104380 return true;
[email protected]61eeb33f2011-07-26 15:30:314381 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4382 *num_written = 1;
4383 if (params) {
[email protected]e259eb412012-10-13 05:47:244384 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114385 if (unit.bound_texture_external_oes.get()) {
[email protected]62e65f02013-05-29 22:28:104386 *params = unit.bound_texture_external_oes->client_id();
[email protected]61eeb33f2011-07-26 15:30:314387 } else {
4388 *params = 0;
4389 }
4390 }
4391 return true;
[email protected]e51bdf32011-11-23 22:21:464392 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4393 *num_written = 1;
4394 if (params) {
[email protected]e259eb412012-10-13 05:47:244395 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114396 if (unit.bound_texture_rectangle_arb.get()) {
[email protected]62e65f02013-05-29 22:28:104397 *params = unit.bound_texture_rectangle_arb->client_id();
[email protected]e51bdf32011-11-23 22:21:464398 } else {
4399 *params = 0;
4400 }
4401 }
4402 return true;
[email protected]6c75c712012-06-19 15:43:174403 case GL_UNPACK_FLIP_Y_CHROMIUM:
4404 *num_written = 1;
4405 if (params) {
4406 params[0] = unpack_flip_y_;
4407 }
4408 return true;
4409 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4410 *num_written = 1;
4411 if (params) {
4412 params[0] = unpack_premultiply_alpha_;
4413 }
4414 return true;
4415 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4416 *num_written = 1;
4417 if (params) {
4418 params[0] = unpack_unpremultiply_alpha_;
4419 }
4420 return true;
[email protected]b273e432010-04-12 17:23:584421 default:
[email protected]2f143d482013-03-14 18:04:494422 if (pname >= GL_DRAW_BUFFER0_ARB &&
4423 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
4424 *num_written = 1;
4425 if (params) {
4426 Framebuffer* framebuffer =
4427 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4428 if (framebuffer) {
4429 params[0] = framebuffer->GetDrawBuffer(pname);
4430 } else { // backbuffer
4431 if (pname == GL_DRAW_BUFFER0_ARB)
4432 params[0] = group_->draw_buffer();
4433 else
4434 params[0] = GL_NONE;
4435 }
4436 }
4437 return true;
4438 }
[email protected]4e8a5b122010-05-08 22:00:104439 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534440 return false;
[email protected]b273e432010-04-12 17:23:584441 }
4442}
4443
[email protected]4e8a5b122010-05-08 22:00:104444bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4445 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264446 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534447 return true;
4448 }
[email protected]4e8a5b122010-05-08 22:00:104449 return GetHelper(pname, NULL, num_values);
4450}
4451
[email protected]7d3c36e2013-07-12 14:13:164452GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) {
4453 if (GL_MAX_SAMPLES == pname &&
4454 features().use_img_for_multisampled_render_to_texture) {
4455 return GL_MAX_SAMPLES_IMG;
4456 }
4457 return pname;
4458}
4459
[email protected]b273e432010-04-12 17:23:584460void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4461 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104462 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534463 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554464 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:264465 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:534466 GetHelper(pname, values.get(), &num_written);
4467 }
[email protected]b273e432010-04-12 17:23:584468 for (GLsizei ii = 0; ii < num_written; ++ii) {
4469 params[ii] = static_cast<GLboolean>(values[ii]);
4470 }
4471 } else {
[email protected]7d3c36e2013-07-12 14:13:164472 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584473 glGetBooleanv(pname, params);
4474 }
4475}
4476
4477void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4478 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104479 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:264480 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:534481 if (GetHelper(pname, NULL, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554482 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]f63b1232012-10-31 07:03:534483 GetHelper(pname, values.get(), &num_written);
4484 for (GLsizei ii = 0; ii < num_written; ++ii) {
4485 params[ii] = static_cast<GLfloat>(values[ii]);
4486 }
4487 } else {
[email protected]7d3c36e2013-07-12 14:13:164488 pname = AdjustGetPname(pname);
[email protected]f63b1232012-10-31 07:03:534489 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:584490 }
[email protected]b273e432010-04-12 17:23:584491 }
4492}
4493
4494void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4495 DCHECK(params);
4496 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:264497 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:534498 !GetHelper(pname, params, &num_written)) {
[email protected]7d3c36e2013-07-12 14:13:164499 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584500 glGetIntegerv(pname, params);
4501 }
4502}
4503
[email protected]a0c3e972010-04-21 00:49:134504void GLES2DecoderImpl::DoGetProgramiv(
4505 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:424506 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
4507 if (!program) {
[email protected]a0c3e972010-04-21 00:49:134508 return;
4509 }
[email protected]df37b9932013-03-08 05:21:424510 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:134511}
4512
[email protected]17cfbe0e2013-03-07 01:26:084513void GLES2DecoderImpl::DoGetBufferParameteriv(
4514 GLenum target, GLenum pname, GLint* params) {
[email protected]0fbba3732013-07-17 15:40:134515 // Just delegate it. Some validation is actually done before this.
4516 buffer_manager()->ValidateAndDoGetBufferParameteriv(
4517 &state_, target, pname, params);
[email protected]17cfbe0e2013-03-07 01:26:084518}
4519
[email protected]258a3313f2011-10-18 20:13:574520void GLES2DecoderImpl::DoBindAttribLocation(
[email protected]df37b9932013-03-08 05:21:424521 GLuint program_id, GLuint index, const char* name) {
[email protected]258a3313f2011-10-18 20:13:574522 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514523 LOCAL_SET_GL_ERROR(
4524 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:574525 return;
4526 }
[email protected]68dcb1f2012-04-07 00:14:564527 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514528 LOCAL_SET_GL_ERROR(
4529 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:564530 return;
4531 }
4532 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:514533 LOCAL_SET_GL_ERROR(
4534 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:564535 return;
4536 }
[email protected]df37b9932013-03-08 05:21:424537 Program* program = GetProgramInfoNotShader(
4538 program_id, "glBindAttribLocation");
4539 if (!program) {
[email protected]258a3313f2011-10-18 20:13:574540 return;
[email protected]558847a2010-03-24 07:02:544541 }
[email protected]df37b9932013-03-08 05:21:424542 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
4543 glBindAttribLocation(program->service_id(), index, name);
[email protected]258a3313f2011-10-18 20:13:574544}
4545
4546error::Error GLES2DecoderImpl::HandleBindAttribLocation(
[email protected]ed9f9cd2013-02-27 21:12:354547 uint32 immediate_data_size, const cmds::BindAttribLocation& c) {
[email protected]258a3313f2011-10-18 20:13:574548 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544549 GLuint index = static_cast<GLuint>(c.index);
4550 uint32 name_size = c.data_size;
4551 const char* name = GetSharedMemoryAs<const char*>(
4552 c.name_shm_id, c.name_shm_offset, name_size);
4553 if (name == NULL) {
4554 return error::kOutOfBounds;
4555 }
4556 String name_str(name, name_size);
[email protected]258a3313f2011-10-18 20:13:574557 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544558 return error::kNoError;
4559}
4560
[email protected]558847a2010-03-24 07:02:544561error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:354562 uint32 immediate_data_size, const cmds::BindAttribLocationBucket& c) {
[email protected]6b8cf1a2010-05-06 16:13:584563 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544564 GLuint index = static_cast<GLuint>(c.index);
4565 Bucket* bucket = GetBucket(c.name_bucket_id);
4566 if (!bucket || bucket->size() == 0) {
4567 return error::kInvalidArguments;
4568 }
4569 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:184570 if (!bucket->GetAsString(&name_str)) {
4571 return error::kInvalidArguments;
4572 }
[email protected]258a3313f2011-10-18 20:13:574573 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544574 return error::kNoError;
4575}
4576
[email protected]2be6abf32012-06-26 00:28:334577void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:424578 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:334579 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514580 LOCAL_SET_GL_ERROR(
4581 GL_INVALID_VALUE,
4582 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:334583 return;
4584 }
4585 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514586 LOCAL_SET_GL_ERROR(
4587 GL_INVALID_OPERATION,
4588 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:334589 return;
4590 }
4591 if (location < 0 || static_cast<uint32>(location) >=
4592 (group_->max_fragment_uniform_vectors() +
4593 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:514594 LOCAL_SET_GL_ERROR(
4595 GL_INVALID_VALUE,
4596 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334597 return;
4598 }
[email protected]df37b9932013-03-08 05:21:424599 Program* program = GetProgramInfoNotShader(
4600 program_id, "glBindUniformLocationCHROMIUM");
4601 if (!program) {
[email protected]2be6abf32012-06-26 00:28:334602 return;
4603 }
[email protected]df37b9932013-03-08 05:21:424604 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:514605 LOCAL_SET_GL_ERROR(
4606 GL_INVALID_VALUE,
4607 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334608 }
4609}
4610
4611error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354612 uint32 immediate_data_size, const cmds::BindUniformLocationCHROMIUM& c) {
[email protected]2be6abf32012-06-26 00:28:334613 GLuint program = static_cast<GLuint>(c.program);
4614 GLint location = static_cast<GLint>(c.location);
4615 uint32 name_size = c.data_size;
4616 const char* name = GetSharedMemoryAs<const char*>(
4617 c.name_shm_id, c.name_shm_offset, name_size);
4618 if (name == NULL) {
4619 return error::kOutOfBounds;
4620 }
4621 String name_str(name, name_size);
4622 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4623 return error::kNoError;
4624}
4625
[email protected]2be6abf32012-06-26 00:28:334626error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
4627 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:354628 const cmds::BindUniformLocationCHROMIUMBucket& c) {
[email protected]2be6abf32012-06-26 00:28:334629 GLuint program = static_cast<GLuint>(c.program);
4630 GLint location = static_cast<GLint>(c.location);
4631 Bucket* bucket = GetBucket(c.name_bucket_id);
4632 if (!bucket || bucket->size() == 0) {
4633 return error::kInvalidArguments;
4634 }
4635 std::string name_str;
4636 if (!bucket->GetAsString(&name_str)) {
4637 return error::kInvalidArguments;
4638 }
4639 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4640 return error::kNoError;
4641}
4642
[email protected]f7a64ee2010-02-01 22:24:144643error::Error GLES2DecoderImpl::HandleDeleteShader(
[email protected]ed9f9cd2013-02-27 21:12:354644 uint32 immediate_data_size, const cmds::DeleteShader& c) {
[email protected]ae51d192010-04-27 00:48:034645 GLuint client_id = c.shader;
4646 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424647 Shader* shader = GetShader(client_id);
4648 if (shader) {
4649 if (!shader->IsDeleted()) {
4650 glDeleteShader(shader->service_id());
4651 shader_manager()->MarkAsDeleted(shader);
[email protected]ca488e12010-12-13 20:06:144652 }
[email protected]ae51d192010-04-27 00:48:034653 } else {
[email protected]ab09b612013-03-11 22:11:514654 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:034655 }
[email protected]96449d2c2009-11-25 00:01:324656 }
[email protected]f7a64ee2010-02-01 22:24:144657 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324658}
4659
[email protected]f7a64ee2010-02-01 22:24:144660error::Error GLES2DecoderImpl::HandleDeleteProgram(
[email protected]ed9f9cd2013-02-27 21:12:354661 uint32 immediate_data_size, const cmds::DeleteProgram& c) {
[email protected]ae51d192010-04-27 00:48:034662 GLuint client_id = c.program;
4663 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424664 Program* program = GetProgram(client_id);
4665 if (program) {
4666 if (!program->IsDeleted()) {
4667 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:144668 }
[email protected]ae51d192010-04-27 00:48:034669 } else {
[email protected]ab09b612013-03-11 22:11:514670 LOCAL_SET_GL_ERROR(
4671 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:034672 }
[email protected]96449d2c2009-11-25 00:01:324673 }
[email protected]f7a64ee2010-02-01 22:24:144674 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324675}
4676
[email protected]269200b12010-11-18 22:53:064677void GLES2DecoderImpl::DoDeleteSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104678 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574679 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104680 for (GLsizei ii = 0; ii < n; ++ii) {
4681 id_allocator->FreeID(ids[ii]);
4682 }
4683}
4684
[email protected]269200b12010-11-18 22:53:064685error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354686 uint32 immediate_data_size, const cmds::DeleteSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104687 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4688 GLsizei n = static_cast<GLsizei>(c.n);
4689 uint32 data_size;
4690 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4691 return error::kOutOfBounds;
4692 }
4693 const GLuint* ids = GetSharedMemoryAs<const GLuint*>(
4694 c.ids_shm_id, c.ids_shm_offset, data_size);
4695 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514696 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "DeleteSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104697 return error::kNoError;
4698 }
4699 if (ids == NULL) {
4700 return error::kOutOfBounds;
4701 }
[email protected]269200b12010-11-18 22:53:064702 DoDeleteSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104703 return error::kNoError;
4704}
4705
[email protected]269200b12010-11-18 22:53:064706void GLES2DecoderImpl::DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104707 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574708 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104709 if (id_offset == 0) {
4710 for (GLsizei ii = 0; ii < n; ++ii) {
4711 ids[ii] = id_allocator->AllocateID();
4712 }
4713 } else {
4714 for (GLsizei ii = 0; ii < n; ++ii) {
4715 ids[ii] = id_allocator->AllocateIDAtOrAbove(id_offset);
4716 id_offset = ids[ii] + 1;
4717 }
4718 }
4719}
4720
[email protected]269200b12010-11-18 22:53:064721error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354722 uint32 immediate_data_size, const cmds::GenSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104723 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4724 GLuint id_offset = static_cast<GLuint>(c.id_offset);
4725 GLsizei n = static_cast<GLsizei>(c.n);
4726 uint32 data_size;
4727 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4728 return error::kOutOfBounds;
4729 }
4730 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4731 c.ids_shm_id, c.ids_shm_offset, data_size);
4732 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514733 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "GenSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104734 return error::kNoError;
4735 }
4736 if (ids == NULL) {
4737 return error::kOutOfBounds;
4738 }
[email protected]269200b12010-11-18 22:53:064739 DoGenSharedIdsCHROMIUM(namespace_id, id_offset, n, ids);
[email protected]066849e32010-05-03 19:14:104740 return error::kNoError;
4741}
4742
[email protected]269200b12010-11-18 22:53:064743void GLES2DecoderImpl::DoRegisterSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104744 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574745 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104746 for (GLsizei ii = 0; ii < n; ++ii) {
4747 if (!id_allocator->MarkAsUsed(ids[ii])) {
4748 for (GLsizei jj = 0; jj < ii; ++jj) {
4749 id_allocator->FreeID(ids[jj]);
4750 }
[email protected]ab09b612013-03-11 22:11:514751 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:434752 GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM",
4753 "attempt to register id that already exists");
[email protected]066849e32010-05-03 19:14:104754 return;
4755 }
4756 }
4757}
4758
[email protected]269200b12010-11-18 22:53:064759error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354760 uint32 immediate_data_size, const cmds::RegisterSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104761 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4762 GLsizei n = static_cast<GLsizei>(c.n);
4763 uint32 data_size;
4764 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4765 return error::kOutOfBounds;
4766 }
4767 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4768 c.ids_shm_id, c.ids_shm_offset, data_size);
4769 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514770 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104771 return error::kNoError;
4772 }
4773 if (ids == NULL) {
4774 return error::kOutOfBounds;
4775 }
[email protected]269200b12010-11-18 22:53:064776 DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104777 return error::kNoError;
4778}
4779
[email protected]a7266a92012-06-28 02:11:084780error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:444781 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:204782 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]297ca1c2011-06-20 23:08:464783 ApplyDirtyState();
[email protected]3a03a8f2011-03-19 00:51:274784 glClear(mask);
4785 }
[email protected]a7266a92012-06-28 02:11:084786 return error::kNoError;
4787}
4788
[email protected]36cef8ce2010-03-16 07:34:454789void GLES2DecoderImpl::DoFramebufferRenderbuffer(
4790 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:034791 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:064792 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4793 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514794 LOCAL_SET_GL_ERROR(
4795 GL_INVALID_OPERATION,
4796 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454797 return;
4798 }
[email protected]ae51d192010-04-27 00:48:034799 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:274800 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:034801 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:274802 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
4803 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:514804 LOCAL_SET_GL_ERROR(
4805 GL_INVALID_OPERATION,
4806 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:034807 return;
4808 }
[email protected]ee2a79c32013-03-10 03:50:274809 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:034810 }
[email protected]ab09b612013-03-11 22:11:514811 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:034812 glFramebufferRenderbufferEXT(
4813 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:514814 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:264815 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:274816 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:284817 }
[email protected]9d3b2e12013-10-02 01:04:344818 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:444819 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:464820 }
[email protected]81fc9d02013-03-14 23:53:324821 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:284822}
4823
[email protected]3a2e7c7b2010-08-06 01:12:284824void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464825 if (SetCapabilityState(cap, false)) {
4826 glDisable(cap);
4827 }
[email protected]3a2e7c7b2010-08-06 01:12:284828}
4829
4830void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464831 if (SetCapabilityState(cap, true)) {
4832 glEnable(cap);
4833 }
[email protected]3a2e7c7b2010-08-06 01:12:284834}
4835
[email protected]88a61bf2012-10-27 13:00:424836void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
4837 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
4838 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
4839 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:284840}
4841
[email protected]b04e24c2013-01-08 18:35:254842void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:424843 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
4844 state_.sample_coverage_invert = (invert != 0);
4845 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:284846}
4847
[email protected]0d6bfdc2011-11-02 01:32:204848// Assumes framebuffer is complete.
4849void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:064850 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304851 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:204852 // bind this to the DRAW point, clear then bind back to READ
4853 // TODO(gman): I don't think there is any guarantee that an FBO that
4854 // is complete on the READ attachment will be complete as a DRAW
4855 // attachment.
4856 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:064857 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:304858 }
[email protected]3a2e7c7b2010-08-06 01:12:284859 GLbitfield clear_bits = 0;
[email protected]4d8f0dd2013-03-09 14:37:064860 if (framebuffer->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)) {
[email protected]297ca1c2011-06-20 23:08:464861 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:204862 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:464863 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:064864 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
4865 1.0f);
[email protected]3a2e7c7b2010-08-06 01:12:284866 glColorMask(true, true, true, true);
4867 clear_bits |= GL_COLOR_BUFFER_BIT;
4868 }
4869
[email protected]4d8f0dd2013-03-09 14:37:064870 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
4871 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:284872 glClearStencil(0);
4873 glStencilMask(-1);
4874 clear_bits |= GL_STENCIL_BUFFER_BIT;
4875 }
4876
[email protected]4d8f0dd2013-03-09 14:37:064877 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
4878 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:284879 glClearDepth(1.0f);
4880 glDepthMask(true);
4881 clear_bits |= GL_DEPTH_BUFFER_BIT;
4882 }
4883
4884 glDisable(GL_SCISSOR_TEST);
4885 glClear(clear_bits);
4886
[email protected]968351b2011-12-20 08:26:514887 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:064888 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:284889
[email protected]c007aa02010-09-02 22:22:404890 RestoreClearState();
4891
4892 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:064893 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
4894 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:484895 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:064896 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
4897 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:484898 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:404899 }
4900}
4901
4902void GLES2DecoderImpl::RestoreClearState() {
[email protected]c986af502013-08-14 01:04:444903 framebuffer_state_.clear_state_dirty = true;
[email protected]e259eb412012-10-13 05:47:244904 glClearColor(
4905 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
4906 state_.color_clear_alpha);
4907 glClearStencil(state_.stencil_clear);
4908 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:224909 if (state_.enable_flags.scissor_test) {
[email protected]3a2e7c7b2010-08-06 01:12:284910 glEnable(GL_SCISSOR_TEST);
4911 }
[email protected]36cef8ce2010-03-16 07:34:454912}
4913
4914GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:354915 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:304916 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:204917 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:454918 return GL_FRAMEBUFFER_COMPLETE;
4919 }
[email protected]0d6bfdc2011-11-02 01:32:204920 GLenum completeness = framebuffer->IsPossiblyComplete();
4921 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
4922 return completeness;
4923 }
[email protected]73276522012-11-09 05:50:204924 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:454925}
4926
4927void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:034928 GLenum target, GLenum attachment, GLenum textarget,
4929 GLuint client_texture_id, GLint level) {
[email protected]7d3c36e2013-07-12 14:13:164930 DoFramebufferTexture2DCommon(
4931 "glFramebufferTexture2D", target, attachment,
4932 textarget, client_texture_id, level, 0);
4933}
4934
4935void GLES2DecoderImpl::DoFramebufferTexture2DMultisample(
4936 GLenum target, GLenum attachment, GLenum textarget,
4937 GLuint client_texture_id, GLint level, GLsizei samples) {
4938 if (!features().multisampled_render_to_texture) {
4939 LOCAL_SET_GL_ERROR(
4940 GL_INVALID_OPERATION,
4941 "glFramebufferTexture2DMultisample", "function not available");
4942 return;
4943 }
4944 DoFramebufferTexture2DCommon(
4945 "glFramebufferTexture2DMultisample", target, attachment,
4946 textarget, client_texture_id, level, samples);
4947}
4948
4949void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
4950 const char* name, GLenum target, GLenum attachment, GLenum textarget,
4951 GLuint client_texture_id, GLint level, GLsizei samples) {
4952 if (samples > renderbuffer_manager()->max_samples()) {
4953 LOCAL_SET_GL_ERROR(
4954 GL_INVALID_VALUE,
4955 "glFramebufferTexture2DMultisample", "samples too large");
4956 return;
4957 }
[email protected]4d8f0dd2013-03-09 14:37:064958 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4959 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514960 LOCAL_SET_GL_ERROR(
4961 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:164962 name, "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:454963 return;
4964 }
[email protected]ae51d192010-04-27 00:48:034965 GLuint service_id = 0;
[email protected]370eaf12013-05-18 09:19:494966 TextureRef* texture_ref = NULL;
[email protected]ae51d192010-04-27 00:48:034967 if (client_texture_id) {
[email protected]370eaf12013-05-18 09:19:494968 texture_ref = GetTexture(client_texture_id);
4969 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:514970 LOCAL_SET_GL_ERROR(
4971 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:164972 name, "unknown texture_ref");
[email protected]ae51d192010-04-27 00:48:034973 return;
4974 }
[email protected]370eaf12013-05-18 09:19:494975 service_id = texture_ref->service_id();
[email protected]ae51d192010-04-27 00:48:034976 }
[email protected]0d6bfdc2011-11-02 01:32:204977
[email protected]80eb6b52012-01-19 00:14:414978 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:514979 LOCAL_SET_GL_ERROR(
4980 GL_INVALID_VALUE,
[email protected]7d3c36e2013-07-12 14:13:164981 name, "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:204982 return;
4983 }
4984
[email protected]91c94eb2013-10-22 10:32:544985 if (texture_ref)
4986 DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget);
4987
[email protected]7d3c36e2013-07-12 14:13:164988 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
4989 if (0 == samples) {
4990 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
4991 } else {
4992 if (features().use_img_for_multisampled_render_to_texture) {
4993 glFramebufferTexture2DMultisampleIMG(target, attachment, textarget,
4994 service_id, level, samples);
4995 } else {
4996 glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
4997 service_id, level, samples);
4998 }
4999 }
5000 GLenum error = LOCAL_PEEK_GL_ERROR(name);
[email protected]9edc6b22010-12-23 02:00:265001 if (error == GL_NO_ERROR) {
[email protected]7d3c36e2013-07-12 14:13:165002 framebuffer->AttachTexture(attachment, texture_ref, textarget, level,
5003 samples);
[email protected]3a2e7c7b2010-08-06 01:12:285004 }
[email protected]9d3b2e12013-10-02 01:04:345005 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445006 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465007 }
[email protected]91c94eb2013-10-22 10:32:545008
5009 if (texture_ref)
5010 DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget);
5011
[email protected]81fc9d02013-03-14 23:53:325012 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:455013}
5014
5015void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
5016 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:065017 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5018 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515019 LOCAL_SET_GL_ERROR(
5020 GL_INVALID_OPERATION,
[email protected]caa13ed2014-02-17 11:29:205021 "glGetFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455022 return;
5023 }
[email protected]74c1ec42010-08-12 01:55:575024 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
[email protected]62e65f02013-05-29 22:28:105025 const Framebuffer::Attachment* attachment_object =
5026 framebuffer->GetAttachment(attachment);
5027 *params = attachment_object ? attachment_object->object_name() : 0;
5028 } else {
[email protected]7d3c36e2013-07-12 14:13:165029 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT &&
5030 features().use_img_for_multisampled_render_to_texture) {
5031 pname = GL_TEXTURE_SAMPLES_IMG;
5032 }
[email protected]62e65f02013-05-29 22:28:105033 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:575034 }
[email protected]36cef8ce2010-03-16 07:34:455035}
5036
5037void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
5038 GLenum target, GLenum pname, GLint* params) {
[email protected]ed9f9cd2013-02-27 21:12:355039 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205040 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5041 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515042 LOCAL_SET_GL_ERROR(
5043 GL_INVALID_OPERATION,
5044 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455045 return;
5046 }
[email protected]3a03a8f2011-03-19 00:51:275047 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:435048 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5049 *params = renderbuffer->internal_format();
5050 break;
5051 case GL_RENDERBUFFER_WIDTH:
5052 *params = renderbuffer->width();
5053 break;
5054 case GL_RENDERBUFFER_HEIGHT:
5055 *params = renderbuffer->height();
5056 break;
[email protected]7d3c36e2013-07-12 14:13:165057 case GL_RENDERBUFFER_SAMPLES_EXT:
5058 if (features().use_img_for_multisampled_render_to_texture) {
5059 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG,
5060 params);
5061 } else {
5062 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT,
5063 params);
5064 }
[email protected]ad84a3a2012-06-08 21:42:435065 default:
5066 glGetRenderbufferParameterivEXT(target, pname, params);
5067 break;
[email protected]b71f52c2010-06-18 22:20:205068 }
[email protected]36cef8ce2010-03-16 07:34:455069}
5070
[email protected]49cabed2013-11-13 18:15:185071void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:305072 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
5073 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5074 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:445075 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]62e155e2012-10-23 22:43:155076 if (!features().chromium_framebuffer_multisample) {
[email protected]ab09b612013-03-11 22:11:515077 LOCAL_SET_GL_ERROR(
5078 GL_INVALID_OPERATION,
[email protected]49cabed2013-11-13 18:15:185079 "glBlitFramebufferCHROMIUM", "function not available");
[email protected]680aa412013-10-31 18:08:015080 return;
[email protected]8e3e0662010-08-23 18:46:305081 }
[email protected]0c16343f2013-03-08 20:40:165082
[email protected]49cabed2013-11-13 18:15:185083 if (!CheckBoundFramebuffersValid("glBlitFramebufferCHROMIUM")) {
[email protected]0c16343f2013-03-08 20:40:165084 return;
5085 }
5086
[email protected]d058bca2012-11-26 10:27:265087 glDisable(GL_SCISSOR_TEST);
[email protected]f42f05b2013-11-15 21:46:185088 BlitFramebufferHelper(
5089 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5090 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
5091}
5092
5093void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(
5094 const FeatureInfo* feature_info,
5095 GLenum target,
5096 GLsizei samples,
5097 GLenum internal_format,
5098 GLsizei width,
5099 GLsizei height) {
5100 // TODO(sievers): This could be resolved at the GL binding level, but the
5101 // binding process is currently a bit too 'brute force'.
5102 if (feature_info->feature_flags().is_angle) {
5103 glRenderbufferStorageMultisampleANGLE(
5104 target, samples, internal_format, width, height);
5105 } else if (feature_info->feature_flags().use_core_framebuffer_multisample) {
5106 glRenderbufferStorageMultisample(
5107 target, samples, internal_format, width, height);
5108 } else {
5109 glRenderbufferStorageMultisampleEXT(
5110 target, samples, internal_format, width, height);
5111 }
5112}
5113
5114void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0,
5115 GLint srcY0,
5116 GLint srcX1,
5117 GLint srcY1,
5118 GLint dstX0,
5119 GLint dstY0,
5120 GLint dstX1,
5121 GLint dstY1,
5122 GLbitfield mask,
5123 GLenum filter) {
5124 // TODO(sievers): This could be resolved at the GL binding level, but the
5125 // binding process is currently a bit too 'brute force'.
5126 if (feature_info_->feature_flags().is_angle) {
[email protected]5094b0f2010-11-09 19:45:245127 glBlitFramebufferANGLE(
5128 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]f42f05b2013-11-15 21:46:185129 } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) {
5130 glBlitFramebuffer(
5131 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]5094b0f2010-11-09 19:45:245132 } else {
5133 glBlitFramebufferEXT(
5134 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5135 }
[email protected]8e3e0662010-08-23 18:46:305136}
5137
[email protected]49cabed2013-11-13 18:15:185138bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample(
5139 GLsizei samples,
5140 GLenum internalformat,
5141 GLsizei width,
5142 GLsizei height) {
[email protected]84afefa2011-10-19 21:45:535143 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:515144 LOCAL_SET_GL_ERROR(
5145 GL_INVALID_VALUE,
5146 "glRenderbufferStorageMultisample", "samples too large");
[email protected]49cabed2013-11-13 18:15:185147 return false;
[email protected]84afefa2011-10-19 21:45:535148 }
5149
5150 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5151 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515152 LOCAL_SET_GL_ERROR(
5153 GL_INVALID_VALUE,
5154 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185155 return false;
[email protected]84afefa2011-10-19 21:45:535156 }
5157
[email protected]7989c9e2013-01-23 06:39:265158 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235159 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5160 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515161 LOCAL_SET_GL_ERROR(
5162 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205163 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185164 return false;
[email protected]8e3e0662010-08-23 18:46:305165 }
5166
[email protected]7989c9e2013-01-23 06:39:265167 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515168 LOCAL_SET_GL_ERROR(
5169 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205170 "glRenderbufferStorageMultisample", "out of memory");
[email protected]49cabed2013-11-13 18:15:185171 return false;
5172 }
5173
5174 return true;
5175}
5176
5177void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM(
5178 GLenum target, GLsizei samples, GLenum internalformat,
5179 GLsizei width, GLsizei height) {
5180 if (!features().chromium_framebuffer_multisample) {
5181 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5182 "glRenderbufferStorageMultisampleCHROMIUM",
5183 "function not available");
5184 return;
5185 }
5186
5187 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5188 if (!renderbuffer) {
5189 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5190 "glRenderbufferStorageMultisampleCHROMIUM",
5191 "no renderbuffer bound");
5192 return;
5193 }
5194
5195 if (!ValidateRenderbufferStorageMultisample(
5196 samples, internalformat, width, height)) {
[email protected]7989c9e2013-01-23 06:39:265197 return;
5198 }
5199
[email protected]8e102e102013-09-20 22:50:235200 GLenum impl_format =
5201 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5202 internalformat);
[email protected]49cabed2013-11-13 18:15:185203 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(
5204 "glRenderbufferStorageMultisampleCHROMIUM");
[email protected]f42f05b2013-11-15 21:46:185205 RenderbufferStorageMultisampleHelper(
5206 feature_info_, target, samples, impl_format, width, height);
[email protected]49cabed2013-11-13 18:15:185207 GLenum error =
5208 LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM");
[email protected]9edc6b22010-12-23 02:00:265209 if (error == GL_NO_ERROR) {
[email protected]4a4c18b2013-09-13 22:50:105210
5211 if (workarounds().validate_multisample_buffer_allocation) {
5212 if (!VerifyMultisampleRenderbufferIntegrity(
5213 renderbuffer->service_id(), impl_format)) {
5214 LOCAL_SET_GL_ERROR(
5215 GL_OUT_OF_MEMORY,
[email protected]49cabed2013-11-13 18:15:185216 "glRenderbufferStorageMultisampleCHROMIUM", "out of memory");
[email protected]4a4c18b2013-09-13 22:50:105217 return;
5218 }
5219 }
5220
[email protected]968351b2011-12-20 08:26:515221 // TODO(gman): If renderbuffers tracked which framebuffers they were
5222 // attached to we could just mark those framebuffers as not complete.
5223 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205224 renderbuffer_manager()->SetInfo(
5225 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265226 }
[email protected]8e3e0662010-08-23 18:46:305227}
5228
[email protected]49cabed2013-11-13 18:15:185229// This is the handler for multisampled_render_to_texture extensions.
5230void GLES2DecoderImpl::DoRenderbufferStorageMultisampleEXT(
5231 GLenum target, GLsizei samples, GLenum internalformat,
5232 GLsizei width, GLsizei height) {
5233 if (!features().multisampled_render_to_texture) {
5234 LOCAL_SET_GL_ERROR(
5235 GL_INVALID_OPERATION,
5236 "glRenderbufferStorageMultisampleEXT", "function not available");
5237 return;
5238 }
5239
5240 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5241 if (!renderbuffer) {
5242 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5243 "glRenderbufferStorageMultisampleEXT",
5244 "no renderbuffer bound");
5245 return;
5246 }
5247
5248 if (!ValidateRenderbufferStorageMultisample(
5249 samples, internalformat, width, height)) {
5250 return;
5251 }
5252
5253 GLenum impl_format =
5254 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5255 internalformat);
5256 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT");
5257 if (features().use_img_for_multisampled_render_to_texture) {
5258 glRenderbufferStorageMultisampleIMG(
5259 target, samples, impl_format, width, height);
5260 } else {
5261 glRenderbufferStorageMultisampleEXT(
5262 target, samples, impl_format, width, height);
5263 }
5264 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT");
5265 if (error == GL_NO_ERROR) {
5266 // TODO(gman): If renderbuffers tracked which framebuffers they were
5267 // attached to we could just mark those framebuffers as not complete.
5268 framebuffer_manager()->IncFramebufferStateChangeCount();
5269 renderbuffer_manager()->SetInfo(
5270 renderbuffer, samples, internalformat, width, height);
5271 }
5272}
5273
[email protected]4a4c18b2013-09-13 22:50:105274// This function validates the allocation of a multisampled renderbuffer
5275// by clearing it to a key color, blitting the contents to a texture, and
5276// reading back the color to ensure it matches the key.
5277bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity(
5278 GLuint renderbuffer, GLenum format) {
5279
5280 // Only validate color buffers.
5281 // These formats have been selected because they are very common or are known
5282 // to be used by the WebGL backbuffer. If problems are observed with other
5283 // color formats they can be added here.
5284 switch(format) {
5285 case GL_RGB:
5286 case GL_RGB8:
5287 case GL_RGBA:
5288 case GL_RGBA8:
5289 break;
5290 default:
5291 return true;
5292 }
5293
5294 GLint draw_framebuffer, read_framebuffer;
5295
5296 // Cache framebuffer and texture bindings.
5297 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer);
5298 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer);
5299
5300 if (!validation_texture_) {
5301 GLint bound_texture;
5302 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
5303
5304 // Create additional resources needed for the verification.
5305 glGenTextures(1, &validation_texture_);
5306 glGenFramebuffersEXT(1, &validation_fbo_multisample_);
5307 glGenFramebuffersEXT(1, &validation_fbo_);
5308
5309 // Texture only needs to be 1x1.
5310 glBindTexture(GL_TEXTURE_2D, validation_texture_);
5311 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB,
5312 GL_UNSIGNED_BYTE, NULL);
5313
5314 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5315 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5316 GL_TEXTURE_2D, validation_texture_, 0);
5317
5318 glBindTexture(GL_TEXTURE_2D, bound_texture);
5319 }
5320
5321 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5322 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5323 GL_RENDERBUFFER, renderbuffer);
5324
5325 // Cache current state and reset it to the values we require.
5326 GLboolean scissor_enabled = false;
5327 glGetBooleanv(GL_SCISSOR_TEST, &scissor_enabled);
5328 if (scissor_enabled)
5329 glDisable(GL_SCISSOR_TEST);
5330
5331 GLboolean color_mask[4] = {true, true, true, true};
5332 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask);
5333 glColorMask(true, true, true, true);
5334
5335 GLfloat clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5336 glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color);
5337 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
5338
5339 // Clear the buffer to the desired key color.
5340 glClear(GL_COLOR_BUFFER_BIT);
5341
5342 // Blit from the multisample buffer to a standard texture.
5343 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, validation_fbo_multisample_);
5344 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, validation_fbo_);
5345
[email protected]f42f05b2013-11-15 21:46:185346 BlitFramebufferHelper(
5347 0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
[email protected]4a4c18b2013-09-13 22:50:105348
5349 // Read a pixel from the buffer.
5350 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5351
5352 unsigned char pixel[3] = {0, 0, 0};
5353 glReadPixels(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);
5354
5355 // Detach the renderbuffer.
5356 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5357 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5358 GL_RENDERBUFFER, 0);
5359
5360 // Restore cached state.
5361 if (scissor_enabled)
5362 glEnable(GL_SCISSOR_TEST);
5363
5364 glColorMask(color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
5365 glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
5366 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, draw_framebuffer);
5367 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, read_framebuffer);
5368
5369 // Return true if the pixel matched the desired key color.
5370 return (pixel[0] == 0xFF &&
5371 pixel[1] == 0x00 &&
5372 pixel[2] == 0xFF);
5373}
5374
[email protected]36cef8ce2010-03-16 07:34:455375void GLES2DecoderImpl::DoRenderbufferStorage(
5376 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:355377 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205378 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5379 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515380 LOCAL_SET_GL_ERROR(
5381 GL_INVALID_OPERATION,
5382 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455383 return;
5384 }
[email protected]876f6fee2010-08-02 23:10:325385
[email protected]84afefa2011-10-19 21:45:535386 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5387 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515388 LOCAL_SET_GL_ERROR(
5389 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535390 return;
5391 }
5392
[email protected]7989c9e2013-01-23 06:39:265393 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235394 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5395 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515396 LOCAL_SET_GL_ERROR(
5397 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265398 return;
5399 }
5400
5401 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515402 LOCAL_SET_GL_ERROR(
5403 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265404 return;
[email protected]b71f52c2010-06-18 22:20:205405 }
[email protected]876f6fee2010-08-02 23:10:325406
[email protected]ab09b612013-03-11 22:11:515407 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:265408 glRenderbufferStorageEXT(
[email protected]8e102e102013-09-20 22:50:235409 target,
5410 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5411 internalformat),
5412 width,
5413 height);
[email protected]ab09b612013-03-11 22:11:515414 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:265415 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515416 // TODO(gman): If tetxures tracked which framebuffers they were attached to
5417 // we could just mark those framebuffers as not complete.
5418 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205419 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:265420 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265421 }
[email protected]36cef8ce2010-03-16 07:34:455422}
5423
[email protected]df37b9932013-03-08 05:21:425424void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:385425 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:425426 Program* program = GetProgramInfoNotShader(
5427 program_id, "glLinkProgram");
5428 if (!program) {
[email protected]a93bb842010-02-16 23:03:475429 return;
5430 }
[email protected]05afda12011-01-20 00:17:345431
[email protected]df37b9932013-03-08 05:21:425432 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]65dfc602012-07-23 20:39:395433 ShaderTranslator* vertex_translator = NULL;
5434 ShaderTranslator* fragment_translator = NULL;
5435 if (use_shader_translator_) {
[email protected]7cd76fd2013-06-02 21:11:115436 vertex_translator = vertex_translator_.get();
5437 fragment_translator = fragment_translator_.get();
[email protected]65dfc602012-07-23 20:39:395438 }
[email protected]df37b9932013-03-08 05:21:425439 if (program->Link(shader_manager(),
[email protected]7cd76fd2013-06-02 21:11:115440 vertex_translator,
5441 fragment_translator,
[email protected]008401532014-02-07 00:10:505442 workarounds().count_all_in_varyings_packing ?
5443 Program::kCountAll : Program::kCountOnlyStaticallyUsed,
[email protected]7cd76fd2013-06-02 21:11:115444 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:425445 if (program == state_.current_program.get()) {
[email protected]b05955552014-02-06 18:41:185446 if (workarounds().use_current_program_after_successful_link)
[email protected]df37b9932013-03-08 05:21:425447 glUseProgram(program->service_id());
[email protected]b05955552014-02-06 18:41:185448 if (workarounds().clear_uniforms_before_first_program_use)
5449 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:545450 }
5451 }
[email protected]07f54fcc2009-12-22 02:46:305452};
5453
[email protected]3916c97e2010-02-25 03:20:505454void GLES2DecoderImpl::DoTexParameterf(
5455 GLenum target, GLenum pname, GLfloat param) {
[email protected]c986af502013-08-14 01:04:445456 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5457 &state_, target);
[email protected]02965c22013-03-09 02:40:075458 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515459 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245460 return;
[email protected]07f54fcc2009-12-22 02:46:305461 }
[email protected]cbb22e42011-05-12 23:36:245462
[email protected]02965c22013-03-09 02:40:075463 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505464 "glTexParameterf", GetErrorState(), texture, pname,
5465 static_cast<GLint>(param));
[email protected]07f54fcc2009-12-22 02:46:305466}
5467
[email protected]3916c97e2010-02-25 03:20:505468void GLES2DecoderImpl::DoTexParameteri(
5469 GLenum target, GLenum pname, GLint param) {
[email protected]c986af502013-08-14 01:04:445470 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5471 &state_, target);
[email protected]02965c22013-03-09 02:40:075472 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515473 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245474 return;
[email protected]3916c97e2010-02-25 03:20:505475 }
[email protected]cbb22e42011-05-12 23:36:245476
[email protected]02965c22013-03-09 02:40:075477 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505478 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:505479}
5480
5481void GLES2DecoderImpl::DoTexParameterfv(
5482 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]c986af502013-08-14 01:04:445483 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5484 &state_, target);
[email protected]02965c22013-03-09 02:40:075485 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515486 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245487 return;
[email protected]3916c97e2010-02-25 03:20:505488 }
[email protected]cbb22e42011-05-12 23:36:245489
[email protected]02965c22013-03-09 02:40:075490 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505491 "glTexParameterfv", GetErrorState(), texture, pname,
5492 static_cast<GLint>(params[0]));
[email protected]3916c97e2010-02-25 03:20:505493}
5494
5495void GLES2DecoderImpl::DoTexParameteriv(
5496 GLenum target, GLenum pname, const GLint* params) {
[email protected]c986af502013-08-14 01:04:445497 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5498 &state_, target);
[email protected]02965c22013-03-09 02:40:075499 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515500 LOCAL_SET_GL_ERROR(
5501 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245502 return;
[email protected]3916c97e2010-02-25 03:20:505503 }
[email protected]cbb22e42011-05-12 23:36:245504
[email protected]02965c22013-03-09 02:40:075505 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505506 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505507}
5508
[email protected]939e7362010-05-13 20:49:105509bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]7cd76fd2013-06-02 21:11:115510 if (!state_.current_program.get()) {
[email protected]ad84a3a2012-06-08 21:42:435511 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:515512 LOCAL_SET_GL_ERROR(
5513 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:435514 return false;
[email protected]939e7362010-05-13 20:49:105515 }
[email protected]e259eb412012-10-13 05:47:245516 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:515517 LOCAL_SET_GL_ERROR(
5518 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:105519 return false;
5520 }
5521 return true;
5522}
5523
5524bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
5525 GLint location, const char* function_name) {
5526 if (!CheckCurrentProgram(function_name)) {
5527 return false;
5528 }
5529 return location != -1;
5530}
5531
[email protected]476ccb72012-12-06 15:52:525532namespace {
5533
5534static const GLenum valid_int_vec1_types_list[] = {
5535 GL_INT,
5536 GL_BOOL,
5537 GL_SAMPLER_2D,
5538 GL_SAMPLER_2D_RECT_ARB,
5539 GL_SAMPLER_CUBE,
5540 GL_SAMPLER_EXTERNAL_OES,
5541};
5542
5543static const GLenum valid_int_vec2_types_list[] = {
5544 GL_INT_VEC2,
5545 GL_BOOL_VEC2,
5546};
5547
5548static const GLenum valid_int_vec3_types_list[] = {
5549 GL_INT_VEC3,
5550 GL_BOOL_VEC3,
5551};
5552
5553static const GLenum valid_int_vec4_types_list[] = {
5554 GL_INT_VEC4,
5555 GL_BOOL_VEC4,
5556};
5557
5558static const GLenum valid_float_vec1_types_list[] = {
5559 GL_FLOAT,
5560 GL_BOOL,
5561};
5562
5563static const GLenum valid_float_vec2_types_list[] = {
5564 GL_FLOAT_VEC2,
5565 GL_BOOL_VEC2,
5566};
5567
5568static const GLenum valid_float_vec3_types_list[] = {
5569 GL_FLOAT_VEC3,
5570 GL_BOOL_VEC3,
5571};
5572
5573static const GLenum valid_float_vec4_types_list[] = {
5574 GL_FLOAT_VEC4,
5575 GL_BOOL_VEC4,
5576};
5577
5578static const GLenum valid_float_mat2_types_list[] = {
5579 GL_FLOAT_MAT2,
5580};
5581
5582static const GLenum valid_float_mat3_types_list[] = {
5583 GL_FLOAT_MAT3,
5584};
5585
5586static const GLenum valid_float_mat4_types_list[] = {
5587 GL_FLOAT_MAT4,
5588};
5589
5590static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec1_base_info = {
5591 valid_int_vec1_types_list,
5592 arraysize(valid_int_vec1_types_list),
5593};
5594
5595static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec2_base_info = {
5596 valid_int_vec2_types_list,
5597 arraysize(valid_int_vec2_types_list),
5598};
5599
5600static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec3_base_info = {
5601 valid_int_vec3_types_list,
5602 arraysize(valid_int_vec3_types_list),
5603};
5604
5605static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec4_base_info = {
5606 valid_int_vec4_types_list,
5607 arraysize(valid_int_vec4_types_list),
5608};
5609
5610static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec1_base_info = {
5611 valid_float_vec1_types_list,
5612 arraysize(valid_float_vec1_types_list),
5613};
5614
5615static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec2_base_info = {
5616 valid_float_vec2_types_list,
5617 arraysize(valid_float_vec2_types_list),
5618};
5619
5620static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec3_base_info = {
5621 valid_float_vec3_types_list,
5622 arraysize(valid_float_vec3_types_list),
5623};
5624
5625static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec4_base_info = {
5626 valid_float_vec4_types_list,
5627 arraysize(valid_float_vec4_types_list),
5628};
5629
5630static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat2_base_info = {
5631 valid_float_mat2_types_list,
5632 arraysize(valid_float_mat2_types_list),
5633};
5634
5635static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat3_base_info = {
5636 valid_float_mat3_types_list,
5637 arraysize(valid_float_mat3_types_list),
5638};
5639
5640static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat4_base_info = {
5641 valid_float_mat4_types_list,
5642 arraysize(valid_float_mat4_types_list),
5643};
5644
5645} // anonymous namespace.
5646
[email protected]43c2f1f2011-03-25 18:35:365647bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:125648 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:525649 const GLES2DecoderImpl::BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:125650 GLint* real_location, GLenum* type, GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:365651 DCHECK(type);
5652 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:125653 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:525654
[email protected]1b0a6752012-02-22 03:44:125655 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:105656 return false;
5657 }
[email protected]43c2f1f2011-03-25 18:35:365658 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:355659 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:245660 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:125661 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:365662 if (!info) {
[email protected]ab09b612013-03-11 22:11:515663 LOCAL_SET_GL_ERROR(
5664 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:105665 return false;
5666 }
[email protected]476ccb72012-12-06 15:52:525667 bool okay = false;
5668 for (size_t ii = 0; ii < base_info.num_valid_types; ++ii) {
5669 if (base_info.valid_types[ii] == info->type) {
5670 okay = true;
5671 break;
5672 }
5673 }
5674 if (!okay) {
[email protected]ab09b612013-03-11 22:11:515675 LOCAL_SET_GL_ERROR(
5676 GL_INVALID_OPERATION, function_name,
5677 "wrong uniform function for type");
[email protected]476ccb72012-12-06 15:52:525678 return false;
5679 }
[email protected]43c2f1f2011-03-25 18:35:365680 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:515681 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435682 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:365683 return false;
5684 }
5685 *count = std::min(info->size - array_index, *count);
5686 if (*count <= 0) {
5687 return false;
5688 }
5689 *type = info->type;
[email protected]939e7362010-05-13 20:49:105690 return true;
5691}
5692
[email protected]1b0a6752012-02-22 03:44:125693void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
5694 GLenum type = 0;
5695 GLsizei count = 1;
5696 GLint real_location = -1;
5697 if (!PrepForSetUniformByLocation(
[email protected]caa13ed2014-02-17 11:29:205698 fake_location, "glUniform1i", valid_int_vec1_base_info,
[email protected]476ccb72012-12-06 15:52:525699 &real_location, &type, &count)) {
[email protected]3916c97e2010-02-25 03:20:505700 return;
5701 }
[email protected]e259eb412012-10-13 05:47:245702 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025703 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:515704 LOCAL_SET_GL_ERROR(
5705 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465706 return;
5707 }
[email protected]1b0a6752012-02-22 03:44:125708 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:505709}
5710
5711void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:125712 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:365713 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125714 GLint real_location = -1;
5715 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525716 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5717 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365718 return;
5719 }
[email protected]74727112012-06-13 21:18:085720 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
5721 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:245722 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025723 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:515724 LOCAL_SET_GL_ERROR(
5725 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465726 return;
5727 }
[email protected]43c2f1f2011-03-25 18:35:365728 }
[email protected]1b0a6752012-02-22 03:44:125729 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:505730}
5731
[email protected]939e7362010-05-13 20:49:105732void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:125733 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365734 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125735 GLint real_location = -1;
5736 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525737 fake_location, "glUniform1fv", valid_float_vec1_base_info,
5738 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105739 return;
5740 }
5741 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:555742 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:105743 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:535744 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105745 }
[email protected]1b0a6752012-02-22 03:44:125746 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105747 } else {
[email protected]1b0a6752012-02-22 03:44:125748 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105749 }
5750}
5751
5752void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:125753 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365754 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125755 GLint real_location = -1;
5756 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525757 fake_location, "glUniform2fv", valid_float_vec2_base_info,
5758 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105759 return;
5760 }
5761 if (type == GL_BOOL_VEC2) {
5762 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:555763 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105764 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535765 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105766 }
[email protected]1b0a6752012-02-22 03:44:125767 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105768 } else {
[email protected]1b0a6752012-02-22 03:44:125769 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105770 }
5771}
5772
5773void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:125774 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365775 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125776 GLint real_location = -1;
5777 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525778 fake_location, "glUniform3fv", valid_float_vec3_base_info,
5779 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105780 return;
5781 }
5782 if (type == GL_BOOL_VEC3) {
5783 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:555784 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105785 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535786 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105787 }
[email protected]1b0a6752012-02-22 03:44:125788 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105789 } else {
[email protected]1b0a6752012-02-22 03:44:125790 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105791 }
5792}
5793
5794void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:125795 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365796 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125797 GLint real_location = -1;
5798 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525799 fake_location, "glUniform4fv", valid_float_vec4_base_info,
5800 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105801 return;
5802 }
5803 if (type == GL_BOOL_VEC4) {
5804 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:555805 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105806 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535807 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105808 }
[email protected]1b0a6752012-02-22 03:44:125809 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105810 } else {
[email protected]1b0a6752012-02-22 03:44:125811 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105812 }
5813}
5814
[email protected]43c2f1f2011-03-25 18:35:365815void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:125816 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365817 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125818 GLint real_location = -1;
5819 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525820 fake_location, "glUniform2iv", valid_int_vec2_base_info,
5821 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365822 return;
5823 }
[email protected]1b0a6752012-02-22 03:44:125824 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365825}
5826
5827void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:125828 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365829 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125830 GLint real_location = -1;
5831 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525832 fake_location, "glUniform3iv", valid_int_vec3_base_info,
5833 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365834 return;
5835 }
[email protected]1b0a6752012-02-22 03:44:125836 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365837}
5838
5839void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:125840 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365841 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125842 GLint real_location = -1;
5843 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525844 fake_location, "glUniform4iv", valid_int_vec4_base_info,
5845 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365846 return;
5847 }
[email protected]1b0a6752012-02-22 03:44:125848 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365849}
5850
5851void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:125852 GLint fake_location, GLsizei count, GLboolean transpose,
5853 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365854 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125855 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365856 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525857 fake_location, "glUniformMatrix2fv", valid_float_mat2_base_info,
5858 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365859 return;
5860 }
[email protected]1b0a6752012-02-22 03:44:125861 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365862}
5863
5864void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:125865 GLint fake_location, GLsizei count, GLboolean transpose,
5866 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365867 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125868 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365869 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525870 fake_location, "glUniformMatrix3fv", valid_float_mat3_base_info,
5871 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365872 return;
5873 }
[email protected]1b0a6752012-02-22 03:44:125874 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365875}
5876
5877void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:125878 GLint fake_location, GLsizei count, GLboolean transpose,
5879 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365880 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125881 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365882 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525883 fake_location, "glUniformMatrix4fv", valid_float_mat4_base_info,
5884 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365885 return;
5886 }
[email protected]1b0a6752012-02-22 03:44:125887 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365888}
5889
[email protected]df37b9932013-03-08 05:21:425890void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:035891 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:425892 Program* program = NULL;
5893 if (program_id) {
5894 program = GetProgramInfoNotShader(program_id, "glUseProgram");
5895 if (!program) {
[email protected]ae51d192010-04-27 00:48:035896 return;
5897 }
[email protected]df37b9932013-03-08 05:21:425898 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:505899 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:515900 LOCAL_SET_GL_ERROR(
5901 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:505902 return;
5903 }
[email protected]df37b9932013-03-08 05:21:425904 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:505905 }
[email protected]7cd76fd2013-06-02 21:11:115906 if (state_.current_program.get()) {
5907 program_manager()->UnuseProgram(shader_manager(),
5908 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:145909 }
[email protected]df37b9932013-03-08 05:21:425910 state_.current_program = program;
5911 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:545912 glUseProgram(service_id);
[email protected]7cd76fd2013-06-02 21:11:115913 if (state_.current_program.get()) {
5914 program_manager()->UseProgram(state_.current_program.get());
[email protected]b05955552014-02-06 18:41:185915 if (workarounds().clear_uniforms_before_first_program_use)
5916 program_manager()->ClearUniforms(program);
[email protected]ca488e12010-12-13 20:06:145917 }
[email protected]3916c97e2010-02-25 03:20:505918}
5919
[email protected]ab09b612013-03-11 22:11:515920void GLES2DecoderImpl::RenderWarning(
5921 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:325922 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:015923}
5924
[email protected]ab09b612013-03-11 22:11:515925void GLES2DecoderImpl::PerformanceWarning(
5926 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:505927 logger_.LogMessage(filename, line,
5928 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:015929}
5930
[email protected]91c94eb2013-10-22 10:32:545931void GLES2DecoderImpl::DoWillUseTexImageIfNeeded(
5932 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:545933 // Image is already in use if texture is attached to a framebuffer.
5934 if (texture && !texture->IsAttachedToFramebuffer()) {
5935 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
5936 if (image) {
5937 ScopedGLErrorSuppressor suppressor(
5938 "GLES2DecoderImpl::DoWillUseTexImageIfNeeded",
5939 GetErrorState());
5940 glBindTexture(textarget, texture->service_id());
5941 image->WillUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:025942 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:545943 }
5944 }
5945}
5946
5947void GLES2DecoderImpl::DoDidUseTexImageIfNeeded(
5948 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:545949 // Image is still in use if texture is attached to a framebuffer.
5950 if (texture && !texture->IsAttachedToFramebuffer()) {
5951 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
5952 if (image) {
5953 ScopedGLErrorSuppressor suppressor(
5954 "GLES2DecoderImpl::DoDidUseTexImageIfNeeded",
5955 GetErrorState());
5956 glBindTexture(textarget, texture->service_id());
5957 image->DidUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:025958 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:545959 }
5960 }
5961}
5962
[email protected]e56131d22013-07-28 16:14:115963bool GLES2DecoderImpl::PrepareTexturesForRender() {
[email protected]7cd76fd2013-06-02 21:11:115964 DCHECK(state_.current_program.get());
[email protected]91c94eb2013-10-22 10:32:545965 if (!texture_manager()->HaveUnrenderableTextures() &&
[email protected]7bffe9e12014-01-27 23:02:555966 !texture_manager()->HaveImages()) {
[email protected]e56131d22013-07-28 16:14:115967 return true;
[email protected]ef526492010-06-02 23:12:255968 }
[email protected]e2367b42013-05-31 03:37:215969
[email protected]ef526492010-06-02 23:12:255970 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:355971 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245972 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505973 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355974 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245975 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505976 DCHECK(uniform_info);
5977 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5978 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025979 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245980 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]91c94eb2013-10-22 10:32:545981 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:365982 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]91c94eb2013-10-22 10:32:545983 GLenum textarget = GetBindTargetForSamplerType(uniform_info->type);
5984 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]ef526492010-06-02 23:12:255985 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:505986 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
5987 glBindTexture(
[email protected]91c94eb2013-10-22 10:32:545988 textarget,
[email protected]00f893d2010-08-24 18:55:495989 texture_manager()->black_texture_id(uniform_info->type));
[email protected]ab09b612013-03-11 22:11:515990 LOCAL_RENDER_WARNING(
[email protected]0f8afe82012-05-14 23:43:015991 std::string("texture bound to texture unit ") +
5992 base::IntToString(texture_unit_index) +
[email protected]ad9b7f8b2013-06-17 07:36:295993 " is not renderable. It maybe non-power-of-2 and have"
5994 " incompatible texture filtering or is not"
5995 " 'texture complete'");
[email protected]91c94eb2013-10-22 10:32:545996 continue;
[email protected]3916c97e2010-02-25 03:20:505997 }
[email protected]91c94eb2013-10-22 10:32:545998
[email protected]4e7b89202014-01-28 01:44:065999 if (textarget != GL_TEXTURE_CUBE_MAP) {
6000 Texture* texture = texture_ref->texture();
6001 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6002 if (image && !texture->IsAttachedToFramebuffer()) {
6003 ScopedGLErrorSuppressor suppressor(
6004 "GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState());
6005 textures_set = true;
6006 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6007 image->WillUseTexImage();
6008 continue;
6009 }
[email protected]91c94eb2013-10-22 10:32:546010 }
[email protected]3916c97e2010-02-25 03:20:506011 }
6012 // else: should this be an error?
6013 }
6014 }
[email protected]e56131d22013-07-28 16:14:116015 return !textures_set;
[email protected]3916c97e2010-02-25 03:20:506016}
6017
[email protected]91c94eb2013-10-22 10:32:546018void GLES2DecoderImpl::RestoreStateForTextures() {
[email protected]7cd76fd2013-06-02 21:11:116019 DCHECK(state_.current_program.get());
[email protected]ed9f9cd2013-02-27 21:12:356020 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116021 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506022 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356023 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246024 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506025 DCHECK(uniform_info);
6026 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6027 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026028 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246029 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]7cd76fd2013-06-02 21:11:116030 TextureRef* texture_ref =
[email protected]91c94eb2013-10-22 10:32:546031 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496032 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]3916c97e2010-02-25 03:20:506033 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]370eaf12013-05-18 09:19:496034 // Get the texture_ref info that was previously bound here.
[email protected]7cd76fd2013-06-02 21:11:116035 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D
6036 ? texture_unit.bound_texture_2d.get()
6037 : texture_unit.bound_texture_cube_map.get();
[email protected]3916c97e2010-02-25 03:20:506038 glBindTexture(texture_unit.bind_target,
[email protected]370eaf12013-05-18 09:19:496039 texture_ref ? texture_ref->service_id() : 0);
[email protected]91c94eb2013-10-22 10:32:546040 continue;
6041 }
6042
[email protected]4e7b89202014-01-28 01:44:066043 if (texture_unit.bind_target != GL_TEXTURE_CUBE_MAP) {
6044 Texture* texture = texture_ref->texture();
6045 gfx::GLImage* image =
6046 texture->GetLevelImage(texture_unit.bind_target, 0);
6047 if (image && !texture->IsAttachedToFramebuffer()) {
6048 ScopedGLErrorSuppressor suppressor(
6049 "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState());
6050 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6051 image->DidUseTexImage();
6052 continue;
6053 }
[email protected]3916c97e2010-02-25 03:20:506054 }
6055 }
6056 }
6057 }
6058 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:246059 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:306060}
6061
[email protected]0d6bfdc2011-11-02 01:32:206062bool GLES2DecoderImpl::ClearUnclearedTextures() {
6063 // Only check if there are some uncleared textures.
6064 if (!texture_manager()->HaveUnsafeTextures()) {
6065 return true;
6066 }
6067
6068 // 1: Check all textures we are about to render with.
[email protected]7cd76fd2013-06-02 21:11:116069 if (state_.current_program.get()) {
[email protected]ed9f9cd2013-02-27 21:12:356070 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116071 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:206072 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356073 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246074 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:206075 DCHECK(uniform_info);
6076 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6077 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026078 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246079 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:496080 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366081 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496082 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
6083 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
[email protected]0d6bfdc2011-11-02 01:32:206084 return false;
6085 }
6086 }
6087 }
6088 }
6089 }
6090 }
6091 return true;
6092}
6093
[email protected]c6aef902012-02-14 03:31:426094bool GLES2DecoderImpl::IsDrawValid(
[email protected]ad84a3a2012-06-08 21:42:436095 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount) {
[email protected]689fa1c52010-06-09 18:35:036096 // NOTE: We specifically do not check current_program->IsValid() because
6097 // it could never be invalid since glUseProgram would have failed. While
6098 // glLinkProgram could later mark the program as invalid the previous
6099 // valid program will still function if it is still the current program.
[email protected]7cd76fd2013-06-02 21:11:116100 if (!state_.current_program.get()) {
[email protected]3916c97e2010-02-25 03:20:506101 // The program does not exist.
6102 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:516103 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:506104 return false;
6105 }
[email protected]c6aef902012-02-14 03:31:426106
[email protected]7cd76fd2013-06-02 21:11:116107 return state_.vertex_attrib_manager
6108 ->ValidateBindings(function_name,
6109 this,
6110 feature_info_.get(),
6111 state_.current_program.get(),
6112 max_vertex_accessed,
6113 primcount);
[email protected]b1122982010-05-17 23:04:246114}
6115
[email protected]c13e1da62011-09-09 21:48:306116bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:436117 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:306118 DCHECK(simulated);
6119 *simulated = false;
6120
[email protected]876f6fee2010-08-02 23:10:326121 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:306122 return true;
[email protected]876f6fee2010-08-02 23:10:326123
[email protected]ac77603c72013-03-08 13:52:066124 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:356125 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:246126 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:246127 bool attrib_0_used =
6128 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:066129 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:306130 return true;
[email protected]b1122982010-05-17 23:04:246131 }
6132
[email protected]b1122982010-05-17 23:04:246133 // Make a buffer with a single repeated vec4 value enough to
6134 // simulate the constant value that is supposed to be here.
6135 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:306136 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:476137 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:306138
6139 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:476140 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306141 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516142 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306143 return false;
6144 }
6145
[email protected]ab09b612013-03-11 22:11:516146 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016147 "Attribute 0 is disabled. This has signficant performance penalty");
6148
[email protected]ab09b612013-03-11 22:11:516149 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:306150 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
6151
[email protected]8f0b86c2f2012-04-10 05:48:286152 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
6153 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:496154 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306155 GLenum error = glGetError();
6156 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516157 LOCAL_SET_GL_ERROR(
6158 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306159 return false;
6160 }
[email protected]fc753442011-02-04 19:49:496161 }
[email protected]af6380962012-11-29 23:24:136162
6163 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:286164 if (new_buffer ||
6165 (attrib_0_used &&
6166 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:136167 (value.v[0] != attrib_0_value_.v[0] ||
6168 value.v[1] != attrib_0_value_.v[1] ||
6169 value.v[2] != attrib_0_value_.v[2] ||
6170 value.v[3] != attrib_0_value_.v[3])))) {
6171 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:496172 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
6173 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:136174 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:246175 attrib_0_size_ = size_needed;
6176 }
6177
6178 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
6179
[email protected]ac77603c72013-03-08 13:52:066180 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:426181 glVertexAttribDivisorANGLE(0, 0);
6182
[email protected]c13e1da62011-09-09 21:48:306183 *simulated = true;
[email protected]b1122982010-05-17 23:04:246184 return true;
[email protected]b1122982010-05-17 23:04:246185}
6186
[email protected]ac77603c72013-03-08 13:52:066187void GLES2DecoderImpl::RestoreStateForAttrib(GLuint attrib_index) {
6188 const VertexAttrib* attrib =
6189 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
6190 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
6191 Buffer* buffer = attrib->buffer();
[email protected]b10492f2013-03-08 05:24:076192 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
[email protected]b1122982010-05-17 23:04:246193 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066194 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
6195 attrib->gl_stride(), ptr);
6196 if (attrib->divisor())
6197 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:246198 glBindBuffer(
6199 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:116200 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
6201 : 0);
[email protected]43410e92012-04-20 17:06:286202
[email protected]265f8992012-07-20 01:03:146203 // Never touch vertex attribute 0's state (in particular, never
6204 // disable it) when running on desktop GL because it will never be
6205 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:066206 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:146207 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:066208 if (attrib->enabled()) {
6209 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146210 } else {
[email protected]ac77603c72013-03-08 13:52:066211 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146212 }
[email protected]43410e92012-04-20 17:06:286213 }
[email protected]b1122982010-05-17 23:04:246214}
[email protected]07f54fcc2009-12-22 02:46:306215
[email protected]8fbedc02010-11-18 18:43:406216bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:436217 const char* function_name,
[email protected]c6aef902012-02-14 03:31:426218 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:406219 DCHECK(simulated);
6220 *simulated = false;
6221 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
6222 return true;
6223
[email protected]e259eb412012-10-13 05:47:246224 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:406225 return true;
6226 }
6227
[email protected]ab09b612013-03-11 22:11:516228 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016229 "GL_FIXED attributes have a signficant performance penalty");
6230
[email protected]8fbedc02010-11-18 18:43:406231 // NOTE: we could be smart and try to check if a buffer is used
6232 // twice in 2 different attribs, find the overlapping parts and therefore
6233 // duplicate the minimum amount of data but this whole code path is not meant
6234 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
6235 // tests so we just add to the buffer attrib used.
6236
[email protected]c13e1da62011-09-09 21:48:306237 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:066238 const VertexAttribManager::VertexAttribList& enabled_attribs =
6239 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
6240 for (VertexAttribManager::VertexAttribList::const_iterator it =
6241 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6242 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356243 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066244 state_.current_program->GetAttribInfoByLocation(attrib->index());
6245 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
6246 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:426247 GLuint num_vertices = max_accessed + 1;
6248 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516249 LOCAL_SET_GL_ERROR(
6250 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426251 return false;
6252 }
[email protected]8fbedc02010-11-18 18:43:406253 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066254 attrib->CanAccess(max_accessed) &&
6255 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:476256 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:066257 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:476258 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:516259 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436260 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406261 return false;
6262 }
6263 }
6264 }
6265
[email protected]3aad1a32012-09-07 20:54:476266 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
6267 uint32 size_needed = 0;
6268 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306269 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516270 LOCAL_SET_GL_ERROR(
6271 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406272 return false;
6273 }
6274
[email protected]ab09b612013-03-11 22:11:516275 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:406276
6277 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:306278 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:406279 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306280 GLenum error = glGetError();
6281 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516282 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436283 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:306284 return false;
6285 }
[email protected]8fbedc02010-11-18 18:43:406286 }
6287
6288 // Copy the elements and convert to float
6289 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:066290 for (VertexAttribManager::VertexAttribList::const_iterator it =
6291 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6292 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356293 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066294 state_.current_program->GetAttribInfoByLocation(attrib->index());
6295 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:426296 max_vertex_accessed);
6297 GLuint num_vertices = max_accessed + 1;
6298 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516299 LOCAL_SET_GL_ERROR(
6300 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426301 return false;
6302 }
[email protected]8fbedc02010-11-18 18:43:406303 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066304 attrib->CanAccess(max_accessed) &&
6305 attrib->type() == GL_FIXED) {
6306 int num_elements = attrib->size() * kSizeOfFloat;
[email protected]8fbedc02010-11-18 18:43:406307 int size = num_elements * num_vertices;
[email protected]40d90a22013-04-09 03:39:556308 scoped_ptr<float[]> data(new float[size]);
[email protected]8fbedc02010-11-18 18:43:406309 const int32* src = reinterpret_cast<const int32 *>(
[email protected]ac77603c72013-03-08 13:52:066310 attrib->buffer()->GetRange(attrib->offset(), size));
[email protected]8fbedc02010-11-18 18:43:406311 const int32* end = src + num_elements;
6312 float* dst = data.get();
6313 while (src != end) {
6314 *dst++ = static_cast<float>(*src++) / 65536.0f;
6315 }
6316 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get());
6317 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066318 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:406319 reinterpret_cast<GLvoid*>(offset));
6320 offset += size;
6321 }
6322 }
6323 *simulated = true;
6324 return true;
6325}
6326
6327void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
6328 // There's no need to call glVertexAttribPointer because we shadow all the
6329 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:246330 glBindBuffer(
6331 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:116332 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
6333 : 0);
[email protected]8fbedc02010-11-18 18:43:406334}
6335
[email protected]ad84a3a2012-06-08 21:42:436336error::Error GLES2DecoderImpl::DoDrawArrays(
6337 const char* function_name,
6338 bool instanced,
6339 GLenum mode,
6340 GLint first,
6341 GLsizei count,
6342 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226343 error::Error error = WillAccessBoundFramebufferForDraw();
6344 if (error != error::kNoError)
6345 return error;
[email protected]38d139d2011-07-14 00:38:436346 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516347 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:436348 return error::kNoError;
6349 }
6350 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516351 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:436352 return error::kNoError;
6353 }
[email protected]c6aef902012-02-14 03:31:426354 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516355 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426356 return error::kNoError;
6357 }
[email protected]ad84a3a2012-06-08 21:42:436358 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:436359 return error::kNoError;
6360 }
6361 // We have to check this here because the prototype for glDrawArrays
6362 // is GLint not GLsizei.
6363 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:516364 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:436365 return error::kNoError;
6366 }
6367
[email protected]c6aef902012-02-14 03:31:426368 if (count == 0 || (instanced && primcount == 0)) {
[email protected]ab09b612013-03-11 22:11:516369 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:436370 return error::kNoError;
6371 }
6372
6373 GLuint max_vertex_accessed = first + count - 1;
[email protected]ad84a3a2012-06-08 21:42:436374 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206375 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516376 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206377 return error::kNoError;
6378 }
[email protected]c13e1da62011-09-09 21:48:306379 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436380 if (!SimulateAttrib0(
6381 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306382 return error::kNoError;
6383 }
[email protected]38d139d2011-07-14 00:38:436384 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436385 if (SimulateFixedAttribs(
6386 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6387 primcount)) {
[email protected]e56131d22013-07-28 16:14:116388 bool textures_set = !PrepareTexturesForRender();
[email protected]38d139d2011-07-14 00:38:436389 ApplyDirtyState();
[email protected]c6aef902012-02-14 03:31:426390 if (!instanced) {
6391 glDrawArrays(mode, first, count);
6392 } else {
6393 glDrawArraysInstancedANGLE(mode, first, count, primcount);
6394 }
[email protected]22e3f552012-03-13 01:54:196395 ProcessPendingQueries();
[email protected]38d139d2011-07-14 00:38:436396 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546397 RestoreStateForTextures();
[email protected]38d139d2011-07-14 00:38:436398 }
6399 if (simulated_fixed_attribs) {
6400 RestoreStateForSimulatedFixedAttribs();
6401 }
6402 }
6403 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:286404 RestoreStateForAttrib(0);
[email protected]38d139d2011-07-14 00:38:436405 }
[email protected]38d139d2011-07-14 00:38:436406 }
6407 return error::kNoError;
6408}
6409
[email protected]c6aef902012-02-14 03:31:426410error::Error GLES2DecoderImpl::HandleDrawArrays(
[email protected]ed9f9cd2013-02-27 21:12:356411 uint32 immediate_data_size, const cmds::DrawArrays& c) {
[email protected]ad84a3a2012-06-08 21:42:436412 return DoDrawArrays("glDrawArrays",
6413 false,
[email protected]c6aef902012-02-14 03:31:426414 static_cast<GLenum>(c.mode),
6415 static_cast<GLint>(c.first),
6416 static_cast<GLsizei>(c.count),
6417 0);
6418}
6419
6420error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356421 uint32 immediate_data_size, const cmds::DrawArraysInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156422 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516423 LOCAL_SET_GL_ERROR(
6424 GL_INVALID_OPERATION,
6425 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426426 return error::kNoError;
6427 }
[email protected]ad84a3a2012-06-08 21:42:436428 return DoDrawArrays("glDrawArraysIntancedANGLE",
6429 true,
[email protected]c6aef902012-02-14 03:31:426430 static_cast<GLenum>(c.mode),
6431 static_cast<GLint>(c.first),
6432 static_cast<GLsizei>(c.count),
6433 static_cast<GLsizei>(c.primcount));
6434}
6435
[email protected]ad84a3a2012-06-08 21:42:436436error::Error GLES2DecoderImpl::DoDrawElements(
6437 const char* function_name,
6438 bool instanced,
6439 GLenum mode,
6440 GLsizei count,
6441 GLenum type,
6442 int32 offset,
6443 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226444 error::Error error = WillAccessBoundFramebufferForDraw();
6445 if (error != error::kNoError)
6446 return error;
[email protected]e259eb412012-10-13 05:47:246447 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:516448 LOCAL_SET_GL_ERROR(
6449 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296450 return error::kNoError;
6451 }
6452
[email protected]8eee29c2010-04-29 03:38:296453 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516454 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296455 return error::kNoError;
6456 }
6457 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516458 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296459 return error::kNoError;
6460 }
[email protected]9438b012010-06-15 22:55:056461 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516462 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296463 return error::kNoError;
6464 }
[email protected]9438b012010-06-15 22:55:056465 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516466 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296467 return error::kNoError;
6468 }
[email protected]c6aef902012-02-14 03:31:426469 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516470 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426471 return error::kNoError;
6472 }
[email protected]8eee29c2010-04-29 03:38:296473
[email protected]ad84a3a2012-06-08 21:42:436474 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276475 return error::kNoError;
6476 }
6477
[email protected]c6aef902012-02-14 03:31:426478 if (count == 0 || (instanced && primcount == 0)) {
[email protected]6c788fb72010-08-26 02:16:316479 return error::kNoError;
6480 }
6481
[email protected]8eee29c2010-04-29 03:38:296482 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:086483 Buffer* element_array_buffer =
6484 state_.vertex_attrib_manager->element_array_buffer();
6485
6486 if (!element_array_buffer->GetMaxValueForRange(
6487 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:516488 LOCAL_SET_GL_ERROR(
6489 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296490 return error::kNoError;
6491 }
6492
[email protected]ad84a3a2012-06-08 21:42:436493 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206494 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516495 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206496 return error::kNoError;
6497 }
[email protected]c13e1da62011-09-09 21:48:306498 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436499 if (!SimulateAttrib0(
6500 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306501 return error::kNoError;
6502 }
[email protected]8fbedc02010-11-18 18:43:406503 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436504 if (SimulateFixedAttribs(
6505 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6506 primcount)) {
[email protected]e56131d22013-07-28 16:14:116507 bool textures_set = !PrepareTexturesForRender();
[email protected]297ca1c2011-06-20 23:08:466508 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:086509 // TODO(gman): Refactor to hide these details in BufferManager or
6510 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:406511 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:086512 bool used_client_side_array = false;
6513 if (element_array_buffer->IsClientSideArray()) {
6514 used_client_side_array = true;
6515 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6516 indices = element_array_buffer->GetRange(offset, 0);
6517 }
6518
[email protected]c6aef902012-02-14 03:31:426519 if (!instanced) {
6520 glDrawElements(mode, count, type, indices);
6521 } else {
6522 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6523 }
[email protected]17cfbe0e2013-03-07 01:26:086524
6525 if (used_client_side_array) {
6526 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
6527 element_array_buffer->service_id());
6528 }
6529
[email protected]22e3f552012-03-13 01:54:196530 ProcessPendingQueries();
[email protected]8fbedc02010-11-18 18:43:406531 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546532 RestoreStateForTextures();
[email protected]8fbedc02010-11-18 18:43:406533 }
6534 if (simulated_fixed_attribs) {
6535 RestoreStateForSimulatedFixedAttribs();
6536 }
[email protected]ba3176a2009-12-16 18:19:466537 }
[email protected]b1122982010-05-17 23:04:246538 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:286539 RestoreStateForAttrib(0);
[email protected]b1122982010-05-17 23:04:246540 }
[email protected]96449d2c2009-11-25 00:01:326541 }
[email protected]f7a64ee2010-02-01 22:24:146542 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326543}
6544
[email protected]c6aef902012-02-14 03:31:426545error::Error GLES2DecoderImpl::HandleDrawElements(
[email protected]ed9f9cd2013-02-27 21:12:356546 uint32 immediate_data_size, const cmds::DrawElements& c) {
[email protected]ad84a3a2012-06-08 21:42:436547 return DoDrawElements("glDrawElements",
6548 false,
[email protected]c6aef902012-02-14 03:31:426549 static_cast<GLenum>(c.mode),
6550 static_cast<GLsizei>(c.count),
6551 static_cast<GLenum>(c.type),
6552 static_cast<int32>(c.index_offset),
6553 0);
6554}
6555
6556error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356557 uint32 immediate_data_size, const cmds::DrawElementsInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156558 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516559 LOCAL_SET_GL_ERROR(
6560 GL_INVALID_OPERATION,
6561 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426562 return error::kNoError;
6563 }
[email protected]ad84a3a2012-06-08 21:42:436564 return DoDrawElements("glDrawElementsInstancedANGLE",
6565 true,
[email protected]c6aef902012-02-14 03:31:426566 static_cast<GLenum>(c.mode),
6567 static_cast<GLsizei>(c.count),
6568 static_cast<GLenum>(c.type),
6569 static_cast<int32>(c.index_offset),
6570 static_cast<GLsizei>(c.primcount));
6571}
6572
[email protected]269200b12010-11-18 22:53:066573GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:236574 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
6575 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:076576 Buffer* buffer = GetBuffer(buffer_id);
6577 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:036578 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516579 LOCAL_SET_GL_ERROR(
6580 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:236581 } else {
[email protected]b10492f2013-03-08 05:24:076582 if (!buffer->GetMaxValueForRange(
6583 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:036584 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516585 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:066586 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436587 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:236588 }
6589 }
6590 return max_vertex_accessed;
6591}
6592
[email protected]96449d2c2009-11-25 00:01:326593// Calls glShaderSource for the various versions of the ShaderSource command.
6594// Assumes that data / data_size points to a piece of memory that is in range
6595// of whatever context it came from (shared memory, immediate memory, bucket
6596// memory.)
[email protected]45bf5152010-02-12 00:11:316597error::Error GLES2DecoderImpl::ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036598 GLuint client_id, const char* data, uint32 data_size) {
[email protected]258a3313f2011-10-18 20:13:576599 std::string str(data, data + data_size);
[email protected]df37b9932013-03-08 05:21:426600 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
6601 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316602 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326603 }
[email protected]45bf5152010-02-12 00:11:316604 // Note: We don't actually call glShaderSource here. We wait until
6605 // the call to glCompileShader.
[email protected]df37b9932013-03-08 05:21:426606 shader->UpdateSource(str.c_str());
[email protected]f7a64ee2010-02-01 22:24:146607 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326608}
6609
[email protected]f7a64ee2010-02-01 22:24:146610error::Error GLES2DecoderImpl::HandleShaderSource(
[email protected]ed9f9cd2013-02-27 21:12:356611 uint32 immediate_data_size, const cmds::ShaderSource& c) {
[email protected]96449d2c2009-11-25 00:01:326612 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:316613 const char* data = GetSharedMemoryAs<const char*>(
[email protected]96449d2c2009-11-25 00:01:326614 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]ba3176a2009-12-16 18:19:466615 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146616 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:326617 }
[email protected]ae51d192010-04-27 00:48:036618 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]96449d2c2009-11-25 00:01:326619}
6620
[email protected]558847a2010-03-24 07:02:546621error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
[email protected]ed9f9cd2013-02-27 21:12:356622 uint32 immediate_data_size, const cmds::ShaderSourceBucket& c) {
[email protected]558847a2010-03-24 07:02:546623 Bucket* bucket = GetBucket(c.data_bucket_id);
6624 if (!bucket || bucket->size() == 0) {
6625 return error::kInvalidArguments;
6626 }
6627 return ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036628 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
[email protected]558847a2010-03-24 07:02:546629 bucket->size() - 1);
6630}
6631
[email protected]ae51d192010-04-27 00:48:036632void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:386633 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:426634 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
6635 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316636 return;
6637 }
[email protected]f57bb282010-11-12 00:51:346638 ShaderTranslator* translator = NULL;
[email protected]b1d2dcb2010-05-17 19:24:186639 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:426640 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]a550584e2010-09-17 18:01:456641 vertex_translator_.get() : fragment_translator_.get();
[email protected]de17df392010-04-23 21:09:416642 }
[email protected]de17df392010-04-23 21:09:416643
[email protected]b05955552014-02-06 18:41:186644 program_manager()->DoCompileShader(
6645 shader,
6646 translator,
6647 feature_info_->feature_flags().angle_translated_shader_source ?
6648 ProgramManager::kANGLE : ProgramManager::kGL);
[email protected]45bf5152010-02-12 00:11:316649};
6650
[email protected]ddd968b82010-03-02 00:44:296651void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:426652 GLuint shader_id, GLenum pname, GLint* params) {
6653 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
6654 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:296655 return;
6656 }
[email protected]8f1ccdac2010-05-19 21:01:486657 switch (pname) {
6658 case GL_SHADER_SOURCE_LENGTH:
[email protected]df37b9932013-03-08 05:21:426659 *params = shader->source() ? shader->source()->size() + 1 : 0;
[email protected]8f1ccdac2010-05-19 21:01:486660 return;
6661 case GL_COMPILE_STATUS:
[email protected]df37b9932013-03-08 05:21:426662 *params = compile_shader_always_succeeds_ ? true : shader->IsValid();
[email protected]e5186162010-06-14 18:54:416663 return;
[email protected]8f1ccdac2010-05-19 21:01:486664 case GL_INFO_LOG_LENGTH:
[email protected]df37b9932013-03-08 05:21:426665 *params = shader->log_info() ? shader->log_info()->size() + 1 : 0;
[email protected]e5186162010-06-14 18:54:416666 return;
[email protected]d6a53e42011-10-05 00:09:366667 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
[email protected]df37b9932013-03-08 05:21:426668 *params = shader->translated_source() ?
6669 shader->translated_source()->size() + 1 : 0;
[email protected]d6a53e42011-10-05 00:09:366670 return;
[email protected]8f1ccdac2010-05-19 21:01:486671 default:
6672 break;
[email protected]ddd968b82010-03-02 00:44:296673 }
[email protected]df37b9932013-03-08 05:21:426674 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:296675}
6676
[email protected]ae51d192010-04-27 00:48:036677error::Error GLES2DecoderImpl::HandleGetShaderSource(
[email protected]ed9f9cd2013-02-27 21:12:356678 uint32 immediate_data_size, const cmds::GetShaderSource& c) {
[email protected]df37b9932013-03-08 05:21:426679 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:036680 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6681 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426682 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
6683 if (!shader || !shader->source()) {
[email protected]8eee29c2010-04-29 03:38:296684 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:296685 return error::kNoError;
6686 }
[email protected]df37b9932013-03-08 05:21:426687 bucket->SetFromString(shader->source()->c_str());
[email protected]ae51d192010-04-27 00:48:036688 return error::kNoError;
6689}
6690
[email protected]d6a53e42011-10-05 00:09:366691error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
6692 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:356693 const cmds::GetTranslatedShaderSourceANGLE& c) {
[email protected]df37b9932013-03-08 05:21:426694 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:366695 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6696 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426697 Shader* shader = GetShaderInfoNotProgram(
[email protected]caa13ed2014-02-17 11:29:206698 shader_id, "glGetTranslatedShaderSourceANGLE");
[email protected]df37b9932013-03-08 05:21:426699 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:366700 bucket->SetSize(0);
6701 return error::kNoError;
6702 }
6703
[email protected]df37b9932013-03-08 05:21:426704 bucket->SetFromString(shader->translated_source() ?
6705 shader->translated_source()->c_str() : NULL);
[email protected]d6a53e42011-10-05 00:09:366706 return error::kNoError;
6707}
6708
[email protected]ae51d192010-04-27 00:48:036709error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356710 uint32 immediate_data_size, const cmds::GetProgramInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426711 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:586712 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6713 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426714 Program* program = GetProgramInfoNotShader(
6715 program_id, "glGetProgramInfoLog");
6716 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466717 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036718 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:316719 }
[email protected]df37b9932013-03-08 05:21:426720 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036721 return error::kNoError;
6722}
6723
6724error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356725 uint32 immediate_data_size, const cmds::GetShaderInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426726 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:586727 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6728 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426729 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
6730 if (!shader || !shader->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466731 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036732 return error::kNoError;
6733 }
[email protected]df37b9932013-03-08 05:21:426734 bucket->SetFromString(shader->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036735 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326736}
6737
[email protected]d058bca2012-11-26 10:27:266738bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
6739 return state_.GetEnabled(cap);
6740}
6741
[email protected]1958e0e2010-04-22 05:17:156742bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:216743 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106744 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156745}
6746
6747bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356748 const Framebuffer* framebuffer =
6749 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106750 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156751}
6752
6753bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366754 // IsProgram is true for programs as soon as they are created, until they are
6755 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:356756 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:106757 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156758}
6759
6760bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356761 const Renderbuffer* renderbuffer =
6762 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106763 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156764}
6765
6766bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366767 // IsShader is true for shaders as soon as they are created, until they
6768 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:356769 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:106770 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156771}
6772
6773bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:496774 const TextureRef* texture_ref = GetTexture(client_id);
6775 return texture_ref && texture_ref->texture()->IsValid();
[email protected]ae51d192010-04-27 00:48:036776}
6777
6778void GLES2DecoderImpl::DoAttachShader(
6779 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426780 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586781 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:426782 if (!program) {
[email protected]ae51d192010-04-27 00:48:036783 return;
[email protected]1958e0e2010-04-22 05:17:156784 }
[email protected]df37b9932013-03-08 05:21:426785 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
6786 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036787 return;
6788 }
[email protected]df37b9932013-03-08 05:21:426789 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516790 LOCAL_SET_GL_ERROR(
6791 GL_INVALID_OPERATION,
6792 "glAttachShader",
6793 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:316794 return;
6795 }
[email protected]df37b9932013-03-08 05:21:426796 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036797}
6798
6799void GLES2DecoderImpl::DoDetachShader(
6800 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426801 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586802 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:426803 if (!program) {
[email protected]ae51d192010-04-27 00:48:036804 return;
6805 }
[email protected]df37b9932013-03-08 05:21:426806 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
6807 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036808 return;
6809 }
[email protected]df37b9932013-03-08 05:21:426810 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516811 LOCAL_SET_GL_ERROR(
6812 GL_INVALID_OPERATION,
6813 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:226814 return;
6815 }
[email protected]df37b9932013-03-08 05:21:426816 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036817}
6818
6819void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:426820 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586821 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:426822 if (!program) {
[email protected]ae51d192010-04-27 00:48:036823 return;
6824 }
[email protected]df37b9932013-03-08 05:21:426825 program->Validate();
[email protected]1958e0e2010-04-22 05:17:156826}
6827
[email protected]ac77603c72013-03-08 13:52:066828void GLES2DecoderImpl::GetVertexAttribHelper(
6829 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:246830 switch (pname) {
6831 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:066832 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:246833 if (buffer && !buffer->IsDeleted()) {
6834 GLuint client_id;
6835 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
6836 *params = client_id;
6837 }
6838 break;
6839 }
6840 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:066841 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:246842 break;
6843 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:066844 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:246845 break;
6846 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:066847 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:246848 break;
6849 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:066850 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:246851 break;
6852 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:066853 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:246854 break;
[email protected]c6aef902012-02-14 03:31:426855 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:066856 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:426857 break;
[email protected]ac77603c72013-03-08 13:52:066858 default:
6859 NOTREACHED();
6860 break;
6861 }
6862}
6863
6864void GLES2DecoderImpl::DoGetVertexAttribfv(
6865 GLuint index, GLenum pname, GLfloat* params) {
6866 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6867 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:516868 LOCAL_SET_GL_ERROR(
6869 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:066870 return;
6871 }
6872 switch (pname) {
6873 case GL_CURRENT_VERTEX_ATTRIB: {
6874 const Vec4& value = state_.attrib_values[index];
6875 params[0] = value.v[0];
6876 params[1] = value.v[1];
6877 params[2] = value.v[2];
6878 params[3] = value.v[3];
6879 break;
6880 }
6881 default: {
6882 GLint value = 0;
6883 GetVertexAttribHelper(attrib, pname, &value);
6884 *params = static_cast<GLfloat>(value);
6885 break;
6886 }
6887 }
6888}
6889
6890void GLES2DecoderImpl::DoGetVertexAttribiv(
6891 GLuint index, GLenum pname, GLint* params) {
6892 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6893 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:516894 LOCAL_SET_GL_ERROR(
6895 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:066896 return;
6897 }
6898 switch (pname) {
[email protected]af6380962012-11-29 23:24:136899 case GL_CURRENT_VERTEX_ATTRIB: {
6900 const Vec4& value = state_.attrib_values[index];
6901 params[0] = static_cast<GLint>(value.v[0]);
6902 params[1] = static_cast<GLint>(value.v[1]);
6903 params[2] = static_cast<GLint>(value.v[2]);
6904 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:246905 break;
[email protected]af6380962012-11-29 23:24:136906 }
[email protected]b1122982010-05-17 23:04:246907 default:
[email protected]ac77603c72013-03-08 13:52:066908 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:246909 break;
6910 }
6911}
6912
[email protected]af6380962012-11-29 23:24:136913bool GLES2DecoderImpl::SetVertexAttribValue(
6914 const char* function_name, GLuint index, const GLfloat* value) {
6915 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:516916 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:136917 return false;
[email protected]b1122982010-05-17 23:04:246918 }
[email protected]af6380962012-11-29 23:24:136919 Vec4& v = state_.attrib_values[index];
6920 v.v[0] = value[0];
6921 v.v[1] = value[1];
6922 v.v[2] = value[2];
6923 v.v[3] = value[3];
6924 return true;
6925}
6926
6927void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
6928 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
6929 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
6930 glVertexAttrib1f(index, v0);
6931 }
[email protected]b1122982010-05-17 23:04:246932}
6933
6934void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:136935 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
6936 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
6937 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:246938 }
[email protected]b1122982010-05-17 23:04:246939}
6940
6941void GLES2DecoderImpl::DoVertexAttrib3f(
6942 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:136943 GLfloat v[4] = { v0, v1, v2, 1.0f, };
6944 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
6945 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:246946 }
[email protected]b1122982010-05-17 23:04:246947}
6948
6949void GLES2DecoderImpl::DoVertexAttrib4f(
6950 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:136951 GLfloat v[4] = { v0, v1, v2, v3, };
6952 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
6953 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:246954 }
[email protected]b1122982010-05-17 23:04:246955}
6956
6957void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136958 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
6959 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
6960 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:246961 }
[email protected]b1122982010-05-17 23:04:246962}
6963
6964void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136965 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
6966 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
6967 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:246968 }
[email protected]b1122982010-05-17 23:04:246969}
6970
6971void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136972 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
6973 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
6974 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:246975 }
[email protected]b1122982010-05-17 23:04:246976}
6977
6978void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136979 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
6980 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:246981 }
[email protected]b1122982010-05-17 23:04:246982}
6983
[email protected]f7a64ee2010-02-01 22:24:146984error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
[email protected]ed9f9cd2013-02-27 21:12:356985 uint32 immediate_data_size, const cmds::VertexAttribPointer& c) {
[email protected]944b62f32012-09-27 02:20:466986
[email protected]7cd76fd2013-06-02 21:11:116987 if (!state_.bound_array_buffer.get() ||
6988 state_.bound_array_buffer->IsDeleted()) {
6989 if (state_.vertex_attrib_manager.get() ==
6990 default_vertex_attrib_manager_.get()) {
[email protected]ab09b612013-03-11 22:11:516991 LOCAL_SET_GL_ERROR(
6992 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:466993 return error::kNoError;
6994 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:516995 LOCAL_SET_GL_ERROR(
6996 GL_INVALID_VALUE,
6997 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:466998 return error::kNoError;
6999 }
[email protected]96449d2c2009-11-25 00:01:327000 }
[email protected]8eee29c2010-04-29 03:38:297001
7002 GLuint indx = c.indx;
7003 GLint size = c.size;
7004 GLenum type = c.type;
7005 GLboolean normalized = c.normalized;
7006 GLsizei stride = c.stride;
7007 GLsizei offset = c.offset;
7008 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:057009 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517010 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:297011 return error::kNoError;
7012 }
[email protected]9438b012010-06-15 22:55:057013 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:517014 LOCAL_SET_GL_ERROR(
7015 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:297016 return error::kNoError;
7017 }
7018 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517019 LOCAL_SET_GL_ERROR(
7020 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:297021 return error::kNoError;
7022 }
7023 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:517024 LOCAL_SET_GL_ERROR(
7025 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:297026 return error::kNoError;
7027 }
7028 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:517029 LOCAL_SET_GL_ERROR(
7030 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:297031 return error::kNoError;
7032 }
7033 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:517034 LOCAL_SET_GL_ERROR(
7035 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:297036 return error::kNoError;
7037 }
7038 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:317039 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]8eee29c2010-04-29 03:38:297040 if (offset % component_size > 0) {
[email protected]ab09b612013-03-11 22:11:517041 LOCAL_SET_GL_ERROR(
7042 GL_INVALID_OPERATION,
7043 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:317044 return error::kNoError;
7045 }
7046 if (stride % component_size > 0) {
[email protected]ab09b612013-03-11 22:11:517047 LOCAL_SET_GL_ERROR(
7048 GL_INVALID_OPERATION,
7049 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:297050 return error::kNoError;
7051 }
[email protected]7cd76fd2013-06-02 21:11:117052 state_.vertex_attrib_manager
7053 ->SetAttribInfo(indx,
7054 state_.bound_array_buffer.get(),
7055 size,
7056 type,
7057 normalized,
7058 stride,
7059 stride != 0 ? stride : component_size * size,
7060 offset);
[email protected]8fbedc02010-11-18 18:43:407061 if (type != GL_FIXED) {
7062 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
7063 }
[email protected]f7a64ee2010-02-01 22:24:147064 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327065}
7066
[email protected]43410e92012-04-20 17:06:287067void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
7068 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:247069 state_.viewport_x = x;
7070 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:027071 state_.viewport_width = std::min(width, viewport_max_width_);
7072 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:287073 glViewport(x, y, width, height);
7074}
7075
[email protected]c6aef902012-02-14 03:31:427076error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
[email protected]ed9f9cd2013-02-27 21:12:357077 uint32 immediate_data_size, const cmds::VertexAttribDivisorANGLE& c) {
[email protected]62e155e2012-10-23 22:43:157078 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517079 LOCAL_SET_GL_ERROR(
7080 GL_INVALID_OPERATION,
7081 "glVertexAttribDivisorANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:427082 }
7083 GLuint index = c.index;
7084 GLuint divisor = c.divisor;
7085 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517086 LOCAL_SET_GL_ERROR(
7087 GL_INVALID_VALUE,
7088 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:427089 return error::kNoError;
7090 }
7091
[email protected]e259eb412012-10-13 05:47:247092 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:427093 index,
7094 divisor);
7095 glVertexAttribDivisorANGLE(index, divisor);
7096 return error::kNoError;
7097}
7098
[email protected]68586372013-12-11 01:27:597099template <typename pixel_data_type>
7100static void WriteAlphaData(
7101 void *pixels, uint32 row_count, uint32 channel_count,
7102 uint32 alpha_channel_index, uint32 unpadded_row_size,
7103 uint32 padded_row_size, pixel_data_type alpha_value) {
7104 DCHECK_GT(channel_count, 0U);
7105 DCHECK_EQ(unpadded_row_size % sizeof(pixel_data_type), 0U);
7106 uint32 unpadded_row_size_in_elements =
7107 unpadded_row_size / sizeof(pixel_data_type);
7108 DCHECK_EQ(padded_row_size % sizeof(pixel_data_type), 0U);
7109 uint32 padded_row_size_in_elements =
7110 padded_row_size / sizeof(pixel_data_type);
7111 pixel_data_type* dst =
7112 static_cast<pixel_data_type*>(pixels) + alpha_channel_index;
7113 for (uint32 yy = 0; yy < row_count; ++yy) {
7114 pixel_data_type* end = dst + unpadded_row_size_in_elements;
7115 for (pixel_data_type* d = dst; d < end; d += channel_count) {
7116 *d = alpha_value;
7117 }
7118 dst += padded_row_size_in_elements;
7119 }
7120}
7121
[email protected]5a36dc132013-07-23 23:17:557122void GLES2DecoderImpl::FinishReadPixels(
7123 const cmds::ReadPixels& c,
7124 GLuint buffer) {
7125 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels");
7126 GLsizei width = c.width;
7127 GLsizei height = c.height;
7128 GLenum format = c.format;
7129 GLenum type = c.type;
7130 typedef cmds::ReadPixels::Result Result;
7131 uint32 pixels_size;
7132 Result* result = NULL;
7133 if (c.result_shm_id != 0) {
7134 result = GetSharedMemoryAs<Result*>(
7135 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7136 if (!result) {
7137 if (buffer != 0) {
7138 glDeleteBuffersARB(1, &buffer);
7139 }
7140 return;
7141 }
7142 }
7143 GLES2Util::ComputeImageDataSizes(
7144 width, height, format, type, state_.pack_alignment, &pixels_size,
7145 NULL, NULL);
7146 void* pixels = GetSharedMemoryAs<void*>(
7147 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
7148 if (!pixels) {
7149 if (buffer != 0) {
7150 glDeleteBuffersARB(1, &buffer);
7151 }
7152 return;
7153 }
7154
7155 if (buffer != 0) {
7156 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
[email protected]e585f9e22013-08-27 02:50:337157 void* data;
7158 if (features().map_buffer_range) {
7159 data = glMapBufferRange(
7160 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT);
7161 } else {
7162 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
7163 }
[email protected]5a36dc132013-07-23 23:17:557164 memcpy(pixels, data, pixels_size);
7165 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't
7166 // have to restore the state.
7167 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
7168 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7169 glDeleteBuffersARB(1, &buffer);
7170 }
7171
7172 if (result != NULL) {
7173 *result = true;
7174 }
7175
7176 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7177 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7178 if ((channels_exist & 0x0008) == 0 &&
7179 workarounds().clear_alpha_in_readpixels) {
7180 // Set the alpha to 255 because some drivers are buggy in this regard.
7181 uint32 temp_size;
7182
7183 uint32 unpadded_row_size;
7184 uint32 padded_row_size;
7185 if (!GLES2Util::ComputeImageDataSizes(
7186 width, 2, format, type, state_.pack_alignment, &temp_size,
7187 &unpadded_row_size, &padded_row_size)) {
7188 return;
7189 }
[email protected]68586372013-12-11 01:27:597190
7191 uint32 channel_count = 0;
7192 uint32 alpha_channel = 0;
[email protected]5a36dc132013-07-23 23:17:557193 switch (format) {
7194 case GL_RGBA:
7195 case GL_BGRA_EXT:
[email protected]68586372013-12-11 01:27:597196 channel_count = 4;
7197 alpha_channel = 3;
[email protected]5a36dc132013-07-23 23:17:557198 break;
[email protected]68586372013-12-11 01:27:597199 case GL_ALPHA:
7200 channel_count = 1;
7201 alpha_channel = 0;
7202 break;
7203 }
7204
7205 if (channel_count > 0) {
7206 switch (type) {
7207 case GL_UNSIGNED_BYTE:
7208 WriteAlphaData<uint8>(
7209 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7210 padded_row_size, 0xFF);
7211 break;
7212 case GL_FLOAT:
7213 WriteAlphaData<float>(
7214 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7215 padded_row_size, 1.0f);
7216 break;
7217 case GL_HALF_FLOAT:
7218 WriteAlphaData<uint16>(
7219 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7220 padded_row_size, 0x3C00);
7221 break;
[email protected]5a36dc132013-07-23 23:17:557222 }
[email protected]5a36dc132013-07-23 23:17:557223 }
7224 }
7225}
7226
7227
[email protected]f7a64ee2010-02-01 22:24:147228error::Error GLES2DecoderImpl::HandleReadPixels(
[email protected]ed9f9cd2013-02-27 21:12:357229 uint32 immediate_data_size, const cmds::ReadPixels& c) {
[email protected]c76fe672013-12-13 23:30:227230 error::Error fbo_error = WillAccessBoundFramebufferForRead();
7231 if (fbo_error != error::kNoError)
7232 return fbo_error;
[email protected]612d2f82009-12-08 20:49:317233 GLint x = c.x;
7234 GLint y = c.y;
7235 GLsizei width = c.width;
7236 GLsizei height = c.height;
7237 GLenum format = c.format;
7238 GLenum type = c.type;
[email protected]5a36dc132013-07-23 23:17:557239 GLboolean async = c.async;
[email protected]57f223832010-03-19 01:57:567240 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:517241 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:567242 return error::kNoError;
7243 }
[email protected]ed9f9cd2013-02-27 21:12:357244 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:187245 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347246 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247247 width, height, format, type, state_.pack_alignment, &pixels_size,
7248 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187249 return error::kOutOfBounds;
7250 }
[email protected]612d2f82009-12-08 20:49:317251 void* pixels = GetSharedMemoryAs<void*>(
7252 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:107253 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147254 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467255 }
[email protected]de43f082013-04-02 01:16:107256 Result* result = NULL;
7257 if (c.result_shm_id != 0) {
7258 result = GetSharedMemoryAs<Result*>(
7259 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7260 if (!result) {
7261 return error::kOutOfBounds;
7262 }
7263 }
[email protected]a51788e2010-02-24 21:54:257264
[email protected]9438b012010-06-15 22:55:057265 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517266 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:297267 return error::kNoError;
7268 }
[email protected]68586372013-12-11 01:27:597269 if (!validators_->read_pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517270 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:127271 return error::kNoError;
7272 }
[email protected]68586372013-12-11 01:27:597273 if ((format != GL_RGBA && format != GL_BGRA_EXT && format != GL_RGB &&
7274 format != GL_ALPHA) || type != GL_UNSIGNED_BYTE) {
7275 // format and type are acceptable enums but not guaranteed to be supported
7276 // for this framebuffer. Have to ask gl if they are valid.
7277 GLint preferred_format = 0;
7278 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &preferred_format);
7279 GLint preferred_type = 0;
7280 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &preferred_type);
7281 if (format != static_cast<GLenum>(preferred_format) ||
7282 type != static_cast<GLenum>(preferred_type)) {
7283 LOCAL_SET_GL_ERROR(
7284 GL_INVALID_OPERATION, "glReadPixels", "format and type incompatible "
7285 "with the current read framebuffer");
7286 return error::kNoError;
7287 }
7288 }
[email protected]57f223832010-03-19 01:57:567289 if (width == 0 || height == 0) {
7290 return error::kNoError;
7291 }
7292
[email protected]57f223832010-03-19 01:57:567293 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:307294 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:567295
[email protected]3aad1a32012-09-07 20:54:477296 int32 max_x;
7297 int32 max_y;
7298 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:517299 LOCAL_SET_GL_ERROR(
7300 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:147301 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:317302 }
[email protected]57f223832010-03-19 01:57:567303
[email protected]0d6bfdc2011-11-02 01:32:207304 if (!CheckBoundFramebuffersValid("glReadPixels")) {
7305 return error::kNoError;
7306 }
7307
[email protected]caa13ed2014-02-17 11:29:207308 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixels");
[email protected]a0b78dc2011-11-11 10:43:107309
7310 ScopedResolvedFrameBufferBinder binder(this, false, true);
7311
[email protected]d37231fa2010-04-09 21:16:027312 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:567313 // The user requested an out of range area. Get the results 1 line
7314 // at a time.
7315 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:347316 uint32 unpadded_row_size;
7317 uint32 padded_row_size;
7318 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247319 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:347320 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:517321 LOCAL_SET_GL_ERROR(
7322 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567323 return error::kNoError;
7324 }
7325
7326 GLint dest_x_offset = std::max(-x, 0);
7327 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:347328 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247329 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset,
7330 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:517331 LOCAL_SET_GL_ERROR(
7332 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567333 return error::kNoError;
7334 }
7335
7336 // Copy each row into the larger dest rect.
7337 int8* dst = static_cast<int8*>(pixels);
7338 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:027339 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:567340 GLint read_width = read_end_x - read_x;
7341 for (GLint yy = 0; yy < height; ++yy) {
7342 GLint ry = y + yy;
7343
7344 // Clear the row.
7345 memset(dst, 0, unpadded_row_size);
7346
7347 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:027348 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:567349 glReadPixels(
7350 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
7351 }
7352 dst += padded_row_size;
7353 }
7354 } else {
[email protected]5a36dc132013-07-23 23:17:557355 if (async && features().use_async_readpixels) {
7356 GLuint buffer;
7357 glGenBuffersARB(1, &buffer);
7358 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
7359 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, GL_STREAM_READ);
7360 GLenum error = glGetError();
7361 if (error == GL_NO_ERROR) {
7362 glReadPixels(x, y, width, height, format, type, 0);
7363 pending_readpixel_fences_.push(linked_ptr<FenceCallback>(
7364 new FenceCallback()));
7365 WaitForReadPixels(base::Bind(
7366 &GLES2DecoderImpl::FinishReadPixels,
7367 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr
7368 <GLES2DecoderImpl>(this),
7369 c, buffer));
7370 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7371 return error::kNoError;
7372 }
7373 }
[email protected]57f223832010-03-19 01:57:567374 glReadPixels(x, y, width, height, format, type, pixels);
7375 }
[email protected]ab09b612013-03-11 22:11:517376 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:257377 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:107378 if (result != NULL) {
7379 *result = true;
7380 }
[email protected]5a36dc132013-07-23 23:17:557381 FinishReadPixels(c, 0);
[email protected]a51788e2010-02-24 21:54:257382 }
[email protected]4848b9f82011-03-10 18:37:567383
[email protected]f7a64ee2010-02-01 22:24:147384 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327385}
7386
[email protected]f7a64ee2010-02-01 22:24:147387error::Error GLES2DecoderImpl::HandlePixelStorei(
[email protected]ed9f9cd2013-02-27 21:12:357388 uint32 immediate_data_size, const cmds::PixelStorei& c) {
[email protected]b9849abf2009-11-25 19:13:197389 GLenum pname = c.pname;
7390 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:057391 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:517392 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:127393 return error::kNoError;
7394 }
[email protected]222471d2011-11-30 18:06:397395 switch (pname) {
7396 case GL_PACK_ALIGNMENT:
7397 case GL_UNPACK_ALIGNMENT:
7398 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:517399 LOCAL_SET_GL_ERROR(
[email protected]caa13ed2014-02-17 11:29:207400 GL_INVALID_VALUE, "glPixelStorei", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:397401 return error::kNoError;
7402 }
[email protected]164d6d52012-05-05 00:55:037403 break;
[email protected]0a1e9ad2012-05-04 21:13:037404 case GL_UNPACK_FLIP_Y_CHROMIUM:
7405 unpack_flip_y_ = (param != 0);
7406 return error::kNoError;
7407 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
7408 unpack_premultiply_alpha_ = (param != 0);
7409 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:177410 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
7411 unpack_unpremultiply_alpha_ = (param != 0);
7412 return error::kNoError;
[email protected]222471d2011-11-30 18:06:397413 default:
7414 break;
[email protected]b9849abf2009-11-25 19:13:197415 }
7416 glPixelStorei(pname, param);
7417 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:437418 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247419 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437420 break;
7421 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:427422 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:437423 break;
7424 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247425 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437426 break;
7427 default:
7428 // Validation should have prevented us from getting here.
7429 NOTREACHED();
7430 break;
[email protected]b9849abf2009-11-25 19:13:197431 }
[email protected]f7a64ee2010-02-01 22:24:147432 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197433}
7434
[email protected]1c75a3702011-11-11 14:15:287435error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:357436 uint32 immediate_data_size, const cmds::PostSubBufferCHROMIUM& c) {
[email protected]43ed3a72012-05-30 22:55:387437 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]6f5fac9d12012-06-26 21:02:457438 if (!surface_->HasExtension("GL_CHROMIUM_post_sub_buffer")) {
[email protected]ab09b612013-03-11 22:11:517439 LOCAL_SET_GL_ERROR(
7440 GL_INVALID_OPERATION,
7441 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:287442 return error::kNoError;
7443 }
[email protected]8f9b8dd2013-09-12 18:05:137444 bool is_tracing;
7445 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
7446 &is_tracing);
7447 if (is_tracing) {
7448 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
7449 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
7450 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
7451 is_offscreen ? offscreen_size_ : surface_->GetSize());
7452 }
[email protected]7794d512012-04-17 20:36:497453 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:287454 return error::kNoError;
[email protected]7794d512012-04-17 20:36:497455 } else {
7456 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:287457 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:497458 }
[email protected]1c75a3702011-11-11 14:15:287459}
7460
[email protected]558847a2010-03-24 07:02:547461error::Error GLES2DecoderImpl::GetAttribLocationHelper(
7462 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7463 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577464 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517465 LOCAL_SET_GL_ERROR(
7466 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577467 return error::kNoError;
7468 }
[email protected]df37b9932013-03-08 05:21:427469 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587470 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:427471 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147472 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197473 }
[email protected]df37b9932013-03-08 05:21:427474 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517475 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437476 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257477 return error::kNoError;
7478 }
[email protected]b9849abf2009-11-25 19:13:197479 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547480 location_shm_id, location_shm_offset, sizeof(GLint));
7481 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147482 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197483 }
[email protected]558847a2010-03-24 07:02:547484 // Require the client to init this incase the context is lost and we are no
7485 // longer executing commands.
7486 if (*location != -1) {
7487 return error::kGenericError;
7488 }
[email protected]df37b9932013-03-08 05:21:427489 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147490 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197491}
7492
[email protected]558847a2010-03-24 07:02:547493error::Error GLES2DecoderImpl::HandleGetAttribLocation(
[email protected]ed9f9cd2013-02-27 21:12:357494 uint32 immediate_data_size, const cmds::GetAttribLocation& c) {
[email protected]558847a2010-03-24 07:02:547495 uint32 name_size = c.data_size;
7496 const char* name = GetSharedMemoryAs<const char*>(
7497 c.name_shm_id, c.name_shm_offset, name_size);
7498 if (!name) {
7499 return error::kOutOfBounds;
7500 }
7501 String name_str(name, name_size);
7502 return GetAttribLocationHelper(
7503 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7504}
7505
[email protected]558847a2010-03-24 07:02:547506error::Error GLES2DecoderImpl::HandleGetAttribLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:357507 uint32 immediate_data_size, const cmds::GetAttribLocationBucket& c) {
[email protected]558847a2010-03-24 07:02:547508 Bucket* bucket = GetBucket(c.name_bucket_id);
7509 if (!bucket) {
7510 return error::kInvalidArguments;
7511 }
7512 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187513 if (!bucket->GetAsString(&name_str)) {
7514 return error::kInvalidArguments;
7515 }
[email protected]558847a2010-03-24 07:02:547516 return GetAttribLocationHelper(
7517 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7518}
7519
7520error::Error GLES2DecoderImpl::GetUniformLocationHelper(
7521 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7522 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577523 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517524 LOCAL_SET_GL_ERROR(
7525 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577526 return error::kNoError;
7527 }
[email protected]df37b9932013-03-08 05:21:427528 Program* program = GetProgramInfoNotShader(
[email protected]caa13ed2014-02-17 11:29:207529 client_id, "glGetUniformLocation");
[email protected]df37b9932013-03-08 05:21:427530 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147531 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197532 }
[email protected]df37b9932013-03-08 05:21:427533 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517534 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437535 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257536 return error::kNoError;
7537 }
[email protected]b9849abf2009-11-25 19:13:197538 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547539 location_shm_id, location_shm_offset, sizeof(GLint));
7540 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147541 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197542 }
[email protected]558847a2010-03-24 07:02:547543 // Require the client to init this incase the context is lost an we are no
7544 // longer executing commands.
7545 if (*location != -1) {
7546 return error::kGenericError;
7547 }
[email protected]df37b9932013-03-08 05:21:427548 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147549 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197550}
7551
[email protected]f7a64ee2010-02-01 22:24:147552error::Error GLES2DecoderImpl::HandleGetUniformLocation(
[email protected]ed9f9cd2013-02-27 21:12:357553 uint32 immediate_data_size, const cmds::GetUniformLocation& c) {
[email protected]b9849abf2009-11-25 19:13:197554 uint32 name_size = c.data_size;
7555 const char* name = GetSharedMemoryAs<const char*>(
7556 c.name_shm_id, c.name_shm_offset, name_size);
[email protected]558847a2010-03-24 07:02:547557 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:147558 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197559 }
7560 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:547561 return GetUniformLocationHelper(
7562 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197563}
7564
[email protected]558847a2010-03-24 07:02:547565error::Error GLES2DecoderImpl::HandleGetUniformLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:357566 uint32 immediate_data_size, const cmds::GetUniformLocationBucket& c) {
[email protected]558847a2010-03-24 07:02:547567 Bucket* bucket = GetBucket(c.name_bucket_id);
7568 if (!bucket) {
7569 return error::kInvalidArguments;
7570 }
7571 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187572 if (!bucket->GetAsString(&name_str)) {
7573 return error::kInvalidArguments;
7574 }
[email protected]558847a2010-03-24 07:02:547575 return GetUniformLocationHelper(
7576 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197577}
7578
[email protected]ddd968b82010-03-02 00:44:297579error::Error GLES2DecoderImpl::HandleGetString(
[email protected]ed9f9cd2013-02-27 21:12:357580 uint32 immediate_data_size, const cmds::GetString& c) {
[email protected]ddd968b82010-03-02 00:44:297581 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:057582 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:517583 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:297584 return error::kNoError;
7585 }
[email protected]959e9072013-09-20 16:58:387586 const char* str = reinterpret_cast<const char*>(glGetString(name));
[email protected]f0d74742011-10-03 16:31:047587 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:157588 switch (name) {
7589 case GL_VERSION:
7590 str = "OpenGL ES 2.0 Chromium";
7591 break;
7592 case GL_SHADING_LANGUAGE_VERSION:
7593 str = "OpenGL ES GLSL ES 1.0 Chromium";
7594 break;
[email protected]32939602012-05-09 06:25:167595 case GL_RENDERER:
[email protected]32939602012-05-09 06:25:167596 case GL_VENDOR:
[email protected]959e9072013-09-20 16:58:387597 // Return the unmasked VENDOR/RENDERER string for WebGL contexts.
7598 // They are used by WEBGL_debug_renderer_info.
7599 if (!force_webgl_glsl_validation_)
7600 str = "Chromium";
[email protected]32939602012-05-09 06:25:167601 break;
[email protected]1958e0e2010-04-22 05:17:157602 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:047603 {
[email protected]70dc60932013-06-04 03:33:497604 // For WebGL contexts, strip out the OES derivatives and
7605 // EXT frag depth extensions if they have not been enabled.
7606 if (force_webgl_glsl_validation_) {
[email protected]f0d74742011-10-03 16:31:047607 extensions = feature_info_->extensions();
[email protected]70dc60932013-06-04 03:33:497608 if (!derivatives_explicitly_enabled_) {
7609 size_t offset = extensions.find(kOESDerivativeExtension);
7610 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097611 extensions.replace(offset, arraysize(kOESDerivativeExtension),
[email protected]70dc60932013-06-04 03:33:497612 std::string());
7613 }
7614 }
7615 if (!frag_depth_explicitly_enabled_) {
7616 size_t offset = extensions.find(kEXTFragDepthExtension);
7617 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097618 extensions.replace(offset, arraysize(kEXTFragDepthExtension),
[email protected]70dc60932013-06-04 03:33:497619 std::string());
7620 }
[email protected]f0d74742011-10-03 16:31:047621 }
[email protected]aff39ac82013-06-08 04:53:137622 if (!draw_buffers_explicitly_enabled_) {
7623 size_t offset = extensions.find(kEXTDrawBuffersExtension);
7624 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097625 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension),
[email protected]aff39ac82013-06-08 04:53:137626 std::string());
7627 }
7628 }
[email protected]f0d74742011-10-03 16:31:047629 } else {
[email protected]6f5fac9d12012-06-26 21:02:457630 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:047631 }
[email protected]6f5fac9d12012-06-26 21:02:457632 std::string surface_extensions = surface_->GetExtensions();
7633 if (!surface_extensions.empty())
7634 extensions += " " + surface_extensions;
7635 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:047636 }
[email protected]1958e0e2010-04-22 05:17:157637 break;
7638 default:
[email protected]1958e0e2010-04-22 05:17:157639 break;
7640 }
[email protected]ddd968b82010-03-02 00:44:297641 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:157642 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:297643 return error::kNoError;
7644}
7645
[email protected]0c86dbf2010-03-05 08:14:117646error::Error GLES2DecoderImpl::HandleBufferData(
[email protected]ed9f9cd2013-02-27 21:12:357647 uint32 immediate_data_size, const cmds::BufferData& c) {
[email protected]0c86dbf2010-03-05 08:14:117648 GLenum target = static_cast<GLenum>(c.target);
7649 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
7650 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7651 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7652 GLenum usage = static_cast<GLenum>(c.usage);
7653 const void* data = NULL;
7654 if (data_shm_id != 0 || data_shm_offset != 0) {
7655 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
7656 if (!data) {
7657 return error::kOutOfBounds;
7658 }
7659 }
[email protected]0fbba3732013-07-17 15:40:137660 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:147661 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197662}
7663
[email protected]0c86dbf2010-03-05 08:14:117664void GLES2DecoderImpl::DoBufferSubData(
7665 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]0fbba3732013-07-17 15:40:137666 // Just delegate it. Some validation is actually done before this.
7667 buffer_manager()->ValidateAndDoBufferSubData(
7668 &state_, target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:197669}
7670
[email protected]0d6bfdc2011-11-02 01:32:207671bool GLES2DecoderImpl::ClearLevel(
7672 unsigned service_id,
7673 unsigned bind_target,
7674 unsigned target,
7675 int level,
[email protected]d8e6c9242014-02-20 16:56:257676 unsigned internal_format,
[email protected]0d6bfdc2011-11-02 01:32:207677 unsigned format,
7678 unsigned type,
7679 int width,
[email protected]4502e6492011-12-14 19:39:157680 int height,
7681 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:007682 uint32 channels = GLES2Util::GetChannelsForFormat(format);
[email protected]345ba902013-11-14 21:39:007683 if (feature_info_->feature_flags().angle_depth_texture &&
7684 (channels & GLES2Util::kDepth) != 0) {
[email protected]81375742012-06-08 00:04:007685 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
7686 // on depth formats.
7687 GLuint fb = 0;
7688 glGenFramebuffersEXT(1, &fb);
7689 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
7690
7691 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
7692 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
7693 GL_DEPTH_ATTACHMENT;
7694
7695 glFramebufferTexture2DEXT(
7696 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
7697 // ANGLE promises a depth only attachment ok.
7698 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
7699 GL_FRAMEBUFFER_COMPLETE) {
7700 return false;
7701 }
7702 glClearStencil(0);
7703 glStencilMask(-1);
7704 glClearDepth(1.0f);
7705 glDepthMask(true);
7706 glDisable(GL_SCISSOR_TEST);
7707 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
7708
7709 RestoreClearState();
7710
7711 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:357712 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:007713 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
7714 GLuint fb_service_id =
7715 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
7716 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
7717 return true;
7718 }
7719
[email protected]45d15a62012-04-18 14:33:177720 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
7721
7722 uint32 size;
7723 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:347724 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247725 width, height, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:177726 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:207727 return false;
7728 }
[email protected]45d15a62012-04-18 14:33:177729
[email protected]a5d3dad2012-05-26 04:34:447730 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
7731
[email protected]45d15a62012-04-18 14:33:177732 int tile_height;
7733
7734 if (size > kMaxZeroSize) {
7735 if (kMaxZeroSize < padded_row_size) {
7736 // That'd be an awfully large texture.
7737 return false;
7738 }
7739 // We should never have a large total size with a zero row size.
7740 DCHECK_GT(padded_row_size, 0U);
7741 tile_height = kMaxZeroSize / padded_row_size;
7742 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247743 width, tile_height, format, type, state_.unpack_alignment, &size,
7744 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:177745 return false;
7746 }
[email protected]4502e6492011-12-14 19:39:157747 } else {
[email protected]45d15a62012-04-18 14:33:177748 tile_height = height;
7749 }
7750
7751 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:557752 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:177753 memset(zero.get(), 0, size);
7754 glBindTexture(bind_target, service_id);
7755
7756 GLint y = 0;
7757 while (y < height) {
7758 GLint h = y + tile_height > height ? height - y : tile_height;
7759 if (is_texture_immutable || h != height) {
7760 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
7761 } else {
[email protected]8f1d2aa2013-05-10 23:45:387762 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:257763 target, level, internal_format, width, h, 0, format, type,
7764 zero.get());
[email protected]45d15a62012-04-18 14:33:177765 }
7766 y += tile_height;
[email protected]4502e6492011-12-14 19:39:157767 }
[email protected]c986af502013-08-14 01:04:447768 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
7769 &state_, bind_target);
[email protected]02965c22013-03-09 02:40:077770 glBindTexture(bind_target, texture ? texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:207771 return true;
7772}
7773
[email protected]ad84a3a2012-06-08 21:42:437774namespace {
7775
7776const int kS3TCBlockWidth = 4;
7777const int kS3TCBlockHeight = 4;
7778const int kS3TCDXT1BlockSize = 8;
7779const int kS3TCDXT3AndDXT5BlockSize = 16;
[email protected]2d3765b2012-10-03 00:31:077780const int kETC1BlockWidth = 4;
7781const int kETC1BlockHeight = 4;
7782const int kETC1BlockSize = 8;
[email protected]ad84a3a2012-06-08 21:42:437783
7784bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:517785 return (size == 1) ||
7786 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:437787}
7788
7789} // anonymous namespace.
7790
7791bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
7792 const char* function_name,
7793 GLsizei width, GLsizei height, GLenum format, size_t size) {
7794 unsigned int bytes_required = 0;
7795
7796 switch (format) {
7797 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7798 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: {
7799 int num_blocks_across =
7800 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7801 int num_blocks_down =
7802 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7803 int num_blocks = num_blocks_across * num_blocks_down;
7804 bytes_required = num_blocks * kS3TCDXT1BlockSize;
7805 break;
7806 }
7807 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7808 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7809 int num_blocks_across =
7810 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7811 int num_blocks_down =
7812 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7813 int num_blocks = num_blocks_across * num_blocks_down;
7814 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
7815 break;
7816 }
[email protected]2d3765b2012-10-03 00:31:077817 case GL_ETC1_RGB8_OES: {
7818 int num_blocks_across =
7819 (width + kETC1BlockWidth - 1) / kETC1BlockWidth;
7820 int num_blocks_down =
7821 (height + kETC1BlockHeight - 1) / kETC1BlockHeight;
7822 int num_blocks = num_blocks_across * num_blocks_down;
7823 bytes_required = num_blocks * kETC1BlockSize;
7824 break;
7825 }
[email protected]ad84a3a2012-06-08 21:42:437826 default:
[email protected]ab09b612013-03-11 22:11:517827 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:437828 return false;
7829 }
7830
7831 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:517832 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437833 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
7834 return false;
7835 }
7836
7837 return true;
7838}
7839
7840bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
7841 const char* function_name,
7842 GLint level, GLsizei width, GLsizei height, GLenum format) {
7843 switch (format) {
7844 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7845 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7846 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7847 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7848 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:517849 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437850 GL_INVALID_OPERATION, function_name,
7851 "width or height invalid for level");
7852 return false;
7853 }
7854 return true;
7855 }
[email protected]2d3765b2012-10-03 00:31:077856 case GL_ETC1_RGB8_OES:
7857 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:517858 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:077859 GL_INVALID_OPERATION, function_name,
7860 "width or height invalid for level");
7861 return false;
7862 }
7863 return true;
[email protected]ad84a3a2012-06-08 21:42:437864 default:
7865 return false;
7866 }
7867}
7868
7869bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
7870 const char* function_name,
7871 GLenum target, GLint level, GLint xoffset, GLint yoffset,
7872 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:357873 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:437874 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:517875 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437876 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
7877 return false;
7878 }
7879
7880 switch (format) {
7881 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7882 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7883 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7884 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7885 const int kBlockWidth = 4;
7886 const int kBlockHeight = 4;
7887 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:517888 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437889 GL_INVALID_OPERATION, function_name,
7890 "xoffset or yoffset not multiple of 4");
7891 return false;
7892 }
7893 GLsizei tex_width = 0;
7894 GLsizei tex_height = 0;
7895 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
7896 width - xoffset > tex_width ||
7897 height - yoffset > tex_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, "dimensions out of range");
7900 return false;
7901 }
7902 return ValidateCompressedTexDimensions(
7903 function_name, level, width, height, format);
7904 }
[email protected]2d3765b2012-10-03 00:31:077905 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:517906 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:077907 GL_INVALID_OPERATION, function_name,
[email protected]caa13ed2014-02-17 11:29:207908 "not supported for ECT1_RGB8_OES textures");
[email protected]2d3765b2012-10-03 00:31:077909 return false;
7910 }
[email protected]ad84a3a2012-06-08 21:42:437911 default:
7912 return false;
7913 }
7914}
7915
[email protected]a93bb842010-02-16 23:03:477916error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
7917 GLenum target,
7918 GLint level,
7919 GLenum internal_format,
7920 GLsizei width,
7921 GLsizei height,
7922 GLint border,
7923 GLsizei image_size,
7924 const void* data) {
[email protected]a93bb842010-02-16 23:03:477925 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:057926 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517927 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7928 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:297929 return error::kNoError;
7930 }
[email protected]9438b012010-06-15 22:55:057931 if (!validators_->compressed_texture_format.IsValid(
7932 internal_format)) {
[email protected]ab09b612013-03-11 22:11:517933 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:537934 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:477935 return error::kNoError;
7936 }
[email protected]80eb6b52012-01-19 00:14:417937 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:477938 border != 0) {
[email protected]ab09b612013-03-11 22:11:517939 LOCAL_SET_GL_ERROR(
7940 GL_INVALID_VALUE,
7941 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:477942 return error::kNoError;
7943 }
[email protected]c986af502013-08-14 01:04:447944 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
7945 &state_, target);
[email protected]370eaf12013-05-18 09:19:497946 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517947 LOCAL_SET_GL_ERROR(
7948 GL_INVALID_VALUE,
7949 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:477950 return error::kNoError;
7951 }
[email protected]370eaf12013-05-18 09:19:497952 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:077953 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:517954 LOCAL_SET_GL_ERROR(
7955 GL_INVALID_OPERATION,
7956 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:437957 return error::kNoError;
7958 }
7959
7960 if (!ValidateCompressedTexDimensions(
7961 "glCompressedTexImage2D", level, width, height, internal_format) ||
7962 !ValidateCompressedTexFuncData(
7963 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:177964 return error::kNoError;
7965 }
[email protected]968351b2011-12-20 08:26:517966
[email protected]7989c9e2013-01-23 06:39:267967 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:517968 LOCAL_SET_GL_ERROR(
7969 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:267970 return error::kNoError;
7971 }
7972
[email protected]02965c22013-03-09 02:40:077973 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:447974 framebuffer_state_.clear_state_dirty = true;
[email protected]968351b2011-12-20 08:26:517975 }
7976
[email protected]40d90a22013-04-09 03:39:557977 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:477978 if (!data) {
7979 zero.reset(new int8[image_size]);
7980 memset(zero.get(), 0, image_size);
7981 data = zero.get();
7982 }
[email protected]ab09b612013-03-11 22:11:517983 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:477984 glCompressedTexImage2D(
7985 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:517986 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:437987 if (error == GL_NO_ERROR) {
7988 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:497989 texture_ref, target, level, internal_format,
7990 width, height, 1, border, 0, 0, true);
[email protected]cadde4a2010-07-31 17:10:437991 }
[email protected]a93bb842010-02-16 23:03:477992 return error::kNoError;
7993}
7994
[email protected]f7a64ee2010-02-01 22:24:147995error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:357996 uint32 immediate_data_size, const cmds::CompressedTexImage2D& c) {
[email protected]b9849abf2009-11-25 19:13:197997 GLenum target = static_cast<GLenum>(c.target);
7998 GLint level = static_cast<GLint>(c.level);
7999 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8000 GLsizei width = static_cast<GLsizei>(c.width);
8001 GLsizei height = static_cast<GLsizei>(c.height);
8002 GLint border = static_cast<GLint>(c.border);
8003 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
8004 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8005 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8006 const void* data = NULL;
8007 if (data_shm_id != 0 || data_shm_offset != 0) {
8008 data = GetSharedMemoryAs<const void*>(
8009 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:468010 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:148011 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198012 }
8013 }
[email protected]a93bb842010-02-16 23:03:478014 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:198015 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:198016}
8017
[email protected]b6140d02010-05-17 14:47:168018error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
[email protected]ed9f9cd2013-02-27 21:12:358019 uint32 immediate_data_size, const cmds::CompressedTexImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:168020 GLenum target = static_cast<GLenum>(c.target);
8021 GLint level = static_cast<GLint>(c.level);
8022 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8023 GLsizei width = static_cast<GLsizei>(c.width);
8024 GLsizei height = static_cast<GLsizei>(c.height);
8025 GLint border = static_cast<GLint>(c.border);
8026 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288027 if (!bucket) {
8028 return error::kInvalidArguments;
8029 }
8030 uint32 data_size = bucket->size();
8031 GLsizei imageSize = data_size;
8032 const void* data = bucket->GetData(0, data_size);
8033 if (!data) {
8034 return error::kInvalidArguments;
8035 }
[email protected]b6140d02010-05-17 14:47:168036 return DoCompressedTexImage2D(
8037 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:288038 imageSize, data);
[email protected]b6140d02010-05-17 14:47:168039}
8040
8041error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
8042 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:358043 const cmds::CompressedTexSubImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:168044 GLenum target = static_cast<GLenum>(c.target);
8045 GLint level = static_cast<GLint>(c.level);
8046 GLint xoffset = static_cast<GLint>(c.xoffset);
8047 GLint yoffset = static_cast<GLint>(c.yoffset);
8048 GLsizei width = static_cast<GLsizei>(c.width);
8049 GLsizei height = static_cast<GLsizei>(c.height);
8050 GLenum format = static_cast<GLenum>(c.format);
8051 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288052 if (!bucket) {
8053 return error::kInvalidArguments;
8054 }
[email protected]b6140d02010-05-17 14:47:168055 uint32 data_size = bucket->size();
8056 GLsizei imageSize = data_size;
8057 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:288058 if (!data) {
8059 return error::kInvalidArguments;
8060 }
[email protected]9438b012010-06-15 22:55:058061 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518062 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:538063 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:168064 return error::kNoError;
8065 }
[email protected]9438b012010-06-15 22:55:058066 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518067 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8068 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:058069 return error::kNoError;
8070 }
[email protected]b6140d02010-05-17 14:47:168071 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518072 LOCAL_SET_GL_ERROR(
8073 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:168074 return error::kNoError;
8075 }
8076 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518077 LOCAL_SET_GL_ERROR(
8078 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:168079 return error::kNoError;
8080 }
8081 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:518082 LOCAL_SET_GL_ERROR(
8083 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:168084 return error::kNoError;
8085 }
[email protected]cadde4a2010-07-31 17:10:438086 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:168087 target, level, xoffset, yoffset, width, height, format, imageSize, data);
8088 return error::kNoError;
8089}
8090
[email protected]f7a64ee2010-02-01 22:24:148091error::Error GLES2DecoderImpl::HandleTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:358092 uint32 immediate_data_size, const cmds::TexImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:388093 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexImage2D");
[email protected]c986af502013-08-14 01:04:448094 // Set as failed for now, but if it successed, this will be set to not failed.
8095 texture_state_.tex_image_2d_failed = true;
[email protected]b9849abf2009-11-25 19:13:198096 GLenum target = static_cast<GLenum>(c.target);
8097 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:448098 // TODO(kloveless): Change TexImage2D command to use unsigned integer
8099 // for internalformat.
8100 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:198101 GLsizei width = static_cast<GLsizei>(c.width);
8102 GLsizei height = static_cast<GLsizei>(c.height);
8103 GLint border = static_cast<GLint>(c.border);
8104 GLenum format = static_cast<GLenum>(c.format);
8105 GLenum type = static_cast<GLenum>(c.type);
8106 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
8107 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:188108 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:348109 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248110 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
[email protected]3458a64a2012-04-10 17:39:348111 NULL)) {
[email protected]a76b0052010-03-05 00:33:188112 return error::kOutOfBounds;
8113 }
[email protected]b9849abf2009-11-25 19:13:198114 const void* pixels = NULL;
8115 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
8116 pixels = GetSharedMemoryAs<const void*>(
8117 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:468118 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:148119 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198120 }
8121 }
[email protected]f598f422012-12-07 08:30:038122
[email protected]c986af502013-08-14 01:04:448123 TextureManager::DoTextImage2DArguments args = {
8124 target, level, internal_format, width, height, border, format, type,
8125 pixels, pixels_size};
8126 texture_manager()->ValidateAndDoTexImage2D(
8127 &texture_state_, &state_, &framebuffer_state_, args);
[email protected]f598f422012-12-07 08:30:038128 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198129}
8130
[email protected]cadde4a2010-07-31 17:10:438131void GLES2DecoderImpl::DoCompressedTexSubImage2D(
8132 GLenum target,
8133 GLint level,
8134 GLint xoffset,
8135 GLint yoffset,
8136 GLsizei width,
8137 GLsizei height,
8138 GLenum format,
8139 GLsizei image_size,
8140 const void * data) {
[email protected]c986af502013-08-14 01:04:448141 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8142 &state_, target);
[email protected]370eaf12013-05-18 09:19:498143 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518144 LOCAL_SET_GL_ERROR(
8145 GL_INVALID_OPERATION,
8146 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438147 return;
8148 }
[email protected]370eaf12013-05-18 09:19:498149 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438150 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:528151 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078152 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518153 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528154 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438155 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:528156 return;
8157 }
8158 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:518159 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528160 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438161 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:528162 return;
8163 }
[email protected]02965c22013-03-09 02:40:078164 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528165 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518166 LOCAL_SET_GL_ERROR(
8167 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438168 return;
8169 }
[email protected]ad84a3a2012-06-08 21:42:438170
8171 if (!ValidateCompressedTexFuncData(
8172 "glCompressedTexSubImage2D", width, height, format, image_size) ||
8173 !ValidateCompressedTexSubDimensions(
8174 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:078175 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:438176 return;
8177 }
8178
8179
[email protected]0d6bfdc2011-11-02 01:32:208180 // Note: There is no need to deal with texture cleared tracking here
8181 // because the validation above means you can only get here if the level
8182 // is already a matching compressed format and in that case
8183 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:438184 glCompressedTexSubImage2D(
8185 target, level, xoffset, yoffset, width, height, format, image_size, data);
8186}
8187
[email protected]6e288612010-12-21 20:45:038188static void Clip(
8189 GLint start, GLint range, GLint sourceRange,
8190 GLint* out_start, GLint* out_range) {
8191 DCHECK(out_start);
8192 DCHECK(out_range);
8193 if (start < 0) {
8194 range += start;
8195 start = 0;
8196 }
8197 GLint end = start + range;
8198 if (end > sourceRange) {
8199 range -= end - sourceRange;
8200 }
8201 *out_start = start;
8202 *out_range = range;
8203}
8204
[email protected]cadde4a2010-07-31 17:10:438205void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:448206 GLenum target,
8207 GLint level,
8208 GLenum internal_format,
8209 GLint x,
8210 GLint y,
8211 GLsizei width,
8212 GLsizei height,
8213 GLint border) {
[email protected]09e17272012-11-30 10:30:448214 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:448215 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8216 &state_, target);
[email protected]370eaf12013-05-18 09:19:498217 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518218 LOCAL_SET_GL_ERROR(
8219 GL_INVALID_OPERATION,
8220 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438221 return;
8222 }
[email protected]370eaf12013-05-18 09:19:498223 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078224 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518225 LOCAL_SET_GL_ERROR(
8226 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:178227 }
[email protected]80eb6b52012-01-19 00:14:418228 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:188229 border != 0) {
[email protected]ab09b612013-03-11 22:11:518230 LOCAL_SET_GL_ERROR(
8231 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:188232 return;
8233 }
[email protected]17a961192014-02-14 15:20:528234 if (!texture_manager()->ValidateFormatAndTypeCombination(
8235 state_.GetErrorState(), "glCopyTexImage2D", internal_format,
8236 GL_UNSIGNED_BYTE)) {
[email protected]81375742012-06-08 00:04:008237 return;
8238 }
[email protected]f5719fb2010-08-04 18:27:188239
[email protected]9edc6b22010-12-23 02:00:268240 // Check we have compatible formats.
8241 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8242 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8243 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
8244
8245 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518246 LOCAL_SET_GL_ERROR(
8247 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268248 return;
8249 }
8250
[email protected]81375742012-06-08 00:04:008251 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518252 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008253 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:268254 "glCopyTexImage2D", "can not be used with depth or stencil textures");
8255 return;
8256 }
8257
8258 uint32 estimated_size = 0;
8259 if (!GLES2Util::ComputeImageDataSizes(
8260 width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment,
8261 &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518262 LOCAL_SET_GL_ERROR(
8263 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:268264 return;
8265 }
8266
8267 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:518268 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:008269 return;
8270 }
8271
[email protected]a0b78dc2011-11-11 10:43:108272 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
8273 return;
8274 }
8275
[email protected]ab09b612013-03-11 22:11:518276 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:278277 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038278 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:268279
[email protected]02965c22013-03-09 02:40:078280 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448281 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:468282 }
8283
[email protected]9edc6b22010-12-23 02:00:268284 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:038285 GLint copyX = 0;
8286 GLint copyY = 0;
8287 GLint copyWidth = 0;
8288 GLint copyHeight = 0;
8289 Clip(x, width, size.width(), &copyX, &copyWidth);
8290 Clip(y, height, size.height(), &copyY, &copyHeight);
8291
8292 if (copyX != x ||
8293 copyY != y ||
8294 copyWidth != width ||
8295 copyHeight != height) {
8296 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:208297 if (!ClearLevel(
[email protected]02965c22013-03-09 02:40:078298 texture->service_id(), texture->target(),
[email protected]d8e6c9242014-02-20 16:56:258299 target, level, internal_format, internal_format, GL_UNSIGNED_BYTE,
8300 width, height, texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:518301 LOCAL_SET_GL_ERROR(
8302 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:038303 return;
8304 }
[email protected]6e288612010-12-21 20:45:038305 if (copyHeight > 0 && copyWidth > 0) {
8306 GLint dx = copyX - x;
8307 GLint dy = copyY - y;
8308 GLint destX = dx;
8309 GLint destY = dy;
8310 glCopyTexSubImage2D(target, level,
8311 destX, destY, copyX, copyY,
8312 copyWidth, copyHeight);
8313 }
8314 } else {
8315 glCopyTexImage2D(target, level, internal_format,
8316 copyX, copyY, copyWidth, copyHeight, border);
8317 }
[email protected]ab09b612013-03-11 22:11:518318 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438319 if (error == GL_NO_ERROR) {
8320 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498321 texture_ref, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:208322 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:438323 }
8324}
8325
8326void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:448327 GLenum target,
8328 GLint level,
8329 GLint xoffset,
8330 GLint yoffset,
8331 GLint x,
8332 GLint y,
8333 GLsizei width,
8334 GLsizei height) {
[email protected]09e17272012-11-30 10:30:448335 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:448336 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8337 &state_, target);
[email protected]370eaf12013-05-18 09:19:498338 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518339 LOCAL_SET_GL_ERROR(
8340 GL_INVALID_OPERATION,
8341 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438342 return;
8343 }
[email protected]370eaf12013-05-18 09:19:498344 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438345 GLenum type = 0;
8346 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:078347 if (!texture->GetLevelType(target, level, &type, &format) ||
8348 !texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528349 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518350 LOCAL_SET_GL_ERROR(
8351 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438352 return;
8353 }
[email protected]85a4ac22013-05-31 01:58:478354 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518355 LOCAL_SET_GL_ERROR(
8356 GL_INVALID_OPERATION,
8357 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598358 return;
8359 }
[email protected]9edc6b22010-12-23 02:00:268360
8361 // Check we have compatible formats.
8362 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8363 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8364 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
8365
[email protected]2d3765b2012-10-03 00:31:078366 if (!channels_needed ||
8367 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518368 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438369 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268370 return;
8371 }
8372
[email protected]81375742012-06-08 00:04:008373 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518374 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008375 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438376 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:008377 return;
8378 }
8379
[email protected]a0b78dc2011-11-11 10:43:108380 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
8381 return;
8382 }
8383
[email protected]de26b3c2011-08-03 21:54:278384 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038385 gfx::Size size = GetBoundReadFrameBufferSize();
8386 GLint copyX = 0;
8387 GLint copyY = 0;
8388 GLint copyWidth = 0;
8389 GLint copyHeight = 0;
8390 Clip(x, width, size.width(), &copyX, &copyWidth);
8391 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:208392
[email protected]370eaf12013-05-18 09:19:498393 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, level)) {
[email protected]ab09b612013-03-11 22:11:518394 LOCAL_SET_GL_ERROR(
8395 GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big");
[email protected]0d6bfdc2011-11-02 01:32:208396 return;
8397 }
8398
[email protected]6e288612010-12-21 20:45:038399 if (copyX != x ||
8400 copyY != y ||
8401 copyWidth != width ||
8402 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:208403 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:038404 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:348405 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248406 width, height, format, type, state_.unpack_alignment, &pixels_size,
8407 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518408 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438409 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:038410 return;
8411 }
[email protected]40d90a22013-04-09 03:39:558412 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:038413 memset(zero.get(), 0, pixels_size);
8414 glTexSubImage2D(
8415 target, level, xoffset, yoffset, width, height,
8416 format, type, zero.get());
8417 }
[email protected]0d6bfdc2011-11-02 01:32:208418
[email protected]6e288612010-12-21 20:45:038419 if (copyHeight > 0 && copyWidth > 0) {
8420 GLint dx = copyX - x;
8421 GLint dy = copyY - y;
8422 GLint destX = xoffset + dx;
8423 GLint destY = yoffset + dy;
8424 glCopyTexSubImage2D(target, level,
8425 destX, destY, copyX, copyY,
8426 copyWidth, copyHeight);
8427 }
[email protected]cadde4a2010-07-31 17:10:438428}
8429
[email protected]f598f422012-12-07 08:30:038430bool GLES2DecoderImpl::ValidateTexSubImage2D(
8431 error::Error* error,
8432 const char* function_name,
8433 GLenum target,
8434 GLint level,
8435 GLint xoffset,
8436 GLint yoffset,
8437 GLsizei width,
8438 GLsizei height,
8439 GLenum format,
8440 GLenum type,
8441 const void * data) {
8442 (*error) = error::kNoError;
8443 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518444 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:038445 return false;
8446 }
8447 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518448 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:038449 return false;
8450 }
8451 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518452 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:038453 return false;
8454 }
[email protected]c986af502013-08-14 01:04:448455 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8456 &state_, target);
[email protected]370eaf12013-05-18 09:19:498457 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518458 LOCAL_SET_GL_ERROR(
8459 GL_INVALID_OPERATION,
8460 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:038461 return false;
[email protected]cadde4a2010-07-31 17:10:438462 }
[email protected]370eaf12013-05-18 09:19:498463 Texture* texture = texture_ref->texture();
[email protected]df6cf1ad2011-01-29 01:20:528464 GLenum current_type = 0;
8465 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078466 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518467 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:038468 GL_INVALID_OPERATION, function_name, "level does not exist.");
8469 return false;
[email protected]df6cf1ad2011-01-29 01:20:528470 }
[email protected]17a961192014-02-14 15:20:528471 if (!texture_manager()->ValidateTextureParameters(state_.GetErrorState(),
8472 function_name, format, type, internal_format, level)) {
[email protected]f598f422012-12-07 08:30:038473 return false;
[email protected]df6cf1ad2011-01-29 01:20:528474 }
8475 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:518476 LOCAL_SET_GL_ERROR(
8477 GL_INVALID_OPERATION,
8478 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:038479 return false;
[email protected]df6cf1ad2011-01-29 01:20:528480 }
[email protected]85a4ac22013-05-31 01:58:478481 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518482 LOCAL_SET_GL_ERROR(
8483 GL_INVALID_OPERATION,
8484 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598485 return false;
8486 }
[email protected]02965c22013-03-09 02:40:078487 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528488 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518489 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:038490 return false;
[email protected]cadde4a2010-07-31 17:10:438491 }
[email protected]81375742012-06-08 00:04:008492 if ((GLES2Util::GetChannelsForFormat(format) &
8493 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518494 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008495 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038496 function_name, "can not supply data for depth or stencil textures");
8497 return false;
[email protected]81375742012-06-08 00:04:008498 }
[email protected]f598f422012-12-07 08:30:038499 if (data == NULL) {
8500 (*error) = error::kOutOfBounds;
8501 return false;
8502 }
8503 return true;
8504}
[email protected]81375742012-06-08 00:04:008505
[email protected]f598f422012-12-07 08:30:038506error::Error GLES2DecoderImpl::DoTexSubImage2D(
8507 GLenum target,
8508 GLint level,
8509 GLint xoffset,
8510 GLint yoffset,
8511 GLsizei width,
8512 GLsizei height,
8513 GLenum format,
8514 GLenum type,
8515 const void * data) {
8516 error::Error error = error::kNoError;
8517 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
8518 xoffset, yoffset, width, height, format, type, data)) {
8519 return error;
8520 }
[email protected]c986af502013-08-14 01:04:448521 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8522 &state_, target);
[email protected]370eaf12013-05-18 09:19:498523 Texture* texture = texture_ref->texture();
[email protected]4502e6492011-12-14 19:39:158524 GLsizei tex_width = 0;
8525 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:078526 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:158527 DCHECK(ok);
8528 if (xoffset != 0 || yoffset != 0 ||
8529 width != tex_width || height != tex_height) {
[email protected]370eaf12013-05-18 09:19:498530 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
8531 target, level)) {
[email protected]ab09b612013-03-11 22:11:518532 LOCAL_SET_GL_ERROR(
8533 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:038534 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:308535 }
[email protected]c986af502013-08-14 01:04:448536 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:158537 glTexSubImage2D(
8538 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:038539 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:208540 }
[email protected]4502e6492011-12-14 19:39:158541
[email protected]345ba902013-11-14 21:39:008542 if (!texture_state_.texsubimage2d_faster_than_teximage2d &&
[email protected]c986af502013-08-14 01:04:448543 !texture->IsImmutable()) {
8544 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]d8e6c9242014-02-20 16:56:258545 GLenum internal_format;
8546 GLenum tex_type;
8547 texture->GetLevelType(target, level, &tex_type, &internal_format);
8548 // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need
8549 // to look it up.
[email protected]8f1d2aa2013-05-10 23:45:388550 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:258551 target, level, internal_format, width, height, 0, format, type, data);
[email protected]4502e6492011-12-14 19:39:158552 } else {
[email protected]c986af502013-08-14 01:04:448553 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:158554 glTexSubImage2D(
8555 target, level, xoffset, yoffset, width, height, format, type, data);
8556 }
[email protected]370eaf12013-05-18 09:19:498557 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
[email protected]f598f422012-12-07 08:30:038558 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:438559}
8560
[email protected]b493ee622011-04-13 23:52:008561error::Error GLES2DecoderImpl::HandleTexSubImage2D(
[email protected]ed9f9cd2013-02-27 21:12:358562 uint32 immediate_data_size, const cmds::TexSubImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:388563 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D");
[email protected]b493ee622011-04-13 23:52:008564 GLboolean internal = static_cast<GLboolean>(c.internal);
[email protected]c986af502013-08-14 01:04:448565 if (internal == GL_TRUE && texture_state_.tex_image_2d_failed)
[email protected]b493ee622011-04-13 23:52:008566 return error::kNoError;
8567
8568 GLenum target = static_cast<GLenum>(c.target);
8569 GLint level = static_cast<GLint>(c.level);
8570 GLint xoffset = static_cast<GLint>(c.xoffset);
8571 GLint yoffset = static_cast<GLint>(c.yoffset);
8572 GLsizei width = static_cast<GLsizei>(c.width);
8573 GLsizei height = static_cast<GLsizei>(c.height);
8574 GLenum format = static_cast<GLenum>(c.format);
8575 GLenum type = static_cast<GLenum>(c.type);
8576 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348577 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248578 width, height, format, type, state_.unpack_alignment, &data_size,
8579 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008580 return error::kOutOfBounds;
8581 }
8582 const void* pixels = GetSharedMemoryAs<const void*>(
8583 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:038584 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008585 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008586}
8587
[email protected]f7a64ee2010-02-01 22:24:148588error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
[email protected]ed9f9cd2013-02-27 21:12:358589 uint32 immediate_data_size, const cmds::GetVertexAttribPointerv& c) {
[email protected]8bf5a3e2010-01-29 04:21:368590 GLuint index = static_cast<GLuint>(c.index);
8591 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:358592 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:258593 Result* result = GetSharedMemoryAs<Result*>(
8594 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:368595 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:148596 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:368597 }
[email protected]07d0cc82010-02-17 04:51:408598 // Check that the client initialized the result.
8599 if (result->size != 0) {
8600 return error::kInvalidArguments;
8601 }
[email protected]9438b012010-06-15 22:55:058602 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:518603 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8604 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:148605 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368606 }
[email protected]3916c97e2010-02-25 03:20:508607 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:518608 LOCAL_SET_GL_ERROR(
8609 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:148610 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368611 }
[email protected]0bfd9882010-02-05 23:02:258612 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:088613 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:358614 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:148615 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328616}
8617
[email protected]f7b85372010-02-03 01:11:378618bool GLES2DecoderImpl::GetUniformSetup(
[email protected]df37b9932013-03-08 05:21:428619 GLuint program_id, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:378620 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:128621 error::Error* error, GLint* real_location,
8622 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:108623 DCHECK(error);
8624 DCHECK(service_id);
8625 DCHECK(result_pointer);
8626 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:128627 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:378628 *error = error::kNoError;
8629 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:258630 SizedResult<GLint>* result;
8631 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8632 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
8633 if (!result) {
[email protected]f7b85372010-02-03 01:11:378634 *error = error::kOutOfBounds;
8635 return false;
8636 }
[email protected]0bfd9882010-02-05 23:02:258637 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:378638 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:258639 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:428640 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
8641 if (!program) {
[email protected]ae51d192010-04-27 00:48:038642 return false;
8643 }
[email protected]df37b9932013-03-08 05:21:428644 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:378645 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:518646 LOCAL_SET_GL_ERROR(
8647 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:378648 return false;
8649 }
[email protected]df37b9932013-03-08 05:21:428650 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:368651 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:358652 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:428653 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:128654 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:368655 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:378656 // No such location.
[email protected]ab09b612013-03-11 22:11:518657 LOCAL_SET_GL_ERROR(
8658 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:378659 return false;
8660 }
[email protected]43c2f1f2011-03-25 18:35:368661 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:508662 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:378663 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:518664 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:378665 return false;
8666 }
[email protected]0bfd9882010-02-05 23:02:258667 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8668 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
8669 if (!result) {
[email protected]f7b85372010-02-03 01:11:378670 *error = error::kOutOfBounds;
8671 return false;
8672 }
[email protected]0bfd9882010-02-05 23:02:258673 result->size = size;
[email protected]939e7362010-05-13 20:49:108674 *result_type = type;
[email protected]f7b85372010-02-03 01:11:378675 return true;
8676}
8677
[email protected]f7a64ee2010-02-01 22:24:148678error::Error GLES2DecoderImpl::HandleGetUniformiv(
[email protected]ed9f9cd2013-02-27 21:12:358679 uint32 immediate_data_size, const cmds::GetUniformiv& c) {
[email protected]f7b85372010-02-03 01:11:378680 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338681 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378682 GLuint service_id;
[email protected]939e7362010-05-13 20:49:108683 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:128684 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378685 Error error;
[email protected]0bfd9882010-02-05 23:02:258686 void* result;
[email protected]f7b85372010-02-03 01:11:378687 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128688 program, fake_location, c.params_shm_id, c.params_shm_offset,
8689 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:258690 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:128691 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:358692 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:378693 }
8694 return error;
[email protected]96449d2c2009-11-25 00:01:328695}
8696
[email protected]f7a64ee2010-02-01 22:24:148697error::Error GLES2DecoderImpl::HandleGetUniformfv(
[email protected]ed9f9cd2013-02-27 21:12:358698 uint32 immediate_data_size, const cmds::GetUniformfv& c) {
[email protected]f7b85372010-02-03 01:11:378699 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338700 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378701 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:128702 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378703 Error error;
[email protected]ed9f9cd2013-02-27 21:12:358704 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:108705 Result* result;
8706 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:378707 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128708 program, fake_location, c.params_shm_id, c.params_shm_offset,
8709 &error, &real_location, &service_id,
8710 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:108711 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
8712 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
8713 GLsizei num_values = result->GetNumResults();
[email protected]40d90a22013-04-09 03:39:558714 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:128715 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:108716 GLfloat* dst = result->GetData();
8717 for (GLsizei ii = 0; ii < num_values; ++ii) {
8718 dst[ii] = (temp[ii] != 0);
8719 }
8720 } else {
[email protected]1b0a6752012-02-22 03:44:128721 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:108722 }
[email protected]f7b85372010-02-03 01:11:378723 }
8724 return error;
[email protected]96449d2c2009-11-25 00:01:328725}
8726
[email protected]f7a64ee2010-02-01 22:24:148727error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
[email protected]ed9f9cd2013-02-27 21:12:358728 uint32 immediate_data_size, const cmds::GetShaderPrecisionFormat& c) {
[email protected]0bfd9882010-02-05 23:02:258729 GLenum shader_type = static_cast<GLenum>(c.shadertype);
8730 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:358731 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:258732 Result* result = GetSharedMemoryAs<Result*>(
8733 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8734 if (!result) {
8735 return error::kOutOfBounds;
8736 }
[email protected]07d0cc82010-02-17 04:51:408737 // Check that the client initialized the result.
8738 if (result->success != 0) {
8739 return error::kInvalidArguments;
8740 }
[email protected]9438b012010-06-15 22:55:058741 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:518742 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538743 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:298744 return error::kNoError;
8745 }
[email protected]9438b012010-06-15 22:55:058746 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:518747 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538748 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:298749 return error::kNoError;
8750 }
8751
8752 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:408753
[email protected]46c86752013-05-21 05:08:398754 GLint range[2] = { 0, 0 };
[email protected]d8bc3ec2013-03-07 06:28:408755 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:218756 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:408757
8758 result->min_range = range[0];
8759 result->max_range = range[1];
8760 result->precision = precision;
8761
[email protected]f7a64ee2010-02-01 22:24:148762 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328763}
8764
[email protected]f7a64ee2010-02-01 22:24:148765error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
[email protected]ed9f9cd2013-02-27 21:12:358766 uint32 immediate_data_size, const cmds::GetAttachedShaders& c) {
[email protected]0bfd9882010-02-05 23:02:258767 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:428768 GLuint program_id = static_cast<GLuint>(c.program);
8769 Program* program = GetProgramInfoNotShader(
8770 program_id, "glGetAttachedShaders");
8771 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258772 return error::kNoError;
8773 }
[email protected]ed9f9cd2013-02-27 21:12:358774 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:258775 uint32 max_count = Result::ComputeMaxResults(result_size);
8776 Result* result = GetSharedMemoryAs<Result*>(
8777 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
8778 if (!result) {
8779 return error::kOutOfBounds;
8780 }
[email protected]07d0cc82010-02-17 04:51:408781 // Check that the client initialized the result.
8782 if (result->size != 0) {
8783 return error::kInvalidArguments;
8784 }
[email protected]0bfd9882010-02-05 23:02:258785 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:038786 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:428787 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:258788 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:038789 if (!shader_manager()->GetClientId(result->GetData()[ii],
8790 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:258791 NOTREACHED();
8792 return error::kGenericError;
8793 }
8794 }
8795 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:148796 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328797}
8798
[email protected]f7a64ee2010-02-01 22:24:148799error::Error GLES2DecoderImpl::HandleGetActiveUniform(
[email protected]ed9f9cd2013-02-27 21:12:358800 uint32 immediate_data_size, const cmds::GetActiveUniform& c) {
[email protected]df37b9932013-03-08 05:21:428801 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:258802 GLuint index = c.index;
8803 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:358804 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:258805 Result* result = GetSharedMemoryAs<Result*>(
8806 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8807 if (!result) {
8808 return error::kOutOfBounds;
8809 }
[email protected]07d0cc82010-02-17 04:51:408810 // Check that the client initialized the result.
8811 if (result->success != 0) {
8812 return error::kInvalidArguments;
8813 }
[email protected]df37b9932013-03-08 05:21:428814 Program* program = GetProgramInfoNotShader(
8815 program_id, "glGetActiveUniform");
8816 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258817 return error::kNoError;
8818 }
[email protected]ed9f9cd2013-02-27 21:12:358819 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:428820 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:258821 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:518822 LOCAL_SET_GL_ERROR(
8823 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258824 return error::kNoError;
8825 }
8826 result->success = 1; // true.
8827 result->size = uniform_info->size;
8828 result->type = uniform_info->type;
8829 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298830 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148831 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328832}
8833
[email protected]f7a64ee2010-02-01 22:24:148834error::Error GLES2DecoderImpl::HandleGetActiveAttrib(
[email protected]ed9f9cd2013-02-27 21:12:358835 uint32 immediate_data_size, const cmds::GetActiveAttrib& c) {
[email protected]df37b9932013-03-08 05:21:428836 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:258837 GLuint index = c.index;
8838 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:358839 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:258840 Result* result = GetSharedMemoryAs<Result*>(
8841 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8842 if (!result) {
8843 return error::kOutOfBounds;
8844 }
[email protected]07d0cc82010-02-17 04:51:408845 // Check that the client initialized the result.
8846 if (result->success != 0) {
8847 return error::kInvalidArguments;
8848 }
[email protected]df37b9932013-03-08 05:21:428849 Program* program = GetProgramInfoNotShader(
8850 program_id, "glGetActiveAttrib");
8851 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258852 return error::kNoError;
8853 }
[email protected]ed9f9cd2013-02-27 21:12:358854 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:428855 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:258856 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:518857 LOCAL_SET_GL_ERROR(
8858 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258859 return error::kNoError;
8860 }
8861 result->success = 1; // true.
8862 result->size = attrib_info->size;
8863 result->type = attrib_info->type;
8864 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298865 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148866 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328867}
8868
[email protected]b273e432010-04-12 17:23:588869error::Error GLES2DecoderImpl::HandleShaderBinary(
[email protected]ed9f9cd2013-02-27 21:12:358870 uint32 immediate_data_size, const cmds::ShaderBinary& c) {
[email protected]b273e432010-04-12 17:23:588871#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:518872 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:588873 return error::kNoError;
8874#else
8875 GLsizei n = static_cast<GLsizei>(c.n);
8876 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:518877 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:588878 return error::kNoError;
8879 }
8880 GLsizei length = static_cast<GLsizei>(c.length);
8881 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:518882 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:588883 return error::kNoError;
8884 }
8885 uint32 data_size;
8886 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
8887 return error::kOutOfBounds;
8888 }
8889 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
8890 c.shaders_shm_id, c.shaders_shm_offset, data_size);
8891 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
8892 const void* binary = GetSharedMemoryAs<const void*>(
8893 c.binary_shm_id, c.binary_shm_offset, length);
8894 if (shaders == NULL || binary == NULL) {
8895 return error::kOutOfBounds;
8896 }
8897 scoped_array<GLuint> service_ids(new GLuint[n]);
8898 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:428899 Shader* shader = GetShader(shaders[ii]);
8900 if (!shader) {
[email protected]ab09b612013-03-11 22:11:518901 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:588902 return error::kNoError;
8903 }
[email protected]df37b9932013-03-08 05:21:428904 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:588905 }
8906 // TODO(gman): call glShaderBinary
8907 return error::kNoError;
8908#endif
8909}
8910
[email protected]6d792ee12013-05-15 00:40:568911void GLES2DecoderImpl::DoSwapBuffers() {
[email protected]64ace852011-05-19 21:49:498912 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:088913
[email protected]64ace852011-05-19 21:49:498914 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:428915 // TRACE_EVENT for gpu tests:
8916 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:428917 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:428918 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
8919 "width", (is_offscreen ? offscreen_size_.width() :
8920 surface_->GetSize().width()));
[email protected]6d792ee12013-05-15 00:40:568921 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
[email protected]64ace852011-05-19 21:49:498922 "offscreen", is_offscreen,
8923 "frame", this_frame_number);
[email protected]b2e92592014-01-10 15:47:158924 {
8925 TRACE_EVENT_SYNTHETIC_DELAY("gpu.SwapBuffers");
8926 }
8927
[email protected]8f9b8dd2013-09-12 18:05:138928 bool is_tracing;
8929 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
8930 &is_tracing);
8931 if (is_tracing) {
8932 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
8933 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
8934 is_offscreen ? offscreen_size_ : surface_->GetSize());
8935 }
8936
[email protected]6217d392010-03-25 22:08:358937 // If offscreen then don't actually SwapBuffers to the display. Just copy
8938 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:498939 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:318940 TRACE_EVENT2("gpu", "Offscreen",
8941 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:538942 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
8943 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
8944 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
8945 // fix this.
[email protected]62e155e2012-10-23 22:43:158946 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:538947 offscreen_saved_frame_buffer_->Create();
8948 glFinish();
8949 }
8950
8951 // Allocate the offscreen saved color texture.
8952 DCHECK(offscreen_saved_color_format_);
8953 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:098954 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:538955
8956 offscreen_saved_frame_buffer_->AttachRenderTexture(
8957 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:058958 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
8959 if (offscreen_saved_frame_buffer_->CheckStatus() !=
8960 GL_FRAMEBUFFER_COMPLETE) {
8961 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
8962 << "because offscreen saved FBO was incomplete.";
[email protected]6d792ee12013-05-15 00:40:568963 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
8964 return;
[email protected]f0cfe752013-01-14 01:09:058965 }
[email protected]1fb8c482011-08-31 01:01:538966
[email protected]f0cfe752013-01-14 01:09:058967 // Clear the offscreen color texture.
8968 // TODO(piman): Is this still necessary?
8969 {
8970 ScopedFrameBufferBinder binder(this,
8971 offscreen_saved_frame_buffer_->id());
8972 glClearColor(0, 0, 0, 0);
8973 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
8974 glDisable(GL_SCISSOR_TEST);
8975 glClear(GL_COLOR_BUFFER_BIT);
8976 RestoreClearState();
8977 }
[email protected]1fb8c482011-08-31 01:01:538978 }
8979
8980 UpdateParentTextureInfo();
8981 }
8982
[email protected]f0cfe752013-01-14 01:09:058983 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
[email protected]6d792ee12013-05-15 00:40:568984 return;
[email protected]ab09b612013-03-11 22:11:518985 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:308986 "GLES2DecoderImpl::DoSwapBuffers", GetErrorState());
[email protected]6217d392010-03-25 22:08:358987
[email protected]34ff8b0c2010-10-01 20:06:028988 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:138989 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:278990 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]b86b14982010-10-11 18:45:488991 } else {
[email protected]069944672012-04-25 20:52:238992 ScopedFrameBufferBinder binder(this,
8993 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:138994
[email protected]069944672012-04-25 20:52:238995 if (offscreen_target_buffer_preserved_) {
8996 // Copy the target frame buffer to the saved offscreen texture.
8997 offscreen_saved_color_texture_->Copy(
8998 offscreen_saved_color_texture_->size(),
8999 offscreen_saved_color_format_);
9000 } else {
9001 // Flip the textures in the parent context via the texture manager.
9002 if (!!offscreen_saved_color_texture_info_.get())
[email protected]370eaf12013-05-18 09:19:499003 offscreen_saved_color_texture_info_->texture()->
[email protected]069944672012-04-25 20:52:239004 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:569005
[email protected]069944672012-04-25 20:52:239006 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
9007 offscreen_target_frame_buffer_->AttachRenderTexture(
9008 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:489009 }
[email protected]069944672012-04-25 20:52:239010
9011 // Ensure the side effects of the copy are visible to the parent
9012 // context. There is no need to do this for ANGLE because it uses a
9013 // single D3D device for all contexts.
[email protected]f42f05b2013-11-15 21:46:189014 if (!feature_info_->feature_flags().is_angle)
[email protected]069944672012-04-25 20:52:239015 glFlush();
[email protected]0c8c9d22010-06-25 17:36:399016 }
[email protected]6217d392010-03-25 22:08:359017 } else {
[email protected]f62a5ab2011-05-23 20:34:159018 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:019019 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]6d792ee12013-05-15 00:40:569020 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]d0498742010-09-20 20:27:019021 }
[email protected]6217d392010-03-25 22:08:359022 }
[email protected]6217d392010-03-25 22:08:359023}
9024
[email protected]d4239852011-08-12 04:51:229025error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359026 uint32 immediate_data_size, const cmds::EnableFeatureCHROMIUM& c) {
[email protected]b1d2dcb2010-05-17 19:24:189027 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289028 if (!bucket || bucket->size() == 0) {
9029 return error::kInvalidArguments;
9030 }
[email protected]ed9f9cd2013-02-27 21:12:359031 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:189032 Result* result = GetSharedMemoryAs<Result*>(
9033 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9034 if (!result) {
9035 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:109036 }
[email protected]b1d2dcb2010-05-17 19:24:189037 // Check that the client initialized the result.
9038 if (*result != 0) {
9039 return error::kInvalidArguments;
9040 }
9041 std::string feature_str;
9042 if (!bucket->GetAsString(&feature_str)) {
9043 return error::kInvalidArguments;
9044 }
9045
9046 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:229047 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:189048 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:229049 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
[email protected]8fbedc02010-11-18 18:43:409050 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
9051 // TODO(gman): decide how to remove the need for this const_cast.
9052 // I could make validators_ non const but that seems bad as this is the only
9053 // place it is needed. I could make some special friend class of validators
9054 // just to allow this to set them. That seems silly. I could refactor this
9055 // code to use the extension mechanism or the initialization attributes to
9056 // turn this feature on. Given that the only real point of this is to make
9057 // the conformance tests pass and given that there is lots of real work that
9058 // needs to be done it seems like refactoring for one to one of those
9059 // methods is a very low priority.
9060 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:049061 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
9062 force_webgl_glsl_validation_ = true;
9063 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:189064 } else {
9065 return error::kNoError;
9066 }
9067
9068 *result = 1; // true.
9069 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:109070}
9071
[email protected]c2f8c8402010-12-06 18:07:249072error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
9073 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:359074 const cmds::GetRequestableExtensionsCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:249075 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:359076 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]956aec52013-09-05 15:41:199077 info->Initialize(disallowed_features_);
[email protected]c2f8c8402010-12-06 18:07:249078 bucket->SetFromString(info->extensions().c_str());
9079 return error::kNoError;
9080}
9081
9082error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359083 uint32 immediate_data_size, const cmds::RequestExtensionCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:249084 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289085 if (!bucket || bucket->size() == 0) {
9086 return error::kInvalidArguments;
9087 }
[email protected]c2f8c8402010-12-06 18:07:249088 std::string feature_str;
9089 if (!bucket->GetAsString(&feature_str)) {
9090 return error::kInvalidArguments;
9091 }
9092
[email protected]4b7eba92013-01-08 02:23:569093 bool desire_webgl_glsl_validation =
9094 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
9095 bool desire_standard_derivatives = false;
[email protected]70dc60932013-06-04 03:33:499096 bool desire_frag_depth = false;
[email protected]aff39ac82013-06-08 04:53:139097 bool desire_draw_buffers = false;
[email protected]4b7eba92013-01-08 02:23:569098 if (force_webgl_glsl_validation_) {
9099 desire_standard_derivatives =
9100 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]70dc60932013-06-04 03:33:499101 desire_frag_depth =
9102 feature_str.find("GL_EXT_frag_depth") != std::string::npos;
[email protected]aff39ac82013-06-08 04:53:139103 desire_draw_buffers =
9104 feature_str.find("GL_EXT_draw_buffers") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:049105 }
9106
[email protected]4b7eba92013-01-08 02:23:569107 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
[email protected]70dc60932013-06-04 03:33:499108 desire_standard_derivatives != derivatives_explicitly_enabled_ ||
[email protected]aff39ac82013-06-08 04:53:139109 desire_frag_depth != frag_depth_explicitly_enabled_ ||
9110 desire_draw_buffers != draw_buffers_explicitly_enabled_) {
[email protected]70dc60932013-06-04 03:33:499111 force_webgl_glsl_validation_ |= desire_webgl_glsl_validation;
9112 derivatives_explicitly_enabled_ |= desire_standard_derivatives;
9113 frag_depth_explicitly_enabled_ |= desire_frag_depth;
[email protected]aff39ac82013-06-08 04:53:139114 draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
[email protected]c2f8c8402010-12-06 18:07:249115 InitializeShaderTranslator();
9116 }
9117
[email protected]302ce6d2011-07-07 23:28:119118 UpdateCapabilities();
9119
[email protected]c2f8c8402010-12-06 18:07:249120 return error::kNoError;
9121}
9122
[email protected]372e0412011-06-28 16:08:569123error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359124 uint32 immediate_data_size, const cmds::GetMultipleIntegervCHROMIUM& c) {
[email protected]372e0412011-06-28 16:08:569125 GLuint count = c.count;
9126 uint32 pnames_size;
9127 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
9128 return error::kOutOfBounds;
9129 }
9130 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>(
9131 c.pnames_shm_id, c.pnames_shm_offset, pnames_size);
9132 if (pnames == NULL) {
9133 return error::kOutOfBounds;
9134 }
9135
9136 // We have to copy them since we use them twice so the client
9137 // can't change them between the time we validate them and the time we use
9138 // them.
[email protected]40d90a22013-04-09 03:39:559139 scoped_ptr<GLenum[]> enums(new GLenum[count]);
[email protected]372e0412011-06-28 16:08:569140 memcpy(enums.get(), pnames, pnames_size);
9141
9142 // Count up the space needed for the result.
9143 uint32 num_results = 0;
9144 for (GLuint ii = 0; ii < count; ++ii) {
9145 uint32 num = util_.GLGetNumValuesReturned(enums[ii]);
9146 if (num == 0) {
[email protected]ab09b612013-03-11 22:11:519147 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]caa13ed2014-02-17 11:29:209148 "glGetMultipleCHROMIUM", enums[ii], "pname");
[email protected]372e0412011-06-28 16:08:569149 return error::kNoError;
9150 }
9151 // Num will never be more than 4.
9152 DCHECK_LE(num, 4u);
[email protected]3aad1a32012-09-07 20:54:479153 if (!SafeAddUint32(num_results, num, &num_results)) {
[email protected]372e0412011-06-28 16:08:569154 return error::kOutOfBounds;
9155 }
9156 }
9157
9158 uint32 result_size = 0;
9159 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) {
9160 return error::kOutOfBounds;
9161 }
9162
9163 if (result_size != static_cast<uint32>(c.size)) {
[email protected]ab09b612013-03-11 22:11:519164 LOCAL_SET_GL_ERROR(
9165 GL_INVALID_VALUE,
[email protected]caa13ed2014-02-17 11:29:209166 "glGetMultipleCHROMIUM", "bad size GL_INVALID_VALUE");
[email protected]372e0412011-06-28 16:08:569167 return error::kNoError;
9168 }
9169
9170 GLint* results = GetSharedMemoryAs<GLint*>(
9171 c.results_shm_id, c.results_shm_offset, result_size);
9172 if (results == NULL) {
9173 return error::kOutOfBounds;
9174 }
9175
9176 // Check the results have been cleared in case the context was lost.
9177 for (uint32 ii = 0; ii < num_results; ++ii) {
9178 if (results[ii]) {
9179 return error::kInvalidArguments;
9180 }
9181 }
9182
9183 // Get each result.
9184 GLint* start = results;
9185 for (GLuint ii = 0; ii < count; ++ii) {
9186 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:269187 if (!state_.GetStateAsGLint(enums[ii], results, &num_written) &&
[email protected]f63b1232012-10-31 07:03:539188 !GetHelper(enums[ii], results, &num_written)) {
[email protected]b0ce0982013-05-13 18:51:489189 DoGetIntegerv(enums[ii], results);
[email protected]372e0412011-06-28 16:08:569190 }
9191 results += num_written;
9192 }
9193
9194 // Just to verify. Should this be a DCHECK?
9195 if (static_cast<uint32>(results - start) != num_results) {
9196 return error::kOutOfBounds;
9197 }
9198
9199 return error::kNoError;
9200}
9201
[email protected]2318d342011-07-11 22:27:429202error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359203 uint32 immediate_data_size, const cmds::GetProgramInfoCHROMIUM& c) {
[email protected]df37b9932013-03-08 05:21:429204 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:429205 uint32 bucket_id = c.bucket_id;
9206 Bucket* bucket = CreateBucket(bucket_id);
9207 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:429208 Program* program = NULL;
9209 program = GetProgram(program_id);
9210 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:469211 return error::kNoError;
[email protected]2318d342011-07-11 22:27:429212 }
[email protected]df37b9932013-03-08 05:21:429213 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:429214 return error::kNoError;
9215}
9216
[email protected]38d139d2011-07-14 00:38:439217error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
9218 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:439219 case GL_NO_ERROR:
9220 // TODO(kbr): improve the precision of the error code in this case.
9221 // Consider delegating to context for error code if MakeCurrent fails.
9222 return error::kUnknown;
9223 case GL_GUILTY_CONTEXT_RESET_ARB:
9224 return error::kGuilty;
9225 case GL_INNOCENT_CONTEXT_RESET_ARB:
9226 return error::kInnocent;
9227 case GL_UNKNOWN_CONTEXT_RESET_ARB:
9228 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:439229 }
9230
9231 NOTREACHED();
9232 return error::kUnknown;
9233}
9234
9235bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:099236 if (reset_status_ != GL_NO_ERROR) {
9237 return true;
9238 }
[email protected]706b69f2012-07-27 04:59:309239 if (context_->WasAllocatedUsingRobustnessExtension()) {
9240 GLenum status = GL_NO_ERROR;
9241 if (has_robustness_extension_)
9242 status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:439243 if (status != GL_NO_ERROR) {
9244 // The graphics card was reset. Signal a lost context to the application.
9245 reset_status_ = status;
[email protected]93a7d98f2013-07-11 00:04:229246 reset_by_robustness_extension_ = true;
[email protected]38d139d2011-07-14 00:38:439247 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:099248 << " context lost via ARB/EXT_robustness. Reset status = "
9249 << GLES2Util::GetStringEnum(status);
[email protected]38d139d2011-07-14 00:38:439250 return true;
9251 }
9252 }
9253 return false;
9254}
9255
[email protected]93a7d98f2013-07-11 00:04:229256bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() {
9257 return WasContextLost() && reset_by_robustness_extension_;
9258}
9259
[email protected]c4485aad62012-12-17 10:19:099260void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
9261 // Only loses the context once.
9262 if (reset_status_ != GL_NO_ERROR) {
9263 return;
9264 }
9265
9266 // Marks this context as lost.
9267 reset_status_ = reset_status;
9268 current_decoder_error_ = error::kLostContext;
[email protected]c4485aad62012-12-17 10:19:099269}
9270
9271error::Error GLES2DecoderImpl::HandleLoseContextCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359272 uint32 immediate_data_size, const cmds::LoseContextCHROMIUM& c) {
[email protected]c4485aad62012-12-17 10:19:099273 GLenum current = static_cast<GLenum>(c.current);
9274 GLenum other = static_cast<GLenum>(c.other);
9275 if (!validators_->reset_status.IsValid(current)) {
[email protected]ab09b612013-03-11 22:11:519276 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9277 "glLoseContextCHROMIUM", current, "current");
[email protected]c4485aad62012-12-17 10:19:099278 }
9279 if (!validators_->reset_status.IsValid(other)) {
[email protected]ab09b612013-03-11 22:11:519280 LOCAL_SET_GL_ERROR_INVALID_ENUM("glLoseContextCHROMIUM", other, "other");
[email protected]c4485aad62012-12-17 10:19:099281 }
9282 group_->LoseContexts(other);
9283 reset_status_ = current;
9284 current_decoder_error_ = error::kLostContext;
9285 return error::kLostContext;
9286}
9287
[email protected]b096d032013-03-08 03:08:019288error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
9289 uint32 immediate_data_size, const cmds::InsertSyncPointCHROMIUM& c) {
9290 return error::kUnknownCommand;
9291}
9292
[email protected]840a7e462013-02-27 01:29:519293error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359294 uint32 immediate_data_size, const cmds::WaitSyncPointCHROMIUM& c) {
[email protected]840a7e462013-02-27 01:29:519295 if (wait_sync_point_callback_.is_null())
9296 return error::kNoError;
9297
9298 return wait_sync_point_callback_.Run(c.sync_point) ?
9299 error::kNoError : error::kDeferCommandUntilLater;
9300}
9301
[email protected]5dfc457b2013-12-13 11:13:079302error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM(
9303 uint32 immediate_data_size, const cmds::DiscardBackbufferCHROMIUM& c) {
9304 if (surface_->DeferDraws())
9305 return error::kDeferCommandUntilLater;
9306 if (!surface_->SetBackbufferAllocation(false))
9307 return error::kLostContext;
9308 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
9309 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
9310 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
9311 return error::kNoError;
9312}
9313
[email protected]882ba1e22012-03-08 19:02:539314bool GLES2DecoderImpl::GenQueriesEXTHelper(
9315 GLsizei n, const GLuint* client_ids) {
9316 for (GLsizei ii = 0; ii < n; ++ii) {
9317 if (query_manager_->GetQuery(client_ids[ii])) {
9318 return false;
9319 }
9320 }
[email protected]c45f1972012-03-14 07:27:369321 // NOTE: We don't generate Query objects here. Only in BeginQueryEXT
[email protected]882ba1e22012-03-08 19:02:539322 return true;
9323}
9324
9325void GLES2DecoderImpl::DeleteQueriesEXTHelper(
9326 GLsizei n, const GLuint* client_ids) {
9327 for (GLsizei ii = 0; ii < n; ++ii) {
9328 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
9329 if (query && !query->IsDeleted()) {
[email protected]8ebd46c2014-01-08 12:06:139330 ContextState::QueryMap::iterator it =
9331 state_.current_queries.find(query->target());
9332 if (it != state_.current_queries.end())
9333 state_.current_queries.erase(it);
9334
[email protected]c45f1972012-03-14 07:27:369335 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:539336 query_manager_->RemoveQuery(client_ids[ii]);
9337 }
9338 }
9339}
9340
[email protected]22e3f552012-03-13 01:54:199341bool GLES2DecoderImpl::ProcessPendingQueries() {
9342 if (query_manager_.get() == NULL) {
9343 return false;
9344 }
[email protected]c45f1972012-03-14 07:27:369345 if (!query_manager_->ProcessPendingQueries()) {
[email protected]22e3f552012-03-13 01:54:199346 current_decoder_error_ = error::kOutOfBounds;
9347 }
9348 return query_manager_->HavePendingQueries();
9349}
9350
[email protected]5a36dc132013-07-23 23:17:559351// Note that if there are no pending readpixels right now,
9352// this function will call the callback immediately.
9353void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) {
9354 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) {
9355 pending_readpixel_fences_.back()->callbacks.push_back(callback);
9356 } else {
9357 callback.Run();
9358 }
9359}
9360
9361void GLES2DecoderImpl::ProcessPendingReadPixels() {
9362 while (!pending_readpixel_fences_.empty() &&
9363 pending_readpixel_fences_.front()->fence->HasCompleted()) {
9364 std::vector<base::Closure> callbacks =
9365 pending_readpixel_fences_.front()->callbacks;
9366 pending_readpixel_fences_.pop();
9367 for (size_t i = 0; i < callbacks.size(); i++) {
9368 callbacks[i].Run();
9369 }
9370 }
9371}
9372
[email protected]2b1767cf2013-03-16 09:25:059373bool GLES2DecoderImpl::HasMoreIdleWork() {
[email protected]5a36dc132013-07-23 23:17:559374 return !pending_readpixel_fences_.empty() ||
9375 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059376}
9377
9378void GLES2DecoderImpl::PerformIdleWork() {
[email protected]5a36dc132013-07-23 23:17:559379 ProcessPendingReadPixels();
[email protected]b68b100752013-06-05 08:34:489380 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
[email protected]2b1767cf2013-03-16 09:25:059381 return;
[email protected]b68b100752013-06-05 08:34:489382 async_pixel_transfer_manager_->ProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059383 ProcessFinishedAsyncTransfers();
9384}
9385
[email protected]882ba1e22012-03-08 19:02:539386error::Error GLES2DecoderImpl::HandleBeginQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359387 uint32 immediate_data_size, const cmds::BeginQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539388 GLenum target = static_cast<GLenum>(c.target);
9389 GLuint client_id = static_cast<GLuint>(c.id);
9390 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
9391 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
9392
[email protected]c45f1972012-03-14 07:27:369393 switch (target) {
9394 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:559395 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]5537605d2013-08-27 05:22:319396 case GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM:
9397 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:009398 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:369399 break;
9400 default:
[email protected]62e155e2012-10-23 22:43:159401 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:519402 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:009403 GL_INVALID_OPERATION, "glBeginQueryEXT",
9404 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:369405 return error::kNoError;
9406 }
9407 break;
[email protected]882ba1e22012-03-08 19:02:539408 }
9409
[email protected]8ebd46c2014-01-08 12:06:139410 if (state_.current_queries.find(target) != state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:519411 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439412 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:539413 return error::kNoError;
9414 }
9415
9416 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:519417 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:539418 return error::kNoError;
9419 }
9420
9421 QueryManager::Query* query = query_manager_->GetQuery(client_id);
9422 if (!query) {
[email protected]c45f1972012-03-14 07:27:369423 // TODO(gman): Decide if we need this check.
9424 //
[email protected]882ba1e22012-03-08 19:02:539425 // Checks id was made by glGenQueries
[email protected]c45f1972012-03-14 07:27:369426 //
9427 // From the POV of OpenGL ES 2.0 you need to call glGenQueriesEXT
9428 // for all Query ids but from the POV of the command buffer service maybe
9429 // you don't.
9430 //
9431 // The client can enforce this. I don't think the service cares.
9432 //
9433 // IdAllocatorInterface* id_allocator =
9434 // group_->GetIdAllocator(id_namespaces::kQueries);
9435 // if (!id_allocator->InUse(client_id)) {
[email protected]ab09b612013-03-11 22:11:519436 // LOCAL_SET_GL_ERROR(
9437 // GL_INVALID_OPERATION,
9438 // "glBeginQueryEXT", "id not made by glGenQueriesEXT");
[email protected]c45f1972012-03-14 07:27:369439 // return error::kNoError;
9440 // }
9441 query = query_manager_->CreateQuery(
9442 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:539443 }
9444
[email protected]c45f1972012-03-14 07:27:369445 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:519446 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439447 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:539448 return error::kNoError;
9449 } else if (query->shm_id() != sync_shm_id ||
9450 query->shm_offset() != sync_shm_offset) {
9451 DLOG(ERROR) << "Shared memory used by query not the same as before";
9452 return error::kInvalidArguments;
9453 }
9454
[email protected]c45f1972012-03-14 07:27:369455 if (!query_manager_->BeginQuery(query)) {
9456 return error::kOutOfBounds;
9457 }
[email protected]882ba1e22012-03-08 19:02:539458
[email protected]8ebd46c2014-01-08 12:06:139459 state_.current_queries[target] = query;
[email protected]882ba1e22012-03-08 19:02:539460 return error::kNoError;
9461}
9462
9463error::Error GLES2DecoderImpl::HandleEndQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359464 uint32 immediate_data_size, const cmds::EndQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539465 GLenum target = static_cast<GLenum>(c.target);
9466 uint32 submit_count = static_cast<GLuint>(c.submit_count);
[email protected]8ebd46c2014-01-08 12:06:139467 ContextState::QueryMap::iterator it = state_.current_queries.find(target);
[email protected]882ba1e22012-03-08 19:02:539468
[email protected]8ebd46c2014-01-08 12:06:139469 if (it == state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:519470 LOCAL_SET_GL_ERROR(
9471 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:539472 return error::kNoError;
9473 }
[email protected]882ba1e22012-03-08 19:02:539474
[email protected]8ebd46c2014-01-08 12:06:139475 QueryManager::Query* query = it->second.get();
9476 if (!query_manager_->EndQuery(query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:369477 return error::kOutOfBounds;
9478 }
9479
[email protected]fe8d73c2013-02-16 22:37:329480 query_manager_->ProcessPendingTransferQueries();
9481
[email protected]8ebd46c2014-01-08 12:06:139482 state_.current_queries.erase(it);
[email protected]882ba1e22012-03-08 19:02:539483 return error::kNoError;
9484}
9485
[email protected]944b62f32012-09-27 02:20:469486bool GLES2DecoderImpl::GenVertexArraysOESHelper(
9487 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469488 for (GLsizei ii = 0; ii < n; ++ii) {
9489 if (GetVertexAttribManager(client_ids[ii])) {
9490 return false;
9491 }
9492 }
[email protected]ab4fd7282012-10-12 16:25:579493
[email protected]62e155e2012-10-23 22:43:159494 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579495 // Emulated VAO
9496 for (GLsizei ii = 0; ii < n; ++ii) {
9497 CreateVertexAttribManager(client_ids[ii], 0);
9498 }
9499 } else {
[email protected]40d90a22013-04-09 03:39:559500 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:579501
9502 glGenVertexArraysOES(n, service_ids.get());
9503 for (GLsizei ii = 0; ii < n; ++ii) {
9504 CreateVertexAttribManager(client_ids[ii], service_ids[ii]);
9505 }
[email protected]944b62f32012-09-27 02:20:469506 }
[email protected]ab4fd7282012-10-12 16:25:579507
[email protected]944b62f32012-09-27 02:20:469508 return true;
9509}
9510
9511void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
9512 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469513 for (GLsizei ii = 0; ii < n; ++ii) {
9514 VertexAttribManager* vao =
9515 GetVertexAttribManager(client_ids[ii]);
9516 if (vao && !vao->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:119517 if (state_.vertex_attrib_manager.get() == vao) {
[email protected]e259eb412012-10-13 05:47:249518 state_.vertex_attrib_manager = default_vertex_attrib_manager_;
[email protected]944b62f32012-09-27 02:20:469519 }
9520 RemoveVertexAttribManager(client_ids[ii]);
9521 }
9522 }
9523}
9524
9525void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469526 VertexAttribManager* vao = NULL;
9527 GLuint service_id = 0;
9528 if (client_id != 0) {
9529 vao = GetVertexAttribManager(client_id);
9530 if (!vao) {
9531 // Unlike most Bind* methods, the spec explicitly states that VertexArray
9532 // only allows names that have been previously generated. As such, we do
9533 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:519534 LOCAL_SET_GL_ERROR(
9535 GL_INVALID_OPERATION,
9536 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:469537 current_decoder_error_ = error::kNoError;
9538 return;
9539 } else {
9540 service_id = vao->service_id();
9541 }
[email protected]944b62f32012-09-27 02:20:469542 } else {
[email protected]7cd76fd2013-06-02 21:11:119543 vao = default_vertex_attrib_manager_.get();
[email protected]944b62f32012-09-27 02:20:469544 }
9545
[email protected]ab4fd7282012-10-12 16:25:579546 // Only set the VAO state if it's changed
[email protected]7cd76fd2013-06-02 21:11:119547 if (state_.vertex_attrib_manager.get() != vao) {
[email protected]e259eb412012-10-13 05:47:249548 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:159549 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579550 EmulateVertexArrayState();
9551 } else {
9552 glBindVertexArrayOES(service_id);
9553 }
9554 }
9555}
9556
9557// Used when OES_vertex_array_object isn't natively supported
9558void GLES2DecoderImpl::EmulateVertexArrayState() {
9559 // Setup the Vertex attribute state
9560 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
9561 RestoreStateForAttrib(vv);
9562 }
9563
9564 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:219565 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:249566 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:579567 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
9568 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:469569}
9570
9571bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469572 const VertexAttribManager* vao =
9573 GetVertexAttribManager(client_id);
9574 return vao && vao->IsValid() && !vao->IsDeleted();
9575}
9576
[email protected]e51bdf32011-11-23 22:21:469577#if defined(OS_MACOSX)
9578void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
9579 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
9580 texture_id);
9581 if (it != texture_to_io_surface_map_.end()) {
9582 // Found a previous IOSurface bound to this texture; release it.
9583 CFTypeRef surface = it->second;
9584 CFRelease(surface);
9585 texture_to_io_surface_map_.erase(it);
9586 }
9587}
9588#endif
9589
9590void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
9591 GLenum target, GLsizei width, GLsizei height,
9592 GLuint io_surface_id, GLuint plane) {
9593#if defined(OS_MACOSX)
9594 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:519595 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439596 GL_INVALID_OPERATION,
9597 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:469598 return;
9599 }
9600
9601 IOSurfaceSupport* surface_support = IOSurfaceSupport::Initialize();
9602 if (!surface_support) {
[email protected]ab09b612013-03-11 22:11:519603 LOCAL_SET_GL_ERROR(
9604 GL_INVALID_OPERATION,
9605 "glTexImageIOSurface2DCHROMIUM", "only supported on 10.6.");
[email protected]e51bdf32011-11-23 22:21:469606 return;
9607 }
9608
9609 if (target != GL_TEXTURE_RECTANGLE_ARB) {
9610 // This might be supported in the future, and if we could require
9611 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
9612 // could delete a lot of code. For now, perform strict validation so we
9613 // know what's going on.
[email protected]ab09b612013-03-11 22:11:519614 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469615 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439616 "glTexImageIOSurface2DCHROMIUM",
9617 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:469618 return;
9619 }
9620
[email protected]09d50362012-10-18 20:54:379621 // Default target might be conceptually valid, but disallow it to avoid
9622 // accidents.
[email protected]c986af502013-08-14 01:04:449623 TextureRef* texture_ref =
9624 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:499625 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519626 LOCAL_SET_GL_ERROR(
9627 GL_INVALID_OPERATION,
9628 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:469629 return;
9630 }
[email protected]e51bdf32011-11-23 22:21:469631
9632 // Look up the new IOSurface. Note that because of asynchrony
9633 // between processes this might fail; during live resizing the
9634 // plugin process might allocate and release an IOSurface before
9635 // this process gets a chance to look it up. Hold on to any old
9636 // IOSurface in this case.
9637 CFTypeRef surface = surface_support->IOSurfaceLookup(io_surface_id);
9638 if (!surface) {
[email protected]ab09b612013-03-11 22:11:519639 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439640 GL_INVALID_OPERATION,
9641 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:469642 return;
9643 }
9644
9645 // Release any IOSurface previously bound to this texture.
[email protected]370eaf12013-05-18 09:19:499646 ReleaseIOSurfaceForTexture(texture_ref->service_id());
[email protected]e51bdf32011-11-23 22:21:469647
9648 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
9649 texture_to_io_surface_map_.insert(
[email protected]370eaf12013-05-18 09:19:499650 std::make_pair(texture_ref->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:469651
9652 CGLContextObj context =
9653 static_cast<CGLContextObj>(context_->GetHandle());
9654
9655 CGLError err = surface_support->CGLTexImageIOSurface2D(
9656 context,
9657 target,
9658 GL_RGBA,
9659 width,
9660 height,
9661 GL_BGRA,
9662 GL_UNSIGNED_INT_8_8_8_8_REV,
9663 surface,
9664 plane);
9665
9666 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:519667 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469668 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439669 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:469670 return;
9671 }
9672
9673 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499674 texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:469675 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
9676
9677#else
[email protected]ab09b612013-03-11 22:11:519678 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439679 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:469680#endif
9681}
9682
[email protected]97dc7cbe2011-12-06 17:26:179683static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
9684 switch (internalformat) {
9685 case GL_RGB565:
9686 return GL_RGB;
9687 case GL_RGBA4:
9688 return GL_RGBA;
9689 case GL_RGB5_A1:
9690 return GL_RGBA;
9691 case GL_RGB8_OES:
9692 return GL_RGB;
9693 case GL_RGBA8_OES:
9694 return GL_RGBA;
9695 case GL_LUMINANCE8_ALPHA8_EXT:
9696 return GL_LUMINANCE_ALPHA;
9697 case GL_LUMINANCE8_EXT:
9698 return GL_LUMINANCE;
9699 case GL_ALPHA8_EXT:
9700 return GL_ALPHA;
9701 case GL_RGBA32F_EXT:
9702 return GL_RGBA;
9703 case GL_RGB32F_EXT:
9704 return GL_RGB;
9705 case GL_ALPHA32F_EXT:
9706 return GL_ALPHA;
9707 case GL_LUMINANCE32F_EXT:
9708 return GL_LUMINANCE;
9709 case GL_LUMINANCE_ALPHA32F_EXT:
9710 return GL_LUMINANCE_ALPHA;
9711 case GL_RGBA16F_EXT:
9712 return GL_RGBA;
9713 case GL_RGB16F_EXT:
9714 return GL_RGB;
9715 case GL_ALPHA16F_EXT:
9716 return GL_ALPHA;
9717 case GL_LUMINANCE16F_EXT:
9718 return GL_LUMINANCE;
9719 case GL_LUMINANCE_ALPHA16F_EXT:
9720 return GL_LUMINANCE_ALPHA;
9721 case GL_BGRA8_EXT:
9722 return GL_BGRA_EXT;
9723 default:
9724 return GL_NONE;
9725 }
9726}
9727
[email protected]43410e92012-04-20 17:06:289728void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:039729 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
[email protected]a4a6bdd12013-04-19 20:46:549730 GLenum internal_format, GLenum dest_type) {
[email protected]370eaf12013-05-18 09:19:499731 TextureRef* dest_texture_ref = GetTexture(dest_id);
9732 TextureRef* source_texture_ref = GetTexture(source_id);
[email protected]43410e92012-04-20 17:06:289733
[email protected]370eaf12013-05-18 09:19:499734 if (!source_texture_ref || !dest_texture_ref) {
[email protected]ab09b612013-03-11 22:11:519735 LOCAL_SET_GL_ERROR(
9736 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:289737 return;
9738 }
9739
9740 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:519741 LOCAL_SET_GL_ERROR(
9742 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:289743 return;
9744 }
9745
[email protected]370eaf12013-05-18 09:19:499746 Texture* source_texture = source_texture_ref->texture();
9747 Texture* dest_texture = dest_texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079748 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:259749 (source_texture->target() != GL_TEXTURE_2D &&
9750 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
[email protected]3ecc1052013-09-26 08:59:009751 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
9752 "glCopyTextureCHROMIUM",
9753 "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:039754 return;
9755 }
9756
[email protected]43410e92012-04-20 17:06:289757 int source_width, source_height, dest_width, dest_height;
[email protected]43410e92012-04-20 17:06:289758
[email protected]3e0dfd72014-02-21 06:28:419759 gfx::GLImage* image =
9760 source_texture->GetLevelImage(source_texture->target(), 0);
9761 if (image) {
[email protected]7bffe9e12014-01-27 23:02:559762 gfx::Size size = image->GetSize();
[email protected]377976552013-05-14 23:32:569763 source_width = size.width();
9764 source_height = size.height();
9765 if (source_width <= 0 || source_height <= 0) {
9766 LOCAL_SET_GL_ERROR(
9767 GL_INVALID_VALUE,
[email protected]7bffe9e12014-01-27 23:02:559768 "glCopyTextureChromium", "invalid image size");
[email protected]377976552013-05-14 23:32:569769 return;
9770 }
[email protected]3ecc1052013-09-26 08:59:009771 } else {
9772 if (!source_texture->GetLevelSize(
9773 source_texture->target(), 0, &source_width, &source_height)) {
9774 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
9775 "glCopyTextureChromium",
9776 "source texture has no level 0");
9777 return;
9778 }
9779
9780 // Check that this type of texture is allowed.
9781 if (!texture_manager()->ValidForTarget(
9782 source_texture->target(), level, source_width, source_height, 1)) {
9783 LOCAL_SET_GL_ERROR(
9784 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions");
9785 return;
9786 }
[email protected]377976552013-05-14 23:32:569787 }
9788
[email protected]04b5b37d2014-02-07 02:11:519789 // Clear the source texture if necessary.
9790 if (!texture_manager()->ClearTextureLevel(
9791 this, source_texture_ref, source_texture->target(), 0)) {
9792 LOCAL_SET_GL_ERROR(
9793 GL_OUT_OF_MEMORY, "glCopyTextureCHROMIUM", "dimensions too big");
9794 return;
9795 }
9796
[email protected]cf6b8f62012-05-25 21:43:379797 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
9798 // needed because it takes 10s of milliseconds to initialize.
9799 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:519800 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:379801 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:279802 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:379803 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:519804 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:379805 return;
9806 }
9807
[email protected]a4a6bdd12013-04-19 20:46:549808 GLenum dest_type_previous;
[email protected]0a1e9ad2012-05-04 21:13:039809 GLenum dest_internal_format;
[email protected]02965c22013-03-09 02:40:079810 bool dest_level_defined = dest_texture->GetLevelSize(
9811 GL_TEXTURE_2D, level, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:289812
[email protected]0a1e9ad2012-05-04 21:13:039813 if (dest_level_defined) {
[email protected]a4a6bdd12013-04-19 20:46:549814 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous,
[email protected]02965c22013-03-09 02:40:079815 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:039816 }
9817
9818 // Resize the destination texture to the dimensions of the source texture.
9819 if (!dest_level_defined || dest_width != source_width ||
9820 dest_height != source_height ||
[email protected]a4a6bdd12013-04-19 20:46:549821 dest_internal_format != internal_format ||
9822 dest_type_previous != dest_type) {
[email protected]43410e92012-04-20 17:06:289823 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:519824 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:079825 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
[email protected]8f1d2aa2013-05-10 23:45:389826 glTexImage2D(
[email protected]43410e92012-04-20 17:06:289827 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:039828 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:519829 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:039830 if (error != GL_NO_ERROR) {
[email protected]2b10c02d2014-01-29 16:43:029831 RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D);
[email protected]43410e92012-04-20 17:06:289832 return;
[email protected]0a1e9ad2012-05-04 21:13:039833 }
[email protected]43410e92012-04-20 17:06:289834
9835 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499836 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:039837 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:259838 } else {
[email protected]02965c22013-03-09 02:40:079839 texture_manager()->SetLevelCleared(
[email protected]370eaf12013-05-18 09:19:499840 dest_texture_ref, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:289841 }
9842
[email protected]91c94eb2013-10-22 10:32:549843 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
9844
[email protected]5394a4102013-04-18 05:41:379845 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
9846 // before presenting.
9847 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
9848 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
9849 // instead of using default matrix crbug.com/226218.
9850 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
9851 0.0f, 1.0f, 0.0f, 0.0f,
9852 0.0f, 0.0f, 1.0f, 0.0f,
9853 0.0f, 0.0f, 0.0f, 1.0f};
9854 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
9855 this,
9856 source_texture->target(),
9857 dest_texture->target(),
9858 source_texture->service_id(),
9859 dest_texture->service_id(), level,
9860 source_width, source_height,
9861 unpack_flip_y_,
9862 unpack_premultiply_alpha_,
9863 unpack_unpremultiply_alpha_,
9864 default_matrix);
9865 } else {
9866 copy_texture_CHROMIUM_->DoCopyTexture(
9867 this,
9868 source_texture->target(),
9869 dest_texture->target(),
9870 source_texture->service_id(),
9871 dest_texture->service_id(), level,
9872 source_width, source_height,
9873 unpack_flip_y_,
9874 unpack_premultiply_alpha_,
9875 unpack_unpremultiply_alpha_);
9876 }
[email protected]91c94eb2013-10-22 10:32:549877
9878 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
[email protected]43410e92012-04-20 17:06:289879}
9880
[email protected]97dc7cbe2011-12-06 17:26:179881static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
9882 switch (internalformat) {
9883 case GL_RGB565:
9884 return GL_UNSIGNED_SHORT_5_6_5;
9885 case GL_RGBA4:
9886 return GL_UNSIGNED_SHORT_4_4_4_4;
9887 case GL_RGB5_A1:
9888 return GL_UNSIGNED_SHORT_5_5_5_1;
9889 case GL_RGB8_OES:
9890 return GL_UNSIGNED_BYTE;
9891 case GL_RGBA8_OES:
9892 return GL_UNSIGNED_BYTE;
9893 case GL_LUMINANCE8_ALPHA8_EXT:
9894 return GL_UNSIGNED_BYTE;
9895 case GL_LUMINANCE8_EXT:
9896 return GL_UNSIGNED_BYTE;
9897 case GL_ALPHA8_EXT:
9898 return GL_UNSIGNED_BYTE;
9899 case GL_RGBA32F_EXT:
9900 return GL_FLOAT;
9901 case GL_RGB32F_EXT:
9902 return GL_FLOAT;
9903 case GL_ALPHA32F_EXT:
9904 return GL_FLOAT;
9905 case GL_LUMINANCE32F_EXT:
9906 return GL_FLOAT;
9907 case GL_LUMINANCE_ALPHA32F_EXT:
9908 return GL_FLOAT;
9909 case GL_RGBA16F_EXT:
9910 return GL_HALF_FLOAT_OES;
9911 case GL_RGB16F_EXT:
9912 return GL_HALF_FLOAT_OES;
9913 case GL_ALPHA16F_EXT:
9914 return GL_HALF_FLOAT_OES;
9915 case GL_LUMINANCE16F_EXT:
9916 return GL_HALF_FLOAT_OES;
9917 case GL_LUMINANCE_ALPHA16F_EXT:
9918 return GL_HALF_FLOAT_OES;
9919 case GL_BGRA8_EXT:
9920 return GL_UNSIGNED_BYTE;
9921 default:
9922 return GL_NONE;
9923 }
9924}
9925
9926void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:449927 GLenum target,
9928 GLint levels,
9929 GLenum internal_format,
9930 GLsizei width,
9931 GLsizei height) {
[email protected]43ed3a72012-05-30 22:55:389932 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT");
[email protected]80eb6b52012-01-19 00:14:419933 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]3ecc1052013-09-26 08:59:009934 TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:519935 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439936 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:179937 return;
9938 }
[email protected]c986af502013-08-14 01:04:449939 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9940 &state_, target);
[email protected]370eaf12013-05-18 09:19:499941 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519942 LOCAL_SET_GL_ERROR(
9943 GL_INVALID_OPERATION,
9944 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:179945 return;
9946 }
[email protected]370eaf12013-05-18 09:19:499947 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079948 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:449949 framebuffer_state_.clear_state_dirty = true;
[email protected]97dc7cbe2011-12-06 17:26:179950 }
[email protected]02965c22013-03-09 02:40:079951 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:519952 LOCAL_SET_GL_ERROR(
9953 GL_INVALID_OPERATION,
9954 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:179955 return;
9956 }
[email protected]7989c9e2013-01-23 06:39:269957
9958 GLenum format = ExtractFormatFromStorageFormat(internal_format);
9959 GLenum type = ExtractTypeFromStorageFormat(internal_format);
9960
9961 {
9962 GLsizei level_width = width;
9963 GLsizei level_height = height;
9964 uint32 estimated_size = 0;
9965 for (int ii = 0; ii < levels; ++ii) {
9966 uint32 level_size = 0;
9967 if (!GLES2Util::ComputeImageDataSizes(
9968 level_width, level_height, format, type, state_.unpack_alignment,
9969 &estimated_size, NULL, NULL) ||
9970 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519971 LOCAL_SET_GL_ERROR(
9972 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:269973 return;
9974 }
9975 level_width = std::max(1, level_width >> 1);
9976 level_height = std::max(1, level_height >> 1);
9977 }
9978 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519979 LOCAL_SET_GL_ERROR(
9980 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:269981 return;
9982 }
9983 }
9984
[email protected]ab09b612013-03-11 22:11:519985 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]8f1d2aa2013-05-10 23:45:389986 glTexStorage2DEXT(target, levels, internal_format, width, height);
[email protected]ab09b612013-03-11 22:11:519987 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:179988 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:159989 GLsizei level_width = width;
9990 GLsizei level_height = height;
9991 for (int ii = 0; ii < levels; ++ii) {
9992 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499993 texture_ref, target, ii, format,
9994 level_width, level_height, 1, 0, format, type, false);
[email protected]4502e6492011-12-14 19:39:159995 level_width = std::max(1, level_width >> 1);
9996 level_height = std::max(1, level_height >> 1);
9997 }
[email protected]02965c22013-03-09 02:40:079998 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:179999 }
[email protected]97dc7cbe2011-12-06 17:26:1710000}
[email protected]e51bdf32011-11-23 22:21:4610001
[email protected]78b514b2012-05-01 21:50:5910002error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510003 uint32 immediate_data_size, const cmds::GenMailboxCHROMIUM& c) {
[email protected]baed42c2013-10-01 05:06:3510004 return error::kUnknownCommand;
[email protected]78b514b2012-05-01 21:50:5910005}
10006
10007void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3710008 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0210009 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3210010 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3710011 "mailbox[0]", static_cast<unsigned char>(data[0]));
10012
10013 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
10014 DLOG_IF(ERROR, !mailbox.Verify()) << "ProduceTextureCHROMIUM was passed a "
10015 "mailbox that was not generated by "
10016 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0210017
[email protected]c986af502013-08-14 01:04:4410018 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10019 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910020 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110021 LOCAL_SET_GL_ERROR(
10022 GL_INVALID_OPERATION,
10023 "glProduceTextureCHROMIUM", "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5910024 return;
10025 }
10026
[email protected]62e65f02013-05-29 22:28:1010027 Texture* produced = texture_manager()->Produce(texture_ref);
10028 if (!produced) {
[email protected]ab09b612013-03-11 22:11:5110029 LOCAL_SET_GL_ERROR(
10030 GL_INVALID_OPERATION,
10031 "glProduceTextureCHROMIUM", "invalid texture");
[email protected]78b514b2012-05-01 21:50:5910032 return;
10033 }
10034
[email protected]64ba52f2014-02-15 14:22:3710035 group_->mailbox_manager()->ProduceTexture(target, mailbox, produced);
[email protected]78b514b2012-05-01 21:50:5910036}
10037
10038void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3710039 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0210040 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3210041 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3710042 "mailbox[0]", static_cast<unsigned char>(data[0]));
10043 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
10044 DLOG_IF(ERROR, !mailbox.Verify()) << "ConsumeTextureCHROMIUM was passed a "
10045 "mailbox that was not generated by "
10046 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0210047
[email protected]62e65f02013-05-29 22:28:1010048 scoped_refptr<TextureRef> texture_ref =
[email protected]c986af502013-08-14 01:04:4410049 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]7cd76fd2013-06-02 21:11:1110050 if (!texture_ref.get()) {
10051 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10052 "glConsumeTextureCHROMIUM",
10053 "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5910054 return;
10055 }
[email protected]62e65f02013-05-29 22:28:1010056 GLuint client_id = texture_ref->client_id();
10057 if (!client_id) {
10058 LOCAL_SET_GL_ERROR(
10059 GL_INVALID_OPERATION,
10060 "glConsumeTextureCHROMIUM", "unknown texture for target");
10061 return;
10062 }
[email protected]64ba52f2014-02-15 14:22:3710063 Texture* texture = group_->mailbox_manager()->ConsumeTexture(target, mailbox);
[email protected]62e65f02013-05-29 22:28:1010064 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5110065 LOCAL_SET_GL_ERROR(
10066 GL_INVALID_OPERATION,
10067 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:5910068 return;
10069 }
[email protected]62e65f02013-05-29 22:28:1010070 if (texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:5110071 LOCAL_SET_GL_ERROR(
10072 GL_INVALID_OPERATION,
[email protected]62e65f02013-05-29 22:28:1010073 "glConsumeTextureCHROMIUM", "invalid target");
[email protected]78b514b2012-05-01 21:50:5910074 return;
10075 }
[email protected]62e65f02013-05-29 22:28:1010076
10077 DeleteTexturesHelper(1, &client_id);
10078 texture_ref = texture_manager()->Consume(client_id, texture);
10079 glBindTexture(target, texture_ref->service_id());
10080
10081 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
10082 unit.bind_target = target;
10083 switch (target) {
10084 case GL_TEXTURE_2D:
10085 unit.bound_texture_2d = texture_ref;
10086 break;
10087 case GL_TEXTURE_CUBE_MAP:
10088 unit.bound_texture_cube_map = texture_ref;
10089 break;
10090 case GL_TEXTURE_EXTERNAL_OES:
10091 unit.bound_texture_external_oes = texture_ref;
10092 break;
10093 case GL_TEXTURE_RECTANGLE_ARB:
10094 unit.bound_texture_rectangle_arb = texture_ref;
10095 break;
10096 default:
10097 NOTREACHED(); // Validation should prevent us getting here.
10098 break;
10099 }
[email protected]78b514b2012-05-01 21:50:5910100}
10101
[email protected]d2a0e1a2012-08-12 02:25:0110102void GLES2DecoderImpl::DoInsertEventMarkerEXT(
10103 GLsizei length, const GLchar* marker) {
10104 if (!marker) {
10105 marker = "";
10106 }
10107 debug_marker_manager_.SetMarker(
10108 length ? std::string(marker, length) : std::string(marker));
10109}
10110
10111void GLES2DecoderImpl::DoPushGroupMarkerEXT(
10112 GLsizei length, const GLchar* marker) {
10113 if (!marker) {
10114 marker = "";
10115 }
[email protected]cac16542014-01-15 17:53:5110116 std::string name = length ? std::string(marker, length) : std::string(marker);
10117 debug_marker_manager_.PushGroup(name);
10118 gpu_tracer_->Begin(name, kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0110119}
10120
10121void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
10122 debug_marker_manager_.PopGroup();
[email protected]cac16542014-01-15 17:53:5110123 gpu_tracer_->End(kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0110124}
10125
[email protected]09d50362012-10-18 20:54:3710126void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
10127 GLenum target, GLint image_id) {
10128 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3710129
[email protected]bc26e8d2014-01-29 00:40:3010130 if (target == GL_TEXTURE_CUBE_MAP) {
10131 LOCAL_SET_GL_ERROR(
10132 GL_INVALID_ENUM,
10133 "glBindTexImage2DCHROMIUM", "invalid target");
10134 return;
10135 }
10136
[email protected]09d50362012-10-18 20:54:3710137 // Default target might be conceptually valid, but disallow it to avoid
10138 // accidents.
[email protected]c986af502013-08-14 01:04:4410139 TextureRef* texture_ref =
10140 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910141 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110142 LOCAL_SET_GL_ERROR(
10143 GL_INVALID_OPERATION,
10144 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710145 return;
10146 }
10147
10148 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10149 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110150 LOCAL_SET_GL_ERROR(
10151 GL_INVALID_OPERATION,
10152 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710153 return;
10154 }
10155
[email protected]b8160812013-04-09 00:41:0410156 {
10157 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010158 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2610159 if (!gl_image->BindTexImage(target)) {
[email protected]b8160812013-04-09 00:41:0410160 LOCAL_SET_GL_ERROR(
10161 GL_INVALID_OPERATION,
10162 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
10163 return;
10164 }
[email protected]09d50362012-10-18 20:54:3710165 }
10166
10167 gfx::Size size = gl_image->GetSize();
10168 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910169 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:3710170 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]370eaf12013-05-18 09:19:4910171 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:3710172}
10173
10174void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
10175 GLenum target, GLint image_id) {
10176 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3710177
10178 // Default target might be conceptually valid, but disallow it to avoid
10179 // accidents.
[email protected]c986af502013-08-14 01:04:4410180 TextureRef* texture_ref =
10181 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910182 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110183 LOCAL_SET_GL_ERROR(
10184 GL_INVALID_OPERATION,
10185 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710186 return;
10187 }
10188
10189 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10190 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110191 LOCAL_SET_GL_ERROR(
10192 GL_INVALID_OPERATION,
10193 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710194 return;
10195 }
10196
10197 // Do nothing when image is not currently bound.
[email protected]370eaf12013-05-18 09:19:4910198 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3710199 return;
10200
[email protected]b8160812013-04-09 00:41:0410201 {
10202 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010203 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2610204 gl_image->ReleaseTexImage(target);
[email protected]b8160812013-04-09 00:41:0410205 }
[email protected]09d50362012-10-18 20:54:3710206
10207 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910208 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:3710209 GL_RGBA, GL_UNSIGNED_BYTE, false);
10210}
[email protected]d2a0e1a2012-08-12 02:25:0110211
[email protected]94307712012-11-16 23:26:1110212error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510213 uint32 immediate_data_size, const cmds::TraceBeginCHROMIUM& c) {
[email protected]94307712012-11-16 23:26:1110214 Bucket* bucket = GetBucket(c.bucket_id);
10215 if (!bucket || bucket->size() == 0) {
10216 return error::kInvalidArguments;
10217 }
10218 std::string command_name;
10219 if (!bucket->GetAsString(&command_name)) {
10220 return error::kInvalidArguments;
10221 }
[email protected]fb97b662013-02-20 23:02:1410222 TRACE_EVENT_COPY_ASYNC_BEGIN0("gpu", command_name.c_str(), this);
[email protected]cac16542014-01-15 17:53:5110223 if (!gpu_tracer_->Begin(command_name, kTraceCHROMIUM)) {
[email protected]ab09b612013-03-11 22:11:5110224 LOCAL_SET_GL_ERROR(
10225 GL_INVALID_OPERATION,
10226 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1410227 return error::kNoError;
10228 }
[email protected]94307712012-11-16 23:26:1110229 return error::kNoError;
10230}
10231
10232void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
[email protected]fb97b662013-02-20 23:02:1410233 if (gpu_tracer_->CurrentName().empty()) {
[email protected]ab09b612013-03-11 22:11:5110234 LOCAL_SET_GL_ERROR(
10235 GL_INVALID_OPERATION,
10236 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1110237 return;
10238 }
[email protected]fb97b662013-02-20 23:02:1410239 TRACE_EVENT_COPY_ASYNC_END0("gpu", gpu_tracer_->CurrentName().c_str(), this);
[email protected]cac16542014-01-15 17:53:5110240 gpu_tracer_->End(kTraceCHROMIUM);
[email protected]94307712012-11-16 23:26:1110241}
10242
[email protected]2f143d482013-03-14 18:04:4910243void GLES2DecoderImpl::DoDrawBuffersEXT(
10244 GLsizei count, const GLenum* bufs) {
10245 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
10246 LOCAL_SET_GL_ERROR(
10247 GL_INVALID_VALUE,
10248 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
10249 return;
10250 }
10251
10252 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
10253 if (framebuffer) {
10254 for (GLsizei i = 0; i < count; ++i) {
10255 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
10256 bufs[i] != GL_NONE) {
10257 LOCAL_SET_GL_ERROR(
10258 GL_INVALID_OPERATION,
10259 "glDrawBuffersEXT",
10260 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
10261 return;
10262 }
10263 }
10264 glDrawBuffersARB(count, bufs);
10265 framebuffer->SetDrawBuffers(count, bufs);
10266 } else { // backbuffer
10267 if (count > 1 ||
10268 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
10269 LOCAL_SET_GL_ERROR(
10270 GL_INVALID_OPERATION,
10271 "glDrawBuffersEXT",
10272 "more than one buffer or bufs not GL_NONE or GL_BACK");
10273 return;
10274 }
10275 GLenum mapped_buf = bufs[0];
10276 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
10277 bufs[0] == GL_BACK) {
10278 mapped_buf = GL_COLOR_ATTACHMENT0;
10279 }
10280 glDrawBuffersARB(count, &mapped_buf);
10281 group_->set_draw_buffer(bufs[0]);
10282 }
10283}
10284
[email protected]32145a92012-12-17 09:01:5910285bool GLES2DecoderImpl::ValidateAsyncTransfer(
10286 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:4710287 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:5910288 GLenum target,
10289 GLint level,
10290 const void * data) {
10291 // We only support async uploads to 2D textures for now.
10292 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110293 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5910294 return false;
10295 }
10296 // We only support uploads to level zero for now.
10297 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5110298 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5910299 return false;
10300 }
10301 // A transfer buffer must be bound, even for asyncTexImage2D.
10302 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5110303 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5910304 return false;
10305 }
10306 // We only support one async transfer in progress.
[email protected]85a4ac22013-05-31 01:58:4710307 if (!texture_ref ||
10308 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5110309 LOCAL_SET_GL_ERROR(
10310 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910311 function_name, "transfer already in progress");
10312 return false;
10313 }
10314 return true;
10315}
10316
[email protected]69023942012-11-30 19:57:1610317error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510318 uint32 immediate_data_size, const cmds::AsyncTexImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610319 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610320 GLenum target = static_cast<GLenum>(c.target);
10321 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:4410322 // TODO(kloveless): Change HandleAsyncTexImage2DCHROMIUM command to use
10323 // unsigned integer for internalformat.
10324 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]69023942012-11-30 19:57:1610325 GLsizei width = static_cast<GLsizei>(c.width);
10326 GLsizei height = static_cast<GLsizei>(c.height);
10327 GLint border = static_cast<GLint>(c.border);
10328 GLenum format = static_cast<GLenum>(c.format);
10329 GLenum type = static_cast<GLenum>(c.type);
10330 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
10331 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
10332 uint32 pixels_size;
[email protected]32145a92012-12-17 09:01:5910333
10334 // TODO(epenner): Move this and copies of this memory validation
10335 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1610336 if (!GLES2Util::ComputeImageDataSizes(
10337 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
10338 NULL)) {
10339 return error::kOutOfBounds;
10340 }
10341 const void* pixels = NULL;
10342 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
10343 pixels = GetSharedMemoryAs<const void*>(
10344 pixels_shm_id, pixels_shm_offset, pixels_size);
10345 if (!pixels) {
10346 return error::kOutOfBounds;
10347 }
10348 }
10349
[email protected]c986af502013-08-14 01:04:4410350 TextureManager::DoTextImage2DArguments args = {
10351 target, level, internal_format, width, height, border, format, type,
10352 pixels, pixels_size};
10353 TextureRef* texture_ref;
[email protected]32145a92012-12-17 09:01:5910354 // All the normal glTexSubImage2D validation.
[email protected]c986af502013-08-14 01:04:4410355 if (!texture_manager()->ValidateTexImage2D(
10356 &state_, "glAsyncTexImage2DCHROMIUM", args, &texture_ref)) {
[email protected]32145a92012-12-17 09:01:5910357 return error::kNoError;
10358 }
10359
10360 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4910361 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5910362 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4710363 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910364 return error::kNoError;
10365
10366 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0710367 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5110368 LOCAL_SET_GL_ERROR(
10369 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910370 "glAsyncTexImage2DCHROMIUM", "already defined");
10371 return error::kNoError;
10372 }
10373
[email protected]7989c9e2013-01-23 06:39:2610374 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5110375 LOCAL_SET_GL_ERROR(
10376 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2610377 return error::kNoError;
10378 }
10379
[email protected]32145a92012-12-17 09:01:5910380 // We know the memory/size is safe, so get the real shared memory since
10381 // it might need to be duped to prevent use-after-free of the memory.
[email protected]16ccec12013-02-28 03:40:2110382 gpu::Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id);
[email protected]32145a92012-12-17 09:01:5910383 base::SharedMemory* shared_memory = buffer.shared_memory;
10384 uint32 shm_size = buffer.size;
10385 uint32 shm_data_offset = c.pixels_shm_offset;
10386 uint32 shm_data_size = pixels_size;
10387
[email protected]5b3a8e02013-03-13 05:36:4410388 // Setup the parameters.
[email protected]8f1d2aa2013-05-10 23:45:3810389 AsyncTexImage2DParams tex_params = {
10390 target, level, static_cast<GLenum>(internal_format),
10391 width, height, border, format, type};
10392 AsyncMemoryParams mem_params = {
10393 shared_memory, shm_size, shm_data_offset, shm_data_size};
[email protected]32145a92012-12-17 09:01:5910394
[email protected]5b3a8e02013-03-13 05:36:4410395 // Set up the async state if needed, and make the texture
10396 // immutable so the async state stays valid. The level info
10397 // is set up lazily when the transfer completes.
[email protected]896425e2013-06-12 17:27:1810398 AsyncPixelTransferDelegate* delegate =
10399 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref,
10400 tex_params);
[email protected]5b3a8e02013-03-13 05:36:4410401 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5910402
[email protected]896425e2013-06-12 17:27:1810403 delegate->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4410404 tex_params,
10405 mem_params,
10406 base::Bind(&TextureManager::SetLevelInfoFromParams,
[email protected]370eaf12013-05-18 09:19:4910407 // The callback is only invoked if the transfer delegate still
10408 // exists, which implies through manager->texture_ref->state
[email protected]5b3a8e02013-03-13 05:36:4410409 // ownership that both of these pointers are valid.
10410 base::Unretained(texture_manager()),
[email protected]370eaf12013-05-18 09:19:4910411 base::Unretained(texture_ref),
[email protected]5b3a8e02013-03-13 05:36:4410412 tex_params));
[email protected]f598f422012-12-07 08:30:0310413 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610414}
10415
10416error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510417 uint32 immediate_data_size, const cmds::AsyncTexSubImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610418 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610419 GLenum target = static_cast<GLenum>(c.target);
10420 GLint level = static_cast<GLint>(c.level);
10421 GLint xoffset = static_cast<GLint>(c.xoffset);
10422 GLint yoffset = static_cast<GLint>(c.yoffset);
10423 GLsizei width = static_cast<GLsizei>(c.width);
10424 GLsizei height = static_cast<GLsizei>(c.height);
10425 GLenum format = static_cast<GLenum>(c.format);
10426 GLenum type = static_cast<GLenum>(c.type);
[email protected]32145a92012-12-17 09:01:5910427
10428 // TODO(epenner): Move this and copies of this memory validation
10429 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1610430 uint32 data_size;
10431 if (!GLES2Util::ComputeImageDataSizes(
10432 width, height, format, type, state_.unpack_alignment, &data_size,
10433 NULL, NULL)) {
10434 return error::kOutOfBounds;
10435 }
10436 const void* pixels = GetSharedMemoryAs<const void*>(
10437 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5910438
10439 // All the normal glTexSubImage2D validation.
10440 error::Error error = error::kNoError;
10441 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
10442 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
10443 return error;
[email protected]69023942012-11-30 19:57:1610444 }
10445
[email protected]32145a92012-12-17 09:01:5910446 // Extra async validation.
[email protected]c986af502013-08-14 01:04:4410447 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10448 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910449 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5910450 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4710451 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910452 return error::kNoError;
10453
10454 // Guarantee async textures are always 'cleared' as follows:
10455 // - AsyncTexImage2D can not redefine an existing texture
10456 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
10457 // - AsyncTexSubImage2D clears synchronously if not already cleared.
10458 // - Textures become immutable after an async call.
10459 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0710460 if (!texture->SafeToRenderFrom()) {
[email protected]370eaf12013-05-18 09:19:4910461 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
10462 target, level)) {
[email protected]ab09b612013-03-11 22:11:5110463 LOCAL_SET_GL_ERROR(
10464 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2510465 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5910466 return error::kNoError;
10467 }
10468 }
10469
10470 // We know the memory/size is safe, so get the real shared memory since
10471 // it might need to be duped to prevent use-after-free of the memory.
[email protected]16ccec12013-02-28 03:40:2110472 gpu::Buffer buffer = GetSharedMemoryBuffer(c.data_shm_id);
[email protected]32145a92012-12-17 09:01:5910473 base::SharedMemory* shared_memory = buffer.shared_memory;
10474 uint32 shm_size = buffer.size;
10475 uint32 shm_data_offset = c.data_shm_offset;
10476 uint32 shm_data_size = data_size;
10477
[email protected]5b3a8e02013-03-13 05:36:4410478 // Setup the parameters.
[email protected]2a7568a2013-05-09 23:12:0310479 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
[email protected]32145a92012-12-17 09:01:5910480 width, height, format, type};
[email protected]2a7568a2013-05-09 23:12:0310481 AsyncMemoryParams mem_params = {shared_memory, shm_size,
[email protected]32145a92012-12-17 09:01:5910482 shm_data_offset, shm_data_size};
[email protected]896425e2013-06-12 17:27:1810483 AsyncPixelTransferDelegate* delegate =
10484 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
10485 if (!delegate) {
[email protected]5b3a8e02013-03-13 05:36:4410486 // TODO(epenner): We may want to enforce exclusive use
10487 // of async APIs in which case this should become an error,
10488 // (the texture should have been async defined).
[email protected]2a7568a2013-05-09 23:12:0310489 AsyncTexImage2DParams define_params = {target, level,
[email protected]5b3a8e02013-03-13 05:36:4410490 0, 0, 0, 0, 0, 0};
10491 texture->GetLevelSize(target, level, &define_params.width,
10492 &define_params.height);
10493 texture->GetLevelType(target, level, &define_params.type,
10494 &define_params.internal_format);
10495 // Set up the async state if needed, and make the texture
10496 // immutable so the async state stays valid.
[email protected]896425e2013-06-12 17:27:1810497 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate(
[email protected]85a4ac22013-05-31 01:58:4710498 texture_ref, define_params);
[email protected]5b3a8e02013-03-13 05:36:4410499 texture->SetImmutable(true);
10500 }
10501
[email protected]896425e2013-06-12 17:27:1810502 delegate->AsyncTexSubImage2D(tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5910503 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610504}
10505
[email protected]a00c1f742013-03-05 17:02:1610506error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
10507 uint32 immediate_data_size, const cmds::WaitAsyncTexImage2DCHROMIUM& c) {
10508 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
10509 GLenum target = static_cast<GLenum>(c.target);
10510
10511 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110512 LOCAL_SET_GL_ERROR(
10513 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1610514 return error::kNoError;
10515 }
[email protected]c986af502013-08-14 01:04:4410516 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10517 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910518 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110519 LOCAL_SET_GL_ERROR(
10520 GL_INVALID_OPERATION,
10521 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1610522 return error::kNoError;
10523 }
[email protected]896425e2013-06-12 17:27:1810524 AsyncPixelTransferDelegate* delegate =
10525 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
10526 if (!delegate) {
[email protected]370eaf12013-05-18 09:19:4910527 LOCAL_SET_GL_ERROR(
10528 GL_INVALID_OPERATION,
10529 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
10530 return error::kNoError;
10531 }
[email protected]896425e2013-06-12 17:27:1810532 delegate->WaitForTransferCompletion();
[email protected]69a8701e2013-03-07 21:31:0910533 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1610534 return error::kNoError;
10535}
10536
[email protected]91c94eb2013-10-22 10:32:5410537void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer(
10538 TextureRef* texture_ref) {
10539 Texture* texture = texture_ref->texture();
10540 DoDidUseTexImageIfNeeded(texture, texture->target());
10541}
10542
[email protected]96449d2c2009-11-25 00:01:3210543// Include the auto-generated part of this file. We split this because it means
10544// we can easily edit the non-auto generated parts right here in this file
10545// instead of having to edit some template or the code generator.
10546#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
10547
10548} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2510549} // namespace gpu