blob: f530974de0582ed0aa9ea9b7ede3ed8020854a5e [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]e3c4a9ab2014-03-31 09:07:0218#include "base/callback_helpers.h"
[email protected]e844ae22012-01-14 03:36:2619#include "base/command_line.h"
[email protected]5aa95ac2014-08-14 15:20:5620#include "base/float_util.h"
[email protected]3b63f8f42011-03-28 01:54:1521#include "base/memory/scoped_ptr.h"
[email protected]e3c4a9ab2014-03-31 09:07:0222#include "base/numerics/safe_math.h"
[email protected]f4390962013-06-11 07:29:2223#include "base/strings/string_number_conversions.h"
[email protected]6d668892013-12-04 21:37:1224#include "base/strings/string_split.h"
primiano05dadf012015-01-28 13:10:3225#include "base/trace_event/trace_event.h"
26#include "base/trace_event/trace_event_synthetic_delay.h"
[email protected]d37231fa2010-04-09 21:16:0227#include "build/build_config.h"
[email protected]96449d2c2009-11-25 00:01:3228#define GLES2_GPU_SERVICE 1
[email protected]f4390962013-06-11 07:29:2229#include "gpu/command_buffer/common/debug_marker_manager.h"
[email protected]96449d2c2009-11-25 00:01:3230#include "gpu/command_buffer/common/gles2_cmd_format.h"
31#include "gpu/command_buffer/common/gles2_cmd_utils.h"
[email protected]066849e32010-05-03 19:14:1032#include "gpu/command_buffer/common/id_allocator.h"
[email protected]2ad674132013-06-05 07:48:5133#include "gpu/command_buffer/common/mailbox.h"
[email protected]f4390962013-06-11 07:29:2234#include "gpu/command_buffer/service/async_pixel_transfer_delegate.h"
35#include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
[email protected]3916c97e2010-02-25 03:20:5036#include "gpu/command_buffer/service/buffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3237#include "gpu/command_buffer/service/cmd_buffer_engine.h"
[email protected]3916c97e2010-02-25 03:20:5038#include "gpu/command_buffer/service/context_group.h"
[email protected]e259eb412012-10-13 05:47:2439#include "gpu/command_buffer/service/context_state.h"
[email protected]d3eba342013-04-18 21:11:5040#include "gpu/command_buffer/service/error_state.h"
[email protected]915a59a12010-09-30 21:29:1141#include "gpu/command_buffer/service/feature_info.h"
[email protected]a25fa872010-03-25 02:57:5842#include "gpu/command_buffer/service/framebuffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3243#include "gpu/command_buffer/service/gl_utils.h"
sievers2384f2b2014-11-18 02:10:3544#include "gpu/command_buffer/service/gles2_cmd_clear_framebuffer.h"
[email protected]43410e92012-04-20 17:06:2845#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
[email protected]ba3176a2009-12-16 18:19:4646#include "gpu/command_buffer/service/gles2_cmd_validation.h"
[email protected]8f9b8dd2013-09-12 18:05:1347#include "gpu/command_buffer/service/gpu_state_tracer.h"
[email protected]e844ae22012-01-14 03:36:2648#include "gpu/command_buffer/service/gpu_switches.h"
[email protected]fb97b662013-02-20 23:02:1449#include "gpu/command_buffer/service/gpu_tracer.h"
[email protected]09d50362012-10-18 20:54:3750#include "gpu/command_buffer/service/image_manager.h"
[email protected]78b514b2012-05-01 21:50:5951#include "gpu/command_buffer/service/mailbox_manager.h"
[email protected]ff6493f2012-07-31 19:52:2552#include "gpu/command_buffer/service/memory_tracking.h"
[email protected]a93bb842010-02-16 23:03:4753#include "gpu/command_buffer/service/program_manager.h"
[email protected]882ba1e22012-03-08 19:02:5354#include "gpu/command_buffer/service/query_manager.h"
[email protected]a25fa872010-03-25 02:57:5855#include "gpu/command_buffer/service/renderbuffer_manager.h"
[email protected]a93bb842010-02-16 23:03:4756#include "gpu/command_buffer/service/shader_manager.h"
[email protected]a550584e2010-09-17 18:01:4557#include "gpu/command_buffer/service/shader_translator.h"
[email protected]87fb6ab2012-06-13 22:28:0458#include "gpu/command_buffer/service/shader_translator_cache.h"
[email protected]a93bb842010-02-16 23:03:4759#include "gpu/command_buffer/service/texture_manager.h"
orglofchcad5a6742014-11-07 19:51:1260#include "gpu/command_buffer/service/valuebuffer_manager.h"
[email protected]944b62f32012-09-27 02:20:4661#include "gpu/command_buffer/service/vertex_array_manager.h"
[email protected]f4390962013-06-11 07:29:2262#include "gpu/command_buffer/service/vertex_attrib_manager.h"
[email protected]6896d7f2014-04-28 20:24:1563#include "third_party/smhasher/src/City.h"
[email protected]5a36dc132013-07-23 23:17:5564#include "ui/gl/gl_fence.h"
[email protected]09d50362012-10-18 20:54:3765#include "ui/gl/gl_image.h"
[email protected]c9e2cbbb2012-05-12 21:17:2766#include "ui/gl/gl_implementation.h"
67#include "ui/gl/gl_surface.h"
[email protected]423e644f2013-06-19 00:48:2768
[email protected]e51bdf32011-11-23 22:21:4669#if defined(OS_MACOSX)
[email protected]c3a6b4a2014-06-04 09:25:5370#include <IOSurface/IOSurfaceAPI.h>
71// Note that this must be included after gl_bindings.h to avoid conflicts.
72#include <OpenGL/CGLIOSurface.h>
[email protected]e51bdf32011-11-23 22:21:4673#endif
[email protected]de17df392010-04-23 21:09:4174
[email protected]6eb775352013-08-27 05:57:1675#if defined(OS_WIN)
76#include "base/win/win_util.h"
77#endif
78
[email protected]a7a27ace2009-12-12 00:11:2579namespace gpu {
[email protected]96449d2c2009-11-25 00:01:3280namespace gles2 {
81
[email protected]f0d74742011-10-03 16:31:0482namespace {
[email protected]693ca512012-11-13 18:09:1383
[email protected]f0d74742011-10-03 16:31:0484static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
[email protected]70dc60932013-06-04 03:33:4985static const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
[email protected]aff39ac82013-06-08 04:53:1386static const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
[email protected]93c2fd82014-04-16 02:46:0687static const char kEXTShaderTextureLodExtension[] = "GL_EXT_shader_texture_lod";
[email protected]693ca512012-11-13 18:09:1388
[email protected]448e459e2013-06-12 17:00:4189static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
90 GLint rangeMax,
91 GLint precision) {
92 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
93}
94
[email protected]8dc1bf92013-03-12 03:58:2195static void GetShaderPrecisionFormatImpl(GLenum shader_type,
96 GLenum precision_type,
97 GLint *range, GLint *precision) {
98 switch (precision_type) {
99 case GL_LOW_INT:
100 case GL_MEDIUM_INT:
101 case GL_HIGH_INT:
102 // These values are for a 32-bit twos-complement integer format.
103 range[0] = 31;
104 range[1] = 30;
105 *precision = 0;
106 break;
107 case GL_LOW_FLOAT:
108 case GL_MEDIUM_FLOAT:
109 case GL_HIGH_FLOAT:
110 // These values are for an IEEE single-precision floating-point format.
111 range[0] = 127;
112 range[1] = 127;
113 *precision = 23;
114 break;
115 default:
116 NOTREACHED();
117 break;
118 }
119
[email protected]8af4d5e2013-03-15 23:55:33120 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
121 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) {
[email protected]8dc1bf92013-03-12 03:58:21122 // This function is sometimes defined even though it's really just
123 // a stub, so we need to set range and precision as if it weren't
124 // defined before calling it.
[email protected]501b57402013-03-14 22:21:44125 // On Mac OS with some GPUs, calling this generates a
126 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
127 // platforms.
[email protected]8dc1bf92013-03-12 03:58:21128 glGetShaderPrecisionFormat(shader_type, precision_type,
129 range, precision);
[email protected]448e459e2013-06-12 17:00:41130
131 // TODO(brianderson): Make the following official workarounds.
132
133 // Some drivers have bugs where they report the ranges as a negative number.
134 // Taking the absolute value here shouldn't hurt because negative numbers
135 // aren't expected anyway.
136 range[0] = abs(range[0]);
137 range[1] = abs(range[1]);
138
139 // If the driver reports a precision for highp float that isn't actually
140 // highp, don't pretend like it's supported because shader compilation will
141 // fail anyway.
142 if (precision_type == GL_HIGH_FLOAT &&
143 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
144 range[0] = 0;
145 range[1] = 0;
146 *precision = 0;
147 }
[email protected]8dc1bf92013-03-12 03:58:21148 }
149}
150
[email protected]d286ebbc2014-07-03 17:19:10151static gfx::OverlayTransform GetGFXOverlayTransform(GLenum plane_transform) {
152 switch (plane_transform) {
153 case GL_OVERLAY_TRANSFORM_NONE_CHROMIUM:
154 return gfx::OVERLAY_TRANSFORM_NONE;
155 case GL_OVERLAY_TRANSFORM_FLIP_HORIZONTAL_CHROMIUM:
156 return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL;
157 case GL_OVERLAY_TRANSFORM_FLIP_VERTICAL_CHROMIUM:
158 return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL;
159 case GL_OVERLAY_TRANSFORM_ROTATE_90_CHROMIUM:
160 return gfx::OVERLAY_TRANSFORM_ROTATE_90;
161 case GL_OVERLAY_TRANSFORM_ROTATE_180_CHROMIUM:
162 return gfx::OVERLAY_TRANSFORM_ROTATE_180;
163 case GL_OVERLAY_TRANSFORM_ROTATE_270_CHROMIUM:
164 return gfx::OVERLAY_TRANSFORM_ROTATE_270;
165 default:
166 return gfx::OVERLAY_TRANSFORM_INVALID;
167 }
168}
169
[email protected]b04e24c2013-01-08 18:35:25170} // namespace
[email protected]f0d74742011-10-03 16:31:04171
[email protected]6217d392010-03-25 22:08:35172class GLES2DecoderImpl;
173
[email protected]ab09b612013-03-11 22:11:51174// Local versions of the SET_GL_ERROR macros
175#define LOCAL_SET_GL_ERROR(error, function_name, msg) \
[email protected]d3eba342013-04-18 21:11:50176 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
[email protected]ab09b612013-03-11 22:11:51177#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
[email protected]d3eba342013-04-18 21:11:50178 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
179 function_name, value, label)
[email protected]ab09b612013-03-11 22:11:51180#define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \
[email protected]d3eba342013-04-18 21:11:50181 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \
182 function_name, pname)
[email protected]ab09b612013-03-11 22:11:51183#define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
[email protected]d3eba342013-04-18 21:11:50184 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \
185 function_name)
[email protected]ab09b612013-03-11 22:11:51186#define LOCAL_PEEK_GL_ERROR(function_name) \
[email protected]d3eba342013-04-18 21:11:50187 ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51188#define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
[email protected]d3eba342013-04-18 21:11:50189 ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51190#define LOCAL_PERFORMANCE_WARNING(msg) \
191 PerformanceWarning(__FILE__, __LINE__, msg)
192#define LOCAL_RENDER_WARNING(msg) \
193 RenderWarning(__FILE__, __LINE__, msg)
194
[email protected]07f54fcc2009-12-22 02:46:30195// Check that certain assumptions the code makes are true. There are places in
196// the code where shared memory is passed direclty to GL. Example, glUniformiv,
197// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
198// a few others) are 32bits. If they are not 32bits the code will have to change
199// to call those GL functions with service side memory and then copy the results
200// to shared memory, converting the sizes.
mostynb7f032092014-12-20 00:36:44201static_assert(sizeof(GLint) == sizeof(uint32), // NOLINT
202 "GLint should be the same size as uint32");
203static_assert(sizeof(GLsizei) == sizeof(uint32), // NOLINT
204 "GLsizei should be the same size as uint32");
205static_assert(sizeof(GLfloat) == sizeof(float), // NOLINT
206 "GLfloat should be the same size as float");
[email protected]07f54fcc2009-12-22 02:46:30207
[email protected]43f28f832010-02-03 02:28:48208// TODO(kbr): the use of this anonymous namespace core dumps the
209// linker on Mac OS X 10.6 when the symbol ordering file is used
210// namespace {
[email protected]96449d2c2009-11-25 00:01:32211
212// Returns the address of the first byte after a struct.
213template <typename T>
214const void* AddressAfterStruct(const T& pod) {
215 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
216}
217
[email protected]07f54fcc2009-12-22 02:46:30218// Returns the address of the frst byte after the struct or NULL if size >
219// immediate_data_size.
[email protected]96449d2c2009-11-25 00:01:32220template <typename RETURN_TYPE, typename COMMAND_TYPE>
[email protected]07f54fcc2009-12-22 02:46:30221RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
222 uint32 size,
223 uint32 immediate_data_size) {
224 return (size <= immediate_data_size) ?
225 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
226 NULL;
[email protected]96449d2c2009-11-25 00:01:32227}
228
[email protected]07f54fcc2009-12-22 02:46:30229// Computes the data size for certain gl commands like glUniform.
[email protected]a76b0052010-03-05 00:33:18230bool ComputeDataSize(
[email protected]96449d2c2009-11-25 00:01:32231 GLuint count,
232 size_t size,
[email protected]a76b0052010-03-05 00:33:18233 unsigned int elements_per_unit,
234 uint32* dst) {
235 uint32 value;
236 if (!SafeMultiplyUint32(count, size, &value)) {
237 return false;
238 }
239 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
240 return false;
241 }
242 *dst = value;
243 return true;
[email protected]96449d2c2009-11-25 00:01:32244}
245
[email protected]258a3313f2011-10-18 20:13:57246// Return true if a character belongs to the ASCII subset as defined in
247// GLSL ES 1.0 spec section 3.1.
248static bool CharacterIsValidForGLES(unsigned char c) {
249 // Printing characters are valid except " $ ` @ \ ' DEL.
250 if (c >= 32 && c <= 126 &&
251 c != '"' &&
252 c != '$' &&
253 c != '`' &&
254 c != '@' &&
255 c != '\\' &&
256 c != '\'') {
257 return true;
258 }
259 // Horizontal tab, line feed, vertical tab, form feed, carriage return
260 // are also valid.
261 if (c >= 9 && c <= 13) {
262 return true;
263 }
264
265 return false;
266}
267
268static bool StringIsValidForGLES(const char* str) {
269 for (; *str; ++str) {
270 if (!CharacterIsValidForGLES(*str)) {
271 return false;
272 }
273 }
274 return true;
275}
276
[email protected]6217d392010-03-25 22:08:35277// This class prevents any GL errors that occur when it is in scope from
278// being reported to the client.
279class ScopedGLErrorSuppressor {
280 public:
[email protected]ab09b612013-03-11 22:11:51281 explicit ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:30282 const char* function_name, ErrorState* error_state);
[email protected]6217d392010-03-25 22:08:35283 ~ScopedGLErrorSuppressor();
284 private:
[email protected]ab09b612013-03-11 22:11:51285 const char* function_name_;
[email protected]40621eb52013-10-08 15:40:30286 ErrorState* error_state_;
[email protected]6217d392010-03-25 22:08:35287 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
288};
289
[email protected]2b10c02d2014-01-29 16:43:02290// Temporarily changes a decoder's bound texture and restore it when this
[email protected]6217d392010-03-25 22:08:35291// object goes out of scope. Also temporarily switches to using active texture
292// unit zero in case the client has changed that to something invalid.
[email protected]2b10c02d2014-01-29 16:43:02293class ScopedTextureBinder {
[email protected]6217d392010-03-25 22:08:35294 public:
[email protected]00c2cf92014-03-14 00:08:37295 explicit ScopedTextureBinder(ContextState* state, GLuint id, GLenum target);
[email protected]2b10c02d2014-01-29 16:43:02296 ~ScopedTextureBinder();
[email protected]6217d392010-03-25 22:08:35297
298 private:
[email protected]ce296892013-10-24 22:04:36299 ContextState* state_;
[email protected]2b10c02d2014-01-29 16:43:02300 GLenum target_;
301 DISALLOW_COPY_AND_ASSIGN(ScopedTextureBinder);
[email protected]6217d392010-03-25 22:08:35302};
303
304// Temporarily changes a decoder's bound render buffer and restore it when this
305// object goes out of scope.
306class ScopedRenderBufferBinder {
307 public:
[email protected]00c2cf92014-03-14 00:08:37308 explicit ScopedRenderBufferBinder(ContextState* state, GLuint id);
[email protected]6217d392010-03-25 22:08:35309 ~ScopedRenderBufferBinder();
310
311 private:
[email protected]18e785a2013-10-09 03:29:41312 ContextState* state_;
[email protected]6217d392010-03-25 22:08:35313 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
314};
315
316// Temporarily changes a decoder's bound frame buffer and restore it when this
317// object goes out of scope.
318class ScopedFrameBufferBinder {
319 public:
[email protected]00c2cf92014-03-14 00:08:37320 explicit ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
[email protected]6217d392010-03-25 22:08:35321 ~ScopedFrameBufferBinder();
322
323 private:
324 GLES2DecoderImpl* decoder_;
325 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
326};
327
[email protected]34ff8b0c2010-10-01 20:06:02328// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52329// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27330// if it is bound or enforce_internal_framebuffer is true. If internal is
331// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02332class ScopedResolvedFrameBufferBinder {
333 public:
[email protected]00c2cf92014-03-14 00:08:37334 explicit ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
335 bool enforce_internal_framebuffer,
336 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02337 ~ScopedResolvedFrameBufferBinder();
338
339 private:
340 GLES2DecoderImpl* decoder_;
341 bool resolve_and_bind_;
342 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
343};
344
[email protected]00c2cf92014-03-14 00:08:37345class ScopedModifyPixels {
346 public:
347 explicit ScopedModifyPixels(TextureRef* ref);
348 ~ScopedModifyPixels();
349
350 private:
351 TextureRef* ref_;
352};
353
354ScopedModifyPixels::ScopedModifyPixels(TextureRef* ref) : ref_(ref) {
355 if (ref_)
356 ref_->texture()->OnWillModifyPixels();
357}
358
359ScopedModifyPixels::~ScopedModifyPixels() {
360 if (ref_)
361 ref_->texture()->OnDidModifyPixels();
362}
363
364class ScopedRenderTo {
365 public:
366 explicit ScopedRenderTo(Framebuffer* framebuffer);
367 ~ScopedRenderTo();
368
369 private:
370 const Framebuffer* framebuffer_;
371};
372
373ScopedRenderTo::ScopedRenderTo(Framebuffer* framebuffer)
374 : framebuffer_(framebuffer) {
375 if (framebuffer)
376 framebuffer_->OnWillRenderTo();
377}
378
379ScopedRenderTo::~ScopedRenderTo() {
380 if (framebuffer_)
381 framebuffer_->OnDidRenderTo();
382}
383
[email protected]6217d392010-03-25 22:08:35384// Encapsulates an OpenGL texture.
[email protected]ed9f9cd2013-02-27 21:12:35385class BackTexture {
[email protected]6217d392010-03-25 22:08:35386 public:
[email protected]ce296892013-10-24 22:04:36387 explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35388 ~BackTexture();
[email protected]6217d392010-03-25 22:08:35389
390 // Create a new render texture.
391 void Create();
392
393 // Set the initial size and format of a render texture or resize it.
[email protected]678a73f2012-12-19 19:22:09394 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
[email protected]6217d392010-03-25 22:08:35395
396 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58397 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35398
399 // Destroy the render texture. This must be explicitly called before
400 // destroying this object.
401 void Destroy();
402
[email protected]97872062010-11-03 19:07:05403 // Invalidate the texture. This can be used when a context is lost and it is
404 // not possible to make it current in order to free the resource.
405 void Invalidate();
406
[email protected]6217d392010-03-25 22:08:35407 GLuint id() const {
408 return id_;
409 }
410
[email protected]d37231fa2010-04-09 21:16:02411 gfx::Size size() const {
412 return size_;
413 }
414
[email protected]6217d392010-03-25 22:08:35415 private:
[email protected]ff6493f2012-07-31 19:52:25416 MemoryTypeTracker memory_tracker_;
[email protected]ce296892013-10-24 22:04:36417 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48418 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35419 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02420 gfx::Size size_;
[email protected]ed9f9cd2013-02-27 21:12:35421 DISALLOW_COPY_AND_ASSIGN(BackTexture);
[email protected]6217d392010-03-25 22:08:35422};
423
424// Encapsulates an OpenGL render buffer of any format.
[email protected]ed9f9cd2013-02-27 21:12:35425class BackRenderbuffer {
[email protected]6217d392010-03-25 22:08:35426 public:
[email protected]d5a28e452013-10-10 01:01:40427 explicit BackRenderbuffer(
428 RenderbufferManager* renderbuffer_manager,
429 MemoryTracker* memory_tracker,
430 ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35431 ~BackRenderbuffer();
[email protected]6217d392010-03-25 22:08:35432
433 // Create a new render buffer.
434 void Create();
435
436 // Set the initial size and format of a render buffer or resize it.
[email protected]f42f05b2013-11-15 21:46:18437 bool AllocateStorage(const FeatureInfo* feature_info,
438 const gfx::Size& size,
439 GLenum format,
440 GLsizei samples);
[email protected]6217d392010-03-25 22:08:35441
442 // Destroy the render buffer. This must be explicitly called before destroying
443 // this object.
444 void Destroy();
445
[email protected]97872062010-11-03 19:07:05446 // Invalidate the render buffer. This can be used when a context is lost and
447 // it is not possible to make it current in order to free the resource.
448 void Invalidate();
449
[email protected]6217d392010-03-25 22:08:35450 GLuint id() const {
451 return id_;
452 }
453
454 private:
[email protected]d5a28e452013-10-10 01:01:40455 RenderbufferManager* renderbuffer_manager_;
[email protected]ff6493f2012-07-31 19:52:25456 MemoryTypeTracker memory_tracker_;
[email protected]d5a28e452013-10-10 01:01:40457 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48458 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35459 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35460 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
[email protected]6217d392010-03-25 22:08:35461};
462
463// Encapsulates an OpenGL frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35464class BackFramebuffer {
[email protected]6217d392010-03-25 22:08:35465 public:
[email protected]ed9f9cd2013-02-27 21:12:35466 explicit BackFramebuffer(GLES2DecoderImpl* decoder);
467 ~BackFramebuffer();
[email protected]6217d392010-03-25 22:08:35468
469 // Create a new frame buffer.
470 void Create();
471
472 // Attach a color render buffer to a frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35473 void AttachRenderTexture(BackTexture* texture);
[email protected]6217d392010-03-25 22:08:35474
[email protected]b9363b22010-06-09 22:06:15475 // Attach a render buffer to a frame buffer. Note that this unbinds any
476 // currently bound frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35477 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35478
[email protected]6217d392010-03-25 22:08:35479 // Destroy the frame buffer. This must be explicitly called before destroying
480 // this object.
481 void Destroy();
482
[email protected]97872062010-11-03 19:07:05483 // Invalidate the frame buffer. This can be used when a context is lost and it
484 // is not possible to make it current in order to free the resource.
485 void Invalidate();
486
[email protected]6217d392010-03-25 22:08:35487 // See glCheckFramebufferStatusEXT.
488 GLenum CheckStatus();
489
490 GLuint id() const {
491 return id_;
492 }
493
494 private:
495 GLES2DecoderImpl* decoder_;
496 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35497 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
[email protected]6217d392010-03-25 22:08:35498};
[email protected]34ff8b0c2010-10-01 20:06:02499
[email protected]5a36dc132013-07-23 23:17:55500struct FenceCallback {
501 explicit FenceCallback()
502 : fence(gfx::GLFence::Create()) {
503 DCHECK(fence);
504 }
[email protected]5a36dc132013-07-23 23:17:55505 std::vector<base::Closure> callbacks;
506 scoped_ptr<gfx::GLFence> fence;
507};
508
[email protected]e3c4a9ab2014-03-31 09:07:02509class AsyncUploadTokenCompletionObserver
510 : public AsyncPixelTransferCompletionObserver {
511 public:
512 explicit AsyncUploadTokenCompletionObserver(uint32 async_upload_token)
513 : async_upload_token_(async_upload_token) {
514 }
515
dcheng1f4d1d72014-10-21 16:21:58516 void DidComplete(const AsyncMemoryParams& mem_params) override {
dcheng6ef3c5552014-08-30 05:34:19517 DCHECK(mem_params.buffer().get());
[email protected]e3c4a9ab2014-03-31 09:07:02518 void* data = mem_params.GetDataAddress();
519 AsyncUploadSync* sync = static_cast<AsyncUploadSync*>(data);
520 sync->SetAsyncUploadToken(async_upload_token_);
521 }
522
523 private:
dcheng1f4d1d72014-10-21 16:21:58524 ~AsyncUploadTokenCompletionObserver() override {}
[email protected]e3c4a9ab2014-03-31 09:07:02525
526 uint32 async_upload_token_;
527
528 DISALLOW_COPY_AND_ASSIGN(AsyncUploadTokenCompletionObserver);
529};
530
[email protected]43f28f832010-02-03 02:28:48531// } // anonymous namespace.
[email protected]96449d2c2009-11-25 00:01:32532
[email protected]efc87712014-07-09 00:22:47533// static
534const unsigned int GLES2Decoder::kDefaultStencilMask =
535 static_cast<unsigned int>(-1);
536
[email protected]ddb1e5a2010-12-13 20:10:45537bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
538 uint32* service_texture_id) {
539 return false;
540}
541
[email protected]a3ded6d2010-10-19 06:44:39542GLES2Decoder::GLES2Decoder()
[email protected]55e136f2013-04-03 18:50:06543 : initialized_(false),
544 debug_(false),
zmo84c08202014-11-23 15:28:40545 log_commands_(false),
546 unsafe_es3_apis_enabled_(false) {
[email protected]96449d2c2009-11-25 00:01:32547}
548
[email protected]3916c97e2010-02-25 03:20:50549GLES2Decoder::~GLES2Decoder() {
550}
551
[email protected]cac16542014-01-15 17:53:51552void GLES2Decoder::BeginDecoding() {}
553
554void GLES2Decoder::EndDecoding() {}
555
[email protected]f39f4b3f2010-05-12 17:04:08556// This class implements GLES2Decoder so we don't have to expose all the GLES2
557// cmd stuff to outside this class.
[email protected]91c94eb2013-10-22 10:32:54558class GLES2DecoderImpl : public GLES2Decoder,
[email protected]828a3932014-04-02 14:43:13559 public FramebufferManager::TextureDetachObserver,
560 public ErrorStateClient {
[email protected]f39f4b3f2010-05-12 17:04:08561 public:
[email protected]aa7666122011-09-02 19:45:52562 explicit GLES2DecoderImpl(ContextGroup* group);
dcheng1f4d1d72014-10-21 16:21:58563 ~GLES2DecoderImpl() override;
[email protected]f39f4b3f2010-05-12 17:04:08564
[email protected]96449d2c2009-11-25 00:01:32565 // Overridden from AsyncAPIInterface.
dcheng1f4d1d72014-10-21 16:21:58566 Error DoCommand(unsigned int command,
567 unsigned int arg_count,
568 const void* args) override;
[email protected]96449d2c2009-11-25 00:01:32569
dcheng1f4d1d72014-10-21 16:21:58570 error::Error DoCommands(unsigned int num_commands,
571 const void* buffer,
572 int num_entries,
573 int* entries_processed) override;
vmiura8266ca72014-09-09 21:37:00574
vmiura1c2b1de2014-09-19 19:03:24575 template <bool DebugImpl>
576 error::Error DoCommandsImpl(unsigned int num_commands,
577 const void* buffer,
578 int num_entries,
579 int* entries_processed);
580
[email protected]96449d2c2009-11-25 00:01:32581 // Overridden from AsyncAPIInterface.
dcheng1f4d1d72014-10-21 16:21:58582 const char* GetCommandName(unsigned int command_id) const override;
[email protected]96449d2c2009-11-25 00:01:32583
584 // Overridden from GLES2Decoder.
dcheng1f4d1d72014-10-21 16:21:58585 bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
586 const scoped_refptr<gfx::GLContext>& context,
587 bool offscreen,
588 const gfx::Size& size,
589 const DisallowedFeatures& disallowed_features,
590 const std::vector<int32>& attribs) override;
591 void Destroy(bool have_context) override;
592 void SetSurface(const scoped_refptr<gfx::GLSurface>& surface) override;
593 void ProduceFrontBuffer(const Mailbox& mailbox) override;
594 bool ResizeOffscreenFrameBuffer(const gfx::Size& size) override;
[email protected]9a5afa432011-07-22 18:16:39595 void UpdateParentTextureInfo();
dcheng1f4d1d72014-10-21 16:21:58596 bool MakeCurrent() override;
597 GLES2Util* GetGLES2Util() override { return &util_; }
598 gfx::GLContext* GetGLContext() override { return context_.get(); }
599 ContextGroup* GetContextGroup() override { return group_.get(); }
600 Capabilities GetCapabilities() override;
601 void RestoreState(const ContextState* prev_state) override;
[email protected]29a4d902013-02-26 20:18:06602
dcheng1f4d1d72014-10-21 16:21:58603 void RestoreActiveTexture() const override { state_.RestoreActiveTexture(); }
604 void RestoreAllTextureUnitBindings(
mohan.reddy5e1b8952014-10-08 01:38:17605 const ContextState* prev_state) const override {
[email protected]5baa86bc2014-01-16 04:33:16606 state_.RestoreAllTextureUnitBindings(prev_state);
[email protected]217004512013-05-10 21:25:55607 }
dcheng1f4d1d72014-10-21 16:21:58608 void RestoreActiveTextureUnitBinding(unsigned int target) const override {
[email protected]4b2d2b262014-03-21 22:05:27609 state_.RestoreActiveTextureUnitBinding(target);
610 }
dcheng1f4d1d72014-10-21 16:21:58611 void RestoreBufferBindings() const override {
[email protected]29a4d902013-02-26 20:18:06612 state_.RestoreBufferBindings();
613 }
dcheng1f4d1d72014-10-21 16:21:58614 void RestoreGlobalState() const override { state_.RestoreGlobalState(NULL); }
615 void RestoreProgramBindings() const override {
[email protected]29a4d902013-02-26 20:18:06616 state_.RestoreProgramBindings();
617 }
dcheng1f4d1d72014-10-21 16:21:58618 void RestoreTextureUnitBindings(unsigned unit) const override {
[email protected]5baa86bc2014-01-16 04:33:16619 state_.RestoreTextureUnitBindings(unit, NULL);
[email protected]29a4d902013-02-26 20:18:06620 }
dcheng1f4d1d72014-10-21 16:21:58621 void RestoreFramebufferBindings() const override;
622 void RestoreRenderbufferBindings() override;
623 void RestoreTextureState(unsigned service_id) const override;
[email protected]29a4d902013-02-26 20:18:06624
dcheng1f4d1d72014-10-21 16:21:58625 void ClearAllAttributes() const override;
626 void RestoreAllAttributes() const override;
[email protected]cd2ef752014-02-12 23:16:03627
dcheng1f4d1d72014-10-21 16:21:58628 QueryManager* GetQueryManager() override { return query_manager_.get(); }
629 VertexArrayManager* GetVertexArrayManager() override {
[email protected]944b62f32012-09-27 02:20:46630 return vertex_array_manager_.get();
631 }
dcheng1f4d1d72014-10-21 16:21:58632 ImageManager* GetImageManager() override { return image_manager_.get(); }
orglofch33edd842014-12-03 05:32:15633
634 ValuebufferManager* GetValuebufferManager() override {
635 return valuebuffer_manager();
636 }
637
revemancc241eb2014-11-11 03:30:37638 bool ProcessPendingQueries(bool did_finish) override;
orglofch33edd842014-12-03 05:32:15639
dcheng1f4d1d72014-10-21 16:21:58640 bool HasMoreIdleWork() override;
641 void PerformIdleWork() override;
[email protected]43f28f832010-02-03 02:28:48642
dcheng1f4d1d72014-10-21 16:21:58643 void WaitForReadPixels(base::Closure callback) override;
[email protected]5a36dc132013-07-23 23:17:55644
dcheng1f4d1d72014-10-21 16:21:58645 void SetResizeCallback(
mohan.reddy5e1b8952014-10-08 01:38:17646 const base::Callback<void(gfx::Size, float)>& callback) override;
[email protected]22f320a2011-08-30 01:17:00647
dcheng1f4d1d72014-10-21 16:21:58648 Logger* GetLogger() override;
[email protected]cac16542014-01-15 17:53:51649
dcheng1f4d1d72014-10-21 16:21:58650 void BeginDecoding() override;
651 void EndDecoding() override;
[email protected]cac16542014-01-15 17:53:51652
dcheng1f4d1d72014-10-21 16:21:58653 ErrorState* GetErrorState() override;
654 const ContextState* GetContextState() override { return &state_; }
[email protected]1d82e822013-04-10 21:32:32655
dcheng1f4d1d72014-10-21 16:21:58656 void SetShaderCacheCallback(const ShaderCacheCallback& callback) override;
657 void SetWaitSyncPointCallback(const WaitSyncPointCallback& callback) override;
[email protected]22f320a2011-08-30 01:17:00658
dcheng1f4d1d72014-10-21 16:21:58659 AsyncPixelTransferManager* GetAsyncPixelTransferManager() override;
660 void ResetAsyncPixelTransferManagerForTest() override;
661 void SetAsyncPixelTransferManagerForTest(
mohan.reddy5e1b8952014-10-08 01:38:17662 AsyncPixelTransferManager* manager) override;
dcheng1f4d1d72014-10-21 16:21:58663 void SetIgnoreCachedStateForTest(bool ignore) override;
[email protected]69a8701e2013-03-07 21:31:09664 void ProcessFinishedAsyncTransfers();
[email protected]32145a92012-12-17 09:01:59665
dcheng1f4d1d72014-10-21 16:21:58666 bool GetServiceTextureId(uint32 client_texture_id,
667 uint32* service_texture_id) override;
[email protected]43f28f832010-02-03 02:28:48668
dcheng1f4d1d72014-10-21 16:21:58669 uint32 GetTextureUploadCount() override;
670 base::TimeDelta GetTotalTextureUploadTime() override;
671 base::TimeDelta GetTotalProcessingCommandsTime() override;
672 void AddProcessingCommandsTime(base::TimeDelta) override;
[email protected]63b465922012-09-06 02:04:52673
[email protected]8e3e0662010-08-23 18:46:30674 // Restores the current state to the user's settings.
675 void RestoreCurrentFramebufferBindings();
[email protected]8e3e0662010-08-23 18:46:30676
[email protected]297ca1c2011-06-20 23:08:46677 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
678 void ApplyDirtyState();
679
680 // These check the state of the currently bound framebuffer or the
681 // backbuffer if no framebuffer is bound.
[email protected]f3b191b2013-06-19 03:43:54682 // If all_draw_buffers is false, only check with COLOR_ATTACHMENT0, otherwise
683 // check with all attached and enabled color attachments.
684 bool BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers);
[email protected]297ca1c2011-06-20 23:08:46685 bool BoundFramebufferHasDepthAttachment();
686 bool BoundFramebufferHasStencilAttachment();
687
dcheng1f4d1d72014-10-21 16:21:58688 error::ContextLostReason GetContextLostReason() override;
[email protected]38d139d2011-07-14 00:38:43689
[email protected]91c94eb2013-10-22 10:32:54690 // Overridden from FramebufferManager::TextureDetachObserver:
dcheng1f4d1d72014-10-21 16:21:58691 void OnTextureRefDetachedFromFramebuffer(TextureRef* texture) override;
[email protected]91c94eb2013-10-22 10:32:54692
[email protected]828a3932014-04-02 14:43:13693 // Overriden from ErrorStateClient.
oetuaho37cc50e2014-10-31 11:19:20694 void OnContextLostError() override;
dcheng1f4d1d72014-10-21 16:21:58695 void OnOutOfMemoryError() override;
[email protected]828a3932014-04-02 14:43:13696
[email protected]8875a5f2014-06-27 08:33:47697 // Ensure Renderbuffer corresponding to last DoBindRenderbuffer() is bound.
698 void EnsureRenderbufferBound();
699
[email protected]f42f05b2013-11-15 21:46:18700 // Helpers to facilitate calling into compatible extensions.
701 static void RenderbufferStorageMultisampleHelper(
702 const FeatureInfo* feature_info,
703 GLenum target,
704 GLsizei samples,
705 GLenum internal_format,
706 GLsizei width,
707 GLsizei height);
708
709 void BlitFramebufferHelper(GLint srcX0,
710 GLint srcY0,
711 GLint srcX1,
712 GLint srcY1,
713 GLint dstX0,
714 GLint dstY0,
715 GLint dstX1,
716 GLint dstY1,
717 GLbitfield mask,
718 GLenum filter);
[email protected]345ba902013-11-14 21:39:00719
[email protected]96449d2c2009-11-25 00:01:32720 private:
[email protected]70d34263c2013-01-09 00:27:45721 friend class ScopedFrameBufferBinder;
[email protected]34ff8b0c2010-10-01 20:06:02722 friend class ScopedResolvedFrameBufferBinder;
[email protected]ed9f9cd2013-02-27 21:12:35723 friend class BackFramebuffer;
[email protected]6217d392010-03-25 22:08:35724
[email protected]c2f8c8402010-12-06 18:07:24725 // Initialize or re-initialize the shader translator.
726 bool InitializeShaderTranslator();
727
[email protected]302ce6d2011-07-07 23:28:11728 void UpdateCapabilities();
729
[email protected]ae51d192010-04-27 00:48:03730 // Helpers for the glGen and glDelete functions.
731 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
732 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
733 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
734 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
735 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
736 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
737 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
738 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
orglofchcad5a6742014-11-07 19:51:12739 bool GenValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* client_ids);
740 void DeleteValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53741 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
742 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46743 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
744 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47745
[email protected]e3c4a9ab2014-03-31 09:07:02746 // Helper for async upload token completion notification callback.
747 base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token,
748 uint32 sync_data_shm_id,
749 uint32 sync_data_shm_offset);
750
751
752
[email protected]70d34263c2013-01-09 00:27:45753 // Workarounds
754 void OnFboChanged() const;
[email protected]28718a92013-04-04 12:12:51755 void OnUseFramebuffer() const;
[email protected]70d34263c2013-01-09 00:27:45756
[email protected]3916c97e2010-02-25 03:20:50757 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50758 BufferManager* buffer_manager() {
759 return group_->buffer_manager();
760 }
761
[email protected]a25fa872010-03-25 02:57:58762 RenderbufferManager* renderbuffer_manager() {
763 return group_->renderbuffer_manager();
764 }
765
766 FramebufferManager* framebuffer_manager() {
767 return group_->framebuffer_manager();
768 }
769
orglofchcad5a6742014-11-07 19:51:12770 ValuebufferManager* valuebuffer_manager() {
771 return group_->valuebuffer_manager();
772 }
773
[email protected]3916c97e2010-02-25 03:20:50774 ProgramManager* program_manager() {
775 return group_->program_manager();
776 }
777
778 ShaderManager* shader_manager() {
779 return group_->shader_manager();
780 }
781
[email protected]03cef9b2014-04-03 15:58:14782 ShaderTranslatorCache* shader_translator_cache() {
783 return group_->shader_translator_cache();
784 }
785
[email protected]29a4d902013-02-26 20:18:06786 const TextureManager* texture_manager() const {
787 return group_->texture_manager();
788 }
789
[email protected]3916c97e2010-02-25 03:20:50790 TextureManager* texture_manager() {
791 return group_->texture_manager();
792 }
793
[email protected]78b514b2012-05-01 21:50:59794 MailboxManager* mailbox_manager() {
795 return group_->mailbox_manager();
796 }
797
[email protected]b63f1d62014-07-18 15:40:59798 ImageManager* image_manager() { return image_manager_.get(); }
[email protected]09d50362012-10-18 20:54:37799
[email protected]944b62f32012-09-27 02:20:46800 VertexArrayManager* vertex_array_manager() {
801 return vertex_array_manager_.get();
802 }
803
[email protected]7989c9e2013-01-23 06:39:26804 MemoryTracker* memory_tracker() {
805 return group_->memory_tracker();
806 }
807
808 bool EnsureGPUMemoryAvailable(size_t estimated_size) {
809 MemoryTracker* tracker = memory_tracker();
810 if (tracker) {
811 return tracker->EnsureGPUMemoryAvailable(estimated_size);
812 }
813 return true;
814 }
815
[email protected]34ff8b0c2010-10-01 20:06:02816 bool IsOffscreenBufferMultisampled() const {
817 return offscreen_target_samples_ > 1;
818 }
819
[email protected]ed9f9cd2013-02-27 21:12:35820 // Creates a Texture for the given texture.
[email protected]370eaf12013-05-18 09:19:49821 TextureRef* CreateTexture(
[email protected]ae51d192010-04-27 00:48:03822 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35823 return texture_manager()->CreateTexture(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47824 }
825
826 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]370eaf12013-05-18 09:19:49827 TextureRef* GetTexture(GLuint client_id) const {
[email protected]02965c22013-03-09 02:40:07828 return texture_manager()->GetTexture(client_id);
[email protected]a93bb842010-02-16 23:03:47829 }
830
831 // Deletes the texture info for the given texture.
[email protected]ed9f9cd2013-02-27 21:12:35832 void RemoveTexture(GLuint client_id) {
833 texture_manager()->RemoveTexture(client_id);
[email protected]3916c97e2010-02-25 03:20:50834 }
[email protected]a93bb842010-02-16 23:03:47835
[email protected]d37231fa2010-04-09 21:16:02836 // Get the size (in pixels) of the currently bound frame buffer (either FBO
837 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30838 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02839
[email protected]9edc6b22010-12-23 02:00:26840 // Get the format of the currently bound frame buffer (either FBO or regular
841 // back buffer)
[email protected]68586372013-12-11 01:27:59842 GLenum GetBoundReadFrameBufferTextureType();
[email protected]9edc6b22010-12-23 02:00:26843 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46844 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26845
[email protected]a93bb842010-02-16 23:03:47846 // Wrapper for CompressedTexImage2D commands.
847 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37848 GLenum target,
849 GLint level,
850 GLenum internal_format,
851 GLsizei width,
852 GLsizei height,
853 GLint border,
854 GLsizei image_size,
855 const void* data);
[email protected]a93bb842010-02-16 23:03:47856
[email protected]cadde4a2010-07-31 17:10:43857 // Wrapper for CompressedTexSubImage2D.
858 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37859 GLenum target,
860 GLint level,
861 GLint xoffset,
862 GLint yoffset,
863 GLsizei width,
864 GLsizei height,
865 GLenum format,
866 GLsizei imageSize,
867 const void * data);
[email protected]cadde4a2010-07-31 17:10:43868
869 // Wrapper for CopyTexImage2D.
870 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37871 GLenum target,
872 GLint level,
873 GLenum internal_format,
874 GLint x,
875 GLint y,
876 GLsizei width,
877 GLsizei height,
878 GLint border);
[email protected]cadde4a2010-07-31 17:10:43879
[email protected]6d792ee12013-05-15 00:40:56880 // Wrapper for SwapBuffers.
881 void DoSwapBuffers();
882
bajones2345c1f2014-12-09 04:45:51883 // Wrapper for SwapInterval.
884 void DoSwapInterval(int interval);
885
[email protected]cadde4a2010-07-31 17:10:43886 // Wrapper for CopyTexSubImage2D.
887 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37888 GLenum target,
889 GLint level,
890 GLint xoffset,
891 GLint yoffset,
892 GLint x,
893 GLint y,
894 GLsizei width,
895 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43896
[email protected]f598f422012-12-07 08:30:03897 // Validation for TexSubImage2D.
898 bool ValidateTexSubImage2D(
899 error::Error* error,
900 const char* function_name,
901 GLenum target,
902 GLint level,
903 GLint xoffset,
904 GLint yoffset,
905 GLsizei width,
906 GLsizei height,
907 GLenum format,
908 GLenum type,
909 const void * data);
910
[email protected]cadde4a2010-07-31 17:10:43911 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03912 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37913 GLenum target,
914 GLint level,
915 GLint xoffset,
916 GLint yoffset,
917 GLsizei width,
918 GLsizei height,
919 GLenum format,
920 GLenum type,
921 const void * data);
[email protected]cadde4a2010-07-31 17:10:43922
[email protected]32145a92012-12-17 09:01:59923 // Extra validation for async tex(Sub)Image2D.
924 bool ValidateAsyncTransfer(
925 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:47926 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:59927 GLenum target,
928 GLint level,
929 const void * data);
930
[email protected]e51bdf32011-11-23 22:21:46931 // Wrapper for TexImageIOSurface2DCHROMIUM.
932 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37933 GLenum target,
934 GLsizei width,
935 GLsizei height,
936 GLuint io_surface_id,
937 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46938
[email protected]43410e92012-04-20 17:06:28939 void DoCopyTextureCHROMIUM(
[email protected]09d50362012-10-18 20:54:37940 GLenum target,
941 GLuint source_id,
942 GLuint target_id,
943 GLint level,
[email protected]a4a6bdd12013-04-19 20:46:54944 GLenum internal_format,
945 GLenum dest_type);
[email protected]43410e92012-04-20 17:06:28946
[email protected]97dc7cbe2011-12-06 17:26:17947 // Wrapper for TexStorage2DEXT.
948 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37949 GLenum target,
950 GLint levels,
951 GLenum internal_format,
952 GLsizei width,
953 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17954
[email protected]78b514b2012-05-01 21:50:59955 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
[email protected]43f253da2014-06-10 17:51:22956 void DoProduceTextureDirectCHROMIUM(GLuint texture, GLenum target,
957 const GLbyte* key);
958 void ProduceTextureRef(std::string func_name, TextureRef* texture_ref,
959 GLenum target, const GLbyte* data);
960
[email protected]78b514b2012-05-01 21:50:59961 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
[email protected]43f253da2014-06-10 17:51:22962 void DoCreateAndConsumeTextureCHROMIUM(GLenum target, const GLbyte* key,
963 GLuint client_id);
[email protected]78b514b2012-05-01 21:50:59964
orglofchcad5a6742014-11-07 19:51:12965 bool DoIsValuebufferCHROMIUM(GLuint client_id);
966 void DoBindValueBufferCHROMIUM(GLenum target, GLuint valuebuffer);
967 void DoSubscribeValueCHROMIUM(GLenum target, GLenum subscription);
968 void DoPopulateSubscribedValuesCHROMIUM(GLenum target);
969 void DoUniformValueBufferCHROMIUM(GLint location,
970 GLenum target,
971 GLenum subscription);
972
[email protected]09d50362012-10-18 20:54:37973 void DoBindTexImage2DCHROMIUM(
974 GLenum target,
975 GLint image_id);
976 void DoReleaseTexImage2DCHROMIUM(
977 GLenum target,
978 GLint image_id);
979
[email protected]94307712012-11-16 23:26:11980 void DoTraceEndCHROMIUM(void);
981
[email protected]2f143d482013-03-14 18:04:49982 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
983
[email protected]a6a09f852014-05-23 13:05:03984 void DoLoseContextCHROMIUM(GLenum current, GLenum other);
985
kkinnunen337d59632014-08-26 10:19:57986 void DoMatrixLoadfCHROMIUM(GLenum matrix_mode, const GLfloat* matrix);
987 void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode);
988
[email protected]ed9f9cd2013-02-27 21:12:35989 // Creates a Program for the given program.
990 Program* CreateProgram(
[email protected]d685a682011-04-29 16:19:57991 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35992 return program_manager()->CreateProgram(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47993 }
994
[email protected]07f54fcc2009-12-22 02:46:30995 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35996 Program* GetProgram(GLuint client_id) {
997 return program_manager()->GetProgram(client_id);
[email protected]1d32bc82010-01-13 22:06:46998 }
[email protected]07f54fcc2009-12-22 02:46:30999
[email protected]cae20172012-12-07 00:06:191000#if defined(NDEBUG)
1001 void LogClientServiceMapping(
1002 const char* /* function_name */,
1003 GLuint /* client_id */,
1004 GLuint /* service_id */) {
1005 }
1006 template<typename T>
1007 void LogClientServiceForInfo(
1008 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
1009 }
1010#else
1011 void LogClientServiceMapping(
1012 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:261013 if (service_logging_) {
[email protected]65f7efe2013-11-28 03:11:471014 VLOG(1) << "[" << logger_.GetLogPrefix() << "] " << function_name
1015 << ": client_id = " << client_id
1016 << ", service_id = " << service_id;
[email protected]2a22fe72012-12-07 04:21:261017 }
[email protected]cae20172012-12-07 00:06:191018 }
1019 template<typename T>
1020 void LogClientServiceForInfo(
1021 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:261022 if (info) {
[email protected]cae20172012-12-07 00:06:191023 LogClientServiceMapping(function_name, client_id, info->service_id());
1024 }
1025 }
1026#endif
1027
[email protected]6b8cf1a2010-05-06 16:13:581028 // Gets the program info for the given program. If it's not a program
1029 // generates a GL error. Returns NULL if not program.
[email protected]ed9f9cd2013-02-27 21:12:351030 Program* GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:581031 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421032 Program* program = GetProgram(client_id);
1033 if (!program) {
[email protected]ed9f9cd2013-02-27 21:12:351034 if (GetShader(client_id)) {
[email protected]ab09b612013-03-11 22:11:511035 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431036 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:581037 } else {
[email protected]ab09b612013-03-11 22:11:511038 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:581039 }
1040 }
[email protected]df37b9932013-03-08 05:21:421041 LogClientServiceForInfo(program, client_id, function_name);
1042 return program;
[email protected]6b8cf1a2010-05-06 16:13:581043 }
1044
1045
[email protected]ed9f9cd2013-02-27 21:12:351046 // Creates a Shader for the given shader.
1047 Shader* CreateShader(
[email protected]d685a682011-04-29 16:19:571048 GLuint client_id,
1049 GLuint service_id,
1050 GLenum shader_type) {
[email protected]ed9f9cd2013-02-27 21:12:351051 return shader_manager()->CreateShader(
[email protected]d685a682011-04-29 16:19:571052 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:311053 }
1054
1055 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:351056 Shader* GetShader(GLuint client_id) {
1057 return shader_manager()->GetShader(client_id);
[email protected]45bf5152010-02-12 00:11:311058 }
1059
[email protected]6b8cf1a2010-05-06 16:13:581060 // Gets the shader info for the given shader. If it's not a shader generates a
1061 // GL error. Returns NULL if not shader.
[email protected]ed9f9cd2013-02-27 21:12:351062 Shader* GetShaderInfoNotProgram(
[email protected]6b8cf1a2010-05-06 16:13:581063 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421064 Shader* shader = GetShader(client_id);
1065 if (!shader) {
[email protected]ed9f9cd2013-02-27 21:12:351066 if (GetProgram(client_id)) {
[email protected]ab09b612013-03-11 22:11:511067 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431068 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:581069 } else {
[email protected]ab09b612013-03-11 22:11:511070 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431071 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:581072 }
1073 }
[email protected]df37b9932013-03-08 05:21:421074 LogClientServiceForInfo(shader, client_id, function_name);
1075 return shader;
[email protected]6b8cf1a2010-05-06 16:13:581076 }
1077
[email protected]a93bb842010-02-16 23:03:471078 // Creates a buffer info for the given buffer.
[email protected]ed9f9cd2013-02-27 21:12:351079 void CreateBuffer(GLuint client_id, GLuint service_id) {
1080 return buffer_manager()->CreateBuffer(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:471081 }
1082
[email protected]07f54fcc2009-12-22 02:46:301083 // Gets the buffer info for the given buffer.
[email protected]16ccec12013-02-28 03:40:211084 Buffer* GetBuffer(GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:071085 Buffer* buffer = buffer_manager()->GetBuffer(client_id);
1086 return buffer;
[email protected]1d32bc82010-01-13 22:06:461087 }
[email protected]07f54fcc2009-12-22 02:46:301088
[email protected]a93bb842010-02-16 23:03:471089 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
1090 // on glDeleteBuffers so we can make sure the user does not try to render
1091 // with deleted buffers.
[email protected]ed9f9cd2013-02-27 21:12:351092 void RemoveBuffer(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:471093
[email protected]a25fa872010-03-25 02:57:581094 // Creates a framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351095 void CreateFramebuffer(GLuint client_id, GLuint service_id) {
1096 return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581097 }
1098
1099 // Gets the framebuffer info for the given framebuffer.
[email protected]4d8f0dd2013-03-09 14:37:061100 Framebuffer* GetFramebuffer(GLuint client_id) {
1101 return framebuffer_manager()->GetFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581102 }
1103
1104 // Removes the framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351105 void RemoveFramebuffer(GLuint client_id) {
1106 framebuffer_manager()->RemoveFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581107 }
1108
1109 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351110 void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
1111 return renderbuffer_manager()->CreateRenderbuffer(
[email protected]ae51d192010-04-27 00:48:031112 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581113 }
1114
1115 // Gets the renderbuffer info for the given renderbuffer.
[email protected]ee2a79c32013-03-10 03:50:271116 Renderbuffer* GetRenderbuffer(GLuint client_id) {
1117 return renderbuffer_manager()->GetRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581118 }
1119
1120 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351121 void RemoveRenderbuffer(GLuint client_id) {
1122 renderbuffer_manager()->RemoveRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581123 }
1124
orglofchcad5a6742014-11-07 19:51:121125 // Creates a valuebuffer info for the given valuebuffer.
1126 void CreateValuebuffer(GLuint client_id) {
1127 return valuebuffer_manager()->CreateValuebuffer(client_id);
1128 }
1129
1130 // Gets the valuebuffer info for a given valuebuffer.
1131 Valuebuffer* GetValuebuffer(GLuint client_id) {
1132 return valuebuffer_manager()->GetValuebuffer(client_id);
1133 }
1134
1135 // Removes the valuebuffer info for the given valuebuffer.
1136 void RemoveValuebuffer(GLuint client_id) {
1137 valuebuffer_manager()->RemoveValuebuffer(client_id);
1138 }
1139
[email protected]944b62f32012-09-27 02:20:461140 // Gets the vertex attrib manager for the given vertex array.
1141 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1142 VertexAttribManager* info =
1143 vertex_array_manager()->GetVertexAttribManager(client_id);
1144 return info;
1145 }
1146
1147 // Removes the vertex attrib manager for the given vertex array.
1148 void RemoveVertexAttribManager(GLuint client_id) {
1149 vertex_array_manager()->RemoveVertexAttribManager(client_id);
1150 }
1151
1152 // Creates a vertex attrib manager for the given vertex array.
[email protected]da364812014-05-09 21:39:481153 scoped_refptr<VertexAttribManager> CreateVertexAttribManager(
1154 GLuint client_id,
1155 GLuint service_id,
1156 bool client_visible) {
1157 return vertex_array_manager()->CreateVertexAttribManager(
1158 client_id, service_id, group_->max_vertex_attribs(), client_visible);
[email protected]944b62f32012-09-27 02:20:461159 }
1160
[email protected]258a3313f2011-10-18 20:13:571161 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:331162 void DoBindUniformLocationCHROMIUM(
1163 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571164
[email protected]558847a2010-03-24 07:02:541165 error::Error GetAttribLocationHelper(
zmo4a16ff992015-02-05 22:18:411166 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1167 const std::string& name_str);
[email protected]558847a2010-03-24 07:02:541168
1169 error::Error GetUniformLocationHelper(
zmo4a16ff992015-02-05 22:18:411170 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1171 const std::string& name_str);
[email protected]558847a2010-03-24 07:02:541172
zmo5393fb52015-01-27 01:50:481173 error::Error GetFragDataLocationHelper(
zmo4a16ff992015-02-05 22:18:411174 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1175 const std::string& name_str);
zmo5393fb52015-01-27 01:50:481176
zmo1bb3d1d2015-01-21 20:29:431177 // Wrapper for glShaderSource.
1178 void DoShaderSource(
1179 GLuint client_id, GLsizei count, const char** data, const GLint* length);
[email protected]07f54fcc2009-12-22 02:46:301180
zmo38923562015-01-29 20:17:391181 // Wrapper for glTransformFeedbackVaryings.
1182 void DoTransformFeedbackVaryings(
1183 GLuint client_program_id, GLsizei count, const char* const* varyings,
1184 GLenum buffer_mode);
1185
[email protected]0d6bfdc2011-11-02 01:32:201186 // Clear any textures used by the current program.
1187 bool ClearUnclearedTextures();
1188
[email protected]0d6bfdc2011-11-02 01:32:201189 // Clears any uncleared attachments attached to the given frame buffer.
1190 // Returns false if there was a generated GL error.
[email protected]4d8f0dd2013-03-09 14:37:061191 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
[email protected]3a2e7c7b2010-08-06 01:12:281192
[email protected]0d6bfdc2011-11-02 01:32:201193 // overridden from GLES2Decoder
dcheng1f4d1d72014-10-21 16:21:581194 bool ClearLevel(unsigned service_id,
1195 unsigned bind_target,
1196 unsigned target,
1197 int level,
1198 unsigned internal_format,
1199 unsigned format,
1200 unsigned type,
1201 int width,
1202 int height,
1203 bool is_texture_immutable) override;
[email protected]0d6bfdc2011-11-02 01:32:201204
[email protected]c007aa02010-09-02 22:22:401205 // Restore all GL state that affects clearing.
1206 void RestoreClearState();
1207
[email protected]3a2e7c7b2010-08-06 01:12:281208 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461209 // Returns: true if glEnable/glDisable should actually be called.
1210 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281211
[email protected]0d6bfdc2011-11-02 01:32:201212 // Check that the currently bound framebuffers are valid.
1213 // Generates GL error if not.
1214 bool CheckBoundFramebuffersValid(const char* func_name);
1215
[email protected]2ea5950d2014-07-09 18:20:341216 // Check that the currently bound read framebuffer has a color image
1217 // attached. Generates GL error if not.
1218 bool CheckBoundReadFramebufferColorAttachment(const char* func_name);
1219
zmo383512cf2014-10-14 00:11:001220 // Check that the currently bound read framebuffer's color image
1221 // isn't the target texture of the glCopyTex{Sub}Image2D.
1222 bool FormsTextureCopyingFeedbackLoop(TextureRef* texture, GLint level);
1223
[email protected]0d6bfdc2011-11-02 01:32:201224 // Check if a framebuffer meets our requirements.
1225 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351226 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201227 GLenum target,
1228 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271229
orglofchcad5a6742014-11-07 19:51:121230 // Check if the current valuebuffer exists and is valid. If not generates
1231 // the appropriate GL error. Returns true if the current valuebuffer is in
1232 // a usable state.
1233 bool CheckCurrentValuebuffer(const char* function_name);
1234
1235 // Check if the current valuebuffer exists and is valiud and that the
1236 // value buffer is actually subscribed to the given subscription
1237 bool CheckCurrentValuebufferForSubscription(GLenum subscription,
1238 const char* function_name);
1239
1240 // Check if the location can be used for the given subscription target. If not
1241 // generates the appropriate GL error. Returns true if the location is usable
1242 bool CheckSubscriptionTarget(GLint location,
1243 GLenum subscription,
1244 const char* function_name);
1245
[email protected]939e7362010-05-13 20:49:101246 // Checks if the current program exists and is valid. If not generates the
1247 // appropriate GL error. Returns true if the current program is in a usable
1248 // state.
1249 bool CheckCurrentProgram(const char* function_name);
1250
1251 // Checks if the current program exists and is valid and that location is not
1252 // -1. If the current program is not valid generates the appropriate GL
1253 // error. Returns true if the current program is in a usable state and
1254 // location is not -1.
1255 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1256
zmof9a81360f2014-10-17 00:06:141257 // Checks if the current program samples a texture that is also the color
1258 // image of the current bound framebuffer, i.e., the source and destination
1259 // of the draw operation are the same.
1260 bool CheckDrawingFeedbackLoops();
1261
orglofchcad5a6742014-11-07 19:51:121262 // Checks if |api_type| is valid for the given uniform
1263 // If the api type is not valid generates the appropriate GL
1264 // error. Returns true if |api_type| is valid for the uniform
1265 bool CheckUniformForApiType(const Program::UniformInfo* info,
1266 const char* function_name,
1267 Program::UniformApiType api_type);
1268
[email protected]939e7362010-05-13 20:49:101269 // Gets the type of a uniform for a location in the current program. Sets GL
1270 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361271 // program is valid and the location exists. Adjusts count so it
1272 // does not overflow the uniform.
[email protected]9b1f1b52014-03-12 10:40:131273 bool PrepForSetUniformByLocation(GLint fake_location,
1274 const char* function_name,
1275 Program::UniformApiType api_type,
1276 GLint* real_location,
1277 GLenum* type,
1278 GLsizei* count);
[email protected]939e7362010-05-13 20:49:101279
[email protected]b177ae22011-11-01 03:29:111280 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021281 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111282
[email protected]b273e432010-04-12 17:23:581283 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1284 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1285
[email protected]ac77603c72013-03-08 13:52:061286 // Helper for glGetVertexAttrib
1287 void GetVertexAttribHelper(
1288 const VertexAttrib* attrib, GLenum pname, GLint* param);
1289
[email protected]3916c97e2010-02-25 03:20:501290 // Wrapper for glActiveTexture
1291 void DoActiveTexture(GLenum texture_unit);
1292
[email protected]ae51d192010-04-27 00:48:031293 // Wrapper for glAttachShader
1294 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1295
[email protected]96449d2c2009-11-25 00:01:321296 // Wrapper for glBindBuffer since we need to track the current targets.
1297 void DoBindBuffer(GLenum target, GLuint buffer);
1298
[email protected]86093972010-03-11 00:13:561299 // Wrapper for glBindFramebuffer since we need to track the current targets.
1300 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1301
1302 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1303 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1304
[email protected]a93bb842010-02-16 23:03:471305 // Wrapper for glBindTexture since we need to track the current targets.
1306 void DoBindTexture(GLenum target, GLuint texture);
1307
[email protected]944b62f32012-09-27 02:20:461308 // Wrapper for glBindVertexArrayOES
1309 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571310 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461311
[email protected]49cabed2013-11-13 18:15:181312 // Wrapper for glBlitFramebufferCHROMIUM.
1313 void DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301314 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1315 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1316 GLbitfield mask, GLenum filter);
1317
[email protected]36cef8ce2010-03-16 07:34:451318 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111319 void DoBufferSubData(
1320 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1321
[email protected]36cef8ce2010-03-16 07:34:451322 // Wrapper for glCheckFramebufferStatus
1323 GLenum DoCheckFramebufferStatus(GLenum target);
1324
[email protected]3a03a8f2011-03-19 00:51:271325 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081326 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271327
[email protected]88a61bf2012-10-27 13:00:421328 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421329 void DoDepthRangef(GLclampf znear, GLclampf zfar);
[email protected]b04e24c2013-01-08 18:35:251330 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281331
[email protected]45bf5152010-02-12 00:11:311332 // Wrapper for glCompileShader.
1333 void DoCompileShader(GLuint shader);
1334
[email protected]ae51d192010-04-27 00:48:031335 // Wrapper for glDetachShader
1336 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1337
[email protected]3a2e7c7b2010-08-06 01:12:281338 // Wrapper for glDisable
1339 void DoDisable(GLenum cap);
1340
[email protected]07f54fcc2009-12-22 02:46:301341 // Wrapper for glDisableVertexAttribArray.
1342 void DoDisableVertexAttribArray(GLuint index);
1343
[email protected]60f22d32012-12-12 00:31:581344 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1345 // attachments.
1346 void DoDiscardFramebufferEXT(GLenum target,
1347 GLsizei numAttachments,
1348 const GLenum* attachments);
1349
[email protected]3a2e7c7b2010-08-06 01:12:281350 // Wrapper for glEnable
1351 void DoEnable(GLenum cap);
1352
[email protected]07f54fcc2009-12-22 02:46:301353 // Wrapper for glEnableVertexAttribArray.
1354 void DoEnableVertexAttribArray(GLuint index);
1355
[email protected]882ba1e22012-03-08 19:02:531356 // Wrapper for glFinish.
1357 void DoFinish();
1358
1359 // Wrapper for glFlush.
1360 void DoFlush();
1361
[email protected]36cef8ce2010-03-16 07:34:451362 // Wrapper for glFramebufferRenderbufffer.
1363 void DoFramebufferRenderbuffer(
1364 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1365 GLuint renderbuffer);
1366
1367 // Wrapper for glFramebufferTexture2D.
1368 void DoFramebufferTexture2D(
1369 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1370 GLint level);
1371
[email protected]7d3c36e2013-07-12 14:13:161372 // Wrapper for glFramebufferTexture2DMultisampleEXT.
1373 void DoFramebufferTexture2DMultisample(
1374 GLenum target, GLenum attachment, GLenum textarget,
1375 GLuint texture, GLint level, GLsizei samples);
1376
1377 // Common implementation for both DoFramebufferTexture2D wrappers.
1378 void DoFramebufferTexture2DCommon(const char* name,
1379 GLenum target, GLenum attachment, GLenum textarget,
1380 GLuint texture, GLint level, GLsizei samples);
1381
zmo84c08202014-11-23 15:28:401382 // Wrapper for glFramebufferTextureLayer.
1383 void DoFramebufferTextureLayer(
1384 GLenum target, GLenum attachment, GLuint texture, GLint level,
1385 GLint layer);
1386
[email protected]a93bb842010-02-16 23:03:471387 // Wrapper for glGenerateMipmap
1388 void DoGenerateMipmap(GLenum target);
1389
[email protected]7d3c36e2013-07-12 14:13:161390 // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname
1391 // to account for different pname values defined in different extension
1392 // variants.
1393 GLenum AdjustGetPname(GLenum pname);
1394
[email protected]b273e432010-04-12 17:23:581395 // Wrapper for DoGetBooleanv.
1396 void DoGetBooleanv(GLenum pname, GLboolean* params);
1397
1398 // Wrapper for DoGetFloatv.
1399 void DoGetFloatv(GLenum pname, GLfloat* params);
1400
[email protected]36cef8ce2010-03-16 07:34:451401 // Wrapper for glGetFramebufferAttachmentParameteriv.
1402 void DoGetFramebufferAttachmentParameteriv(
1403 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1404
[email protected]a0c3e972010-04-21 00:49:131405 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581406 void DoGetIntegerv(GLenum pname, GLint* params);
1407
[email protected]29a9eb52010-04-13 09:04:231408 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061409 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231410 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1411
[email protected]17cfbe0e2013-03-07 01:26:081412 // Wrapper for glGetBufferParameteriv.
1413 void DoGetBufferParameteriv(
1414 GLenum target, GLenum pname, GLint* params);
1415
[email protected]a0c3e972010-04-21 00:49:131416 // Wrapper for glGetProgramiv.
1417 void DoGetProgramiv(
1418 GLuint program_id, GLenum pname, GLint* params);
1419
[email protected]36cef8ce2010-03-16 07:34:451420 // Wrapper for glRenderbufferParameteriv.
1421 void DoGetRenderbufferParameteriv(
1422 GLenum target, GLenum pname, GLint* params);
1423
[email protected]ddd968b82010-03-02 00:44:291424 // Wrapper for glGetShaderiv
1425 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1426
[email protected]4c6f5462014-03-05 00:26:561427 // Wrappers for glGetTexParameter.
1428 void DoGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
1429 void DoGetTexParameteriv(GLenum target, GLenum pname, GLint* params);
1430 void InitTextureMaxAnisotropyIfNeeded(GLenum target, GLenum pname);
1431
[email protected]b1122982010-05-17 23:04:241432 // Wrappers for glGetVertexAttrib.
1433 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1434 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1435
[email protected]1958e0e2010-04-22 05:17:151436 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241437 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151438 bool DoIsBuffer(GLuint client_id);
1439 bool DoIsFramebuffer(GLuint client_id);
1440 bool DoIsProgram(GLuint client_id);
1441 bool DoIsRenderbuffer(GLuint client_id);
1442 bool DoIsShader(GLuint client_id);
1443 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461444 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151445
[email protected]07f54fcc2009-12-22 02:46:301446 // Wrapper for glLinkProgram
1447 void DoLinkProgram(GLuint program);
1448
[email protected]36cef8ce2010-03-16 07:34:451449 // Wrapper for glRenderbufferStorage.
1450 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031451 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451452
[email protected]49cabed2013-11-13 18:15:181453 // Handler for glRenderbufferStorageMultisampleCHROMIUM.
1454 void DoRenderbufferStorageMultisampleCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301455 GLenum target, GLsizei samples, GLenum internalformat,
1456 GLsizei width, GLsizei height);
1457
[email protected]49cabed2013-11-13 18:15:181458 // Handler for glRenderbufferStorageMultisampleEXT
1459 // (multisampled_render_to_texture).
1460 void DoRenderbufferStorageMultisampleEXT(
1461 GLenum target, GLsizei samples, GLenum internalformat,
1462 GLsizei width, GLsizei height);
1463
1464 // Common validation for multisample extensions.
1465 bool ValidateRenderbufferStorageMultisample(GLsizei samples,
1466 GLenum internalformat,
1467 GLsizei width,
1468 GLsizei height);
1469
[email protected]4a4c18b2013-09-13 22:50:101470 // Verifies that the currently bound multisample renderbuffer is valid
1471 // Very slow! Only done on platforms with driver bugs that return invalid
1472 // buffers under memory pressure
1473 bool VerifyMultisampleRenderbufferIntegrity(
1474 GLuint renderbuffer, GLenum format);
1475
[email protected]b273e432010-04-12 17:23:581476 // Wrapper for glReleaseShaderCompiler.
1477 void DoReleaseShaderCompiler() { }
1478
zmobcb3fdd62014-12-11 00:49:031479 // Wrappers for glSamplerParameter*v functions.
1480 void DoSamplerParameterfv(
1481 GLuint sampler, GLenum pname, const GLfloat* params);
1482 void DoSamplerParameteriv(GLuint sampler, GLenum pname, const GLint* params);
1483
[email protected]3916c97e2010-02-25 03:20:501484 // Wrappers for glTexParameter functions.
1485 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1486 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1487 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1488 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1489
1490 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1491 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121492 void DoUniform1i(GLint fake_location, GLint v0);
1493 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1494 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1495 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1496 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101497
1498 // Wrappers for glUniformfv because some drivers don't correctly accept
1499 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121500 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1501 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1502 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1503 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501504
[email protected]43c2f1f2011-03-25 18:35:361505 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121506 GLint fake_location, GLsizei count, GLboolean transpose,
1507 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361508 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121509 GLint fake_location, GLsizei count, GLboolean transpose,
1510 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361511 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121512 GLint fake_location, GLsizei count, GLboolean transpose,
1513 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361514
[email protected]af6380962012-11-29 23:24:131515 bool SetVertexAttribValue(
1516 const char* function_name, GLuint index, const GLfloat* value);
1517
[email protected]b1122982010-05-17 23:04:241518 // Wrappers for glVertexAttrib??
1519 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1520 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1521 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1522 void DoVertexAttrib4f(
1523 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1524 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1525 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1526 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1527 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1528
[email protected]43410e92012-04-20 17:06:281529 // Wrapper for glViewport
1530 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1531
[email protected]07f54fcc2009-12-22 02:46:301532 // Wrapper for glUseProgram
1533 void DoUseProgram(GLuint program);
1534
[email protected]ae51d192010-04-27 00:48:031535 // Wrapper for glValidateProgram.
1536 void DoValidateProgram(GLuint program_client_id);
1537
[email protected]d2a0e1a2012-08-12 02:25:011538 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1539 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1540 void DoPopGroupMarkerEXT(void);
1541
[email protected]4e8a5b122010-05-08 22:00:101542 // Gets the number of values that will be returned by glGetXXX. Returns
1543 // false if pname is unknown.
1544 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1545
[email protected]07f54fcc2009-12-22 02:46:301546 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431547 bool IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:101548 const char* function_name, GLuint max_vertex_accessed, bool instanced,
1549 GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301550
[email protected]c13e1da62011-09-09 21:48:301551 // Returns true if successful, simulated will be true if attrib0 was
1552 // simulated.
[email protected]c6aef902012-02-14 03:31:421553 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431554 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]3fc38e22014-05-30 00:13:231555 void RestoreStateForAttrib(GLuint attrib, bool restore_array_binding);
[email protected]b1122982010-05-17 23:04:241556
[email protected]91c94eb2013-10-22 10:32:541557 // If an image is bound to texture, this will call Will/DidUseTexImage
1558 // if needed.
1559 void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1560 void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1561
1562 // Returns false if textures were replaced.
[email protected]e56131d22013-07-28 16:14:111563 bool PrepareTexturesForRender();
[email protected]91c94eb2013-10-22 10:32:541564 void RestoreStateForTextures();
[email protected]3916c97e2010-02-25 03:20:501565
[email protected]8fbedc02010-11-18 18:43:401566 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421567 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431568 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421569 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401570 void RestoreStateForSimulatedFixedAttribs();
1571
[email protected]c6aef902012-02-14 03:31:421572 // Handle DrawArrays and DrawElements for both instanced and non-instanced
[email protected]ac6904d62014-07-30 12:00:101573 // cases (primcount is always 1 for non-instanced).
[email protected]c6aef902012-02-14 03:31:421574 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431575 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421576 bool instanced, GLenum mode, GLint first, GLsizei count,
1577 GLsizei primcount);
1578 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431579 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421580 bool instanced, GLenum mode, GLsizei count, GLenum type,
1581 int32 offset, GLsizei primcount);
1582
[email protected]61eeb33f2011-07-26 15:30:311583 GLenum GetBindTargetForSamplerType(GLenum type) {
1584 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461585 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1586 switch (type) {
1587 case GL_SAMPLER_2D:
1588 return GL_TEXTURE_2D;
1589 case GL_SAMPLER_CUBE:
1590 return GL_TEXTURE_CUBE_MAP;
1591 case GL_SAMPLER_EXTERNAL_OES:
1592 return GL_TEXTURE_EXTERNAL_OES;
1593 case GL_SAMPLER_2D_RECT_ARB:
1594 return GL_TEXTURE_RECTANGLE_ARB;
1595 }
1596
1597 NOTREACHED();
1598 return 0;
[email protected]61eeb33f2011-07-26 15:30:311599 }
1600
[email protected]8e3e0662010-08-23 18:46:301601 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061602 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1603 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301604 switch (target) {
1605 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451606 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341607 framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301608 break;
[email protected]ebfb73c2012-08-15 02:37:451609 case GL_READ_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341610 framebuffer = framebuffer_state_.bound_read_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301611 break;
1612 default:
1613 NOTREACHED();
1614 break;
1615 }
[email protected]4d8f0dd2013-03-09 14:37:061616 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301617 }
1618
[email protected]ed9f9cd2013-02-27 21:12:351619 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201620 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271621 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201622 switch (target) {
1623 case GL_RENDERBUFFER:
[email protected]7cd76fd2013-06-02 21:11:111624 renderbuffer = state_.bound_renderbuffer.get();
[email protected]0d6bfdc2011-11-02 01:32:201625 break;
1626 default:
1627 NOTREACHED();
1628 break;
1629 }
[email protected]ee2a79c32013-03-10 03:50:271630 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201631 }
1632
[email protected]f7b85372010-02-03 01:11:371633 // Validates the program and location for a glGetUniform call and returns
1634 // a SizeResult setup to receive the result. Returns true if glGetUniform
1635 // should be called.
1636 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121637 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371638 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121639 error::Error* error, GLint* real_location, GLuint* service_id,
1640 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371641
jbauman7a059312014-10-16 19:30:541642 void MaybeExitOnContextLost();
dcheng1f4d1d72014-10-21 16:21:581643 bool WasContextLost() override;
1644 bool WasContextLostByRobustnessExtension() override;
1645 void LoseContext(uint32 reset_status) override;
[email protected]38d139d2011-07-14 00:38:431646
[email protected]e51bdf32011-11-23 22:21:461647#if defined(OS_MACOSX)
1648 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1649#endif
1650
[email protected]ad84a3a2012-06-08 21:42:431651 bool ValidateCompressedTexDimensions(
1652 const char* function_name,
1653 GLint level, GLsizei width, GLsizei height, GLenum format);
1654 bool ValidateCompressedTexFuncData(
1655 const char* function_name,
1656 GLsizei width, GLsizei height, GLenum format, size_t size);
1657 bool ValidateCompressedTexSubDimensions(
1658 const char* function_name,
1659 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1660 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351661 Texture* texture);
[email protected]ad84a3a2012-06-08 21:42:431662
[email protected]ab09b612013-03-11 22:11:511663 void RenderWarning(const char* filename, int line, const std::string& msg);
1664 void PerformanceWarning(
1665 const char* filename, int line, const std::string& msg);
[email protected]0f8afe82012-05-14 23:43:011666
[email protected]62e155e2012-10-23 22:43:151667 const FeatureInfo::FeatureFlags& features() const {
1668 return feature_info_->feature_flags();
1669 }
1670
1671 const FeatureInfo::Workarounds& workarounds() const {
1672 return feature_info_->workarounds();
1673 }
1674
[email protected]a7266a92012-06-28 02:11:081675 bool ShouldDeferDraws() {
1676 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341677 framebuffer_state_.bound_draw_framebuffer.get() == NULL &&
[email protected]a7266a92012-06-28 02:11:081678 surface_->DeferDraws();
1679 }
1680
[email protected]09e17272012-11-30 10:30:441681 bool ShouldDeferReads() {
1682 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341683 framebuffer_state_.bound_read_framebuffer.get() == NULL &&
[email protected]09e17272012-11-30 10:30:441684 surface_->DeferDraws();
1685 }
1686
dongseong.hwange1cb2aa2015-02-11 09:33:331687 bool IsRobustnessSupported() {
1688 return has_robustness_extension_ &&
1689 context_->WasAllocatedUsingRobustnessExtension();
1690 }
1691
[email protected]c76fe672013-12-13 23:30:221692 error::Error WillAccessBoundFramebufferForDraw() {
1693 if (ShouldDeferDraws())
1694 return error::kDeferCommandUntilLater;
1695 if (!offscreen_target_frame_buffer_.get() &&
1696 !framebuffer_state_.bound_draw_framebuffer.get() &&
1697 !surface_->SetBackbufferAllocation(true))
1698 return error::kLostContext;
1699 return error::kNoError;
1700 }
1701
1702 error::Error WillAccessBoundFramebufferForRead() {
1703 if (ShouldDeferReads())
1704 return error::kDeferCommandUntilLater;
1705 if (!offscreen_target_frame_buffer_.get() &&
1706 !framebuffer_state_.bound_read_framebuffer.get() &&
1707 !surface_->SetBackbufferAllocation(true))
1708 return error::kLostContext;
1709 return error::kNoError;
1710 }
1711
vmiura8266ca72014-09-09 21:37:001712 // Set remaining commands to process to 0 to force DoCommands to return
1713 // and allow context preemption and GPU watchdog checks in GpuScheduler().
1714 void ExitCommandProcessingEarly() { commands_to_process_ = 0; }
1715
[email protected]5a36dc132013-07-23 23:17:551716 void ProcessPendingReadPixels();
1717 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
1718
[email protected]96449d2c2009-11-25 00:01:321719 // Generate a member function prototype for each command in an automated and
1720 // typesafe way.
vmiuracd108592014-09-08 14:36:341721#define GLES2_CMD_OP(name) \
1722 Error Handle##name(uint32 immediate_data_size, const void* data);
[email protected]96449d2c2009-11-25 00:01:321723
1724 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1725
1726 #undef GLES2_CMD_OP
1727
[email protected]2f2d7042010-04-14 21:45:581728 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381729 scoped_refptr<gfx::GLSurface> surface_;
1730 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021731
[email protected]a3ded6d2010-10-19 06:44:391732 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351733 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391734
[email protected]1d82e822013-04-10 21:32:321735 DebugMarkerManager debug_marker_manager_;
1736 Logger logger_;
1737
[email protected]e259eb412012-10-13 05:47:241738 // All the state for this context.
1739 ContextState state_;
1740
[email protected]34ff8b0c2010-10-01 20:06:021741 // Current width and height of the offscreen frame buffer.
1742 gfx::Size offscreen_size_;
1743
[email protected]96449d2c2009-11-25 00:01:321744 // Util to help with GL.
1745 GLES2Util util_;
1746
[email protected]43410e92012-04-20 17:06:281747 // unpack flip y as last set by glPixelStorei
1748 bool unpack_flip_y_;
1749
[email protected]6c75c712012-06-19 15:43:171750 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281751 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171752 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281753
[email protected]b1122982010-05-17 23:04:241754 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1755 GLuint attrib_0_buffer_id_;
1756
1757 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131758 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241759
[email protected]fc753442011-02-04 19:49:491760 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1761 bool attrib_0_buffer_matches_value_;
1762
[email protected]b1122982010-05-17 23:04:241763 // The size of attrib 0.
1764 GLsizei attrib_0_size_;
1765
[email protected]8fbedc02010-11-18 18:43:401766 // The buffer used to simulate GL_FIXED attribs.
1767 GLuint fixed_attrib_buffer_id_;
1768
1769 // The size of fiixed attrib buffer.
1770 GLsizei fixed_attrib_buffer_size_;
1771
[email protected]b9363b22010-06-09 22:06:151772 // The offscreen frame buffer that the client renders to. With EGL, the
1773 // depth and stencil buffers are separate. With regular GL there is a single
1774 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1775 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351776 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1777 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1778 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1779 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1780 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021781 GLenum offscreen_target_color_format_;
1782 GLenum offscreen_target_depth_format_;
1783 GLenum offscreen_target_stencil_format_;
1784 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561785 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351786
[email protected]de26b3c2011-08-03 21:54:271787 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351788 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1789 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
[email protected]370eaf12013-05-18 09:19:491790 scoped_refptr<TextureRef>
[email protected]ed9f9cd2013-02-27 21:12:351791 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271792
1793 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351794 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1795 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051796 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351797
[email protected]882ba1e22012-03-08 19:02:531798 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531799
[email protected]944b62f32012-09-27 02:20:461800 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1801
[email protected]b63f1d62014-07-18 15:40:591802 scoped_ptr<ImageManager> image_manager_;
1803
[email protected]729c0b42013-05-26 02:05:071804 base::Callback<void(gfx::Size, float)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001805
[email protected]840a7e462013-02-27 01:29:511806 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481807
[email protected]e3932abb2013-03-13 00:01:371808 ShaderCacheCallback shader_cache_callback_;
1809
[email protected]85a4ac22013-05-31 01:58:471810 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
[email protected]b0af4f52011-09-28 22:04:421811
[email protected]32fe9aa2011-01-21 23:47:131812 // The format of the back buffer_
1813 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461814 bool back_buffer_has_depth_;
1815 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131816
achaulkcf5316f2014-09-26 19:28:421817 bool surfaceless_;
1818
[email protected]60f22d32012-12-12 00:31:581819 // Backbuffer attachments that are currently undefined.
1820 uint32 backbuffer_needs_clear_bits_;
1821
[email protected]a6a09f852014-05-23 13:05:031822 // The current decoder error communicates the decoder error through command
1823 // processing functions that do not return the error value. Should be set only
1824 // if not returning an error.
[email protected]a3a93e7b2010-08-28 00:48:561825 error::Error current_decoder_error_;
1826
[email protected]b1d2dcb2010-05-17 19:24:181827 bool use_shader_translator_;
dyen0ff9e4402015-02-12 22:27:431828 scoped_refptr<ShaderTranslatorInterface> vertex_translator_;
1829 scoped_refptr<ShaderTranslatorInterface> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181830
[email protected]e82fb792011-09-22 00:33:291831 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411832
[email protected]915a59a12010-09-30 21:29:111833 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051834 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351835 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051836
[email protected]65225772011-05-12 21:10:241837 int frame_number_;
1838
vmiura8266ca72014-09-09 21:37:001839 // Number of commands remaining to be processed in DoCommands().
1840 int commands_to_process_;
1841
[email protected]706b69f2012-07-27 04:59:301842 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431843 GLenum reset_status_;
[email protected]93a7d98f2013-07-11 00:04:221844 bool reset_by_robustness_extension_;
[email protected]b381ee32014-03-22 02:43:431845 bool supports_post_sub_buffer_;
[email protected]38d139d2011-07-14 00:38:431846
[email protected]f0d74742011-10-03 16:31:041847 // These flags are used to override the state of the shared feature_info_
1848 // member. Because the same FeatureInfo instance may be shared among many
1849 // contexts, the assumptions on the availablity of extensions in WebGL
1850 // contexts may be broken. These flags override the shared state to preserve
1851 // WebGL semantics.
1852 bool force_webgl_glsl_validation_;
1853 bool derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:491854 bool frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:131855 bool draw_buffers_explicitly_enabled_;
[email protected]93c2fd82014-04-16 02:46:061856 bool shader_texture_lod_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:041857
[email protected]062c38b2012-01-18 03:25:101858 bool compile_shader_always_succeeds_;
1859
[email protected]828a3932014-04-02 14:43:131860 // An optional behaviour to lose the context and group when OOM.
1861 bool lose_context_when_out_of_memory_;
1862
[email protected]cae20172012-12-07 00:06:191863 // Log extra info.
1864 bool service_logging_;
1865
[email protected]e51bdf32011-11-23 22:21:461866#if defined(OS_MACOSX)
[email protected]c3a6b4a2014-06-04 09:25:531867 typedef std::map<GLuint, IOSurfaceRef> TextureToIOSurfaceMap;
[email protected]e51bdf32011-11-23 22:21:461868 TextureToIOSurfaceMap texture_to_io_surface_map_;
1869#endif
1870
[email protected]43410e92012-04-20 17:06:281871 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
sievers2384f2b2014-11-18 02:10:351872 scoped_ptr<ClearFramebufferResourceManager> clear_framebuffer_blit_;
[email protected]43410e92012-04-20 17:06:281873
[email protected]1868a342012-11-07 15:56:021874 // Cached values of the currently assigned viewport dimensions.
1875 GLsizei viewport_max_width_;
1876 GLsizei viewport_max_height_;
1877
[email protected]63b465922012-09-06 02:04:521878 // Command buffer stats.
[email protected]63b465922012-09-06 02:04:521879 base::TimeDelta total_processing_commands_time_;
1880
[email protected]c986af502013-08-14 01:04:441881 // States related to each manager.
1882 DecoderTextureState texture_state_;
1883 DecoderFramebufferState framebuffer_state_;
1884
[email protected]fb97b662013-02-20 23:02:141885 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]8f9b8dd2013-09-12 18:05:131886 scoped_ptr<GPUStateTracer> gpu_state_tracer_;
vmiura1c2b1de2014-09-19 19:03:241887 const unsigned char* cb_command_trace_category_;
dyencb86f2f2014-12-09 18:35:411888 const unsigned char* gpu_decoder_category_;
[email protected]cac16542014-01-15 17:53:511889 int gpu_trace_level_;
1890 bool gpu_trace_commands_;
vmiura1c2b1de2014-09-19 19:03:241891 bool gpu_debug_commands_;
[email protected]94307712012-11-16 23:26:111892
[email protected]5a36dc132013-07-23 23:17:551893 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_;
1894
[email protected]4a4c18b2013-09-13 22:50:101895 // Used to validate multisample renderbuffers if needed
1896 GLuint validation_texture_;
1897 GLuint validation_fbo_multisample_;
1898 GLuint validation_fbo_;
1899
vmiuracd108592014-09-08 14:36:341900 typedef gpu::gles2::GLES2Decoder::Error (GLES2DecoderImpl::*CmdHandler)(
1901 uint32 immediate_data_size,
1902 const void* data);
1903
1904 // A struct to hold info about each command.
1905 struct CommandInfo {
1906 CmdHandler cmd_handler;
1907 uint8 arg_flags; // How to handle the arguments for this command
1908 uint8 cmd_flags; // How to handle this command
1909 uint16 arg_count; // How many arguments are expected for this command.
1910 };
1911
1912 // A table of CommandInfo for all the commands.
1913 static const CommandInfo command_info[kNumCommands - kStartPoint];
1914
[email protected]96449d2c2009-11-25 00:01:321915 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1916};
1917
vmiuracd108592014-09-08 14:36:341918const GLES2DecoderImpl::CommandInfo GLES2DecoderImpl::command_info[] = {
1919#define GLES2_CMD_OP(name) \
1920 { \
1921 &GLES2DecoderImpl::Handle##name, cmds::name::kArgFlags, \
1922 cmds::name::cmd_flags, \
1923 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, \
1924 } \
1925 , /* NOLINT */
1926 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1927#undef GLES2_CMD_OP
1928};
1929
[email protected]ab09b612013-03-11 22:11:511930ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:301931 const char* function_name, ErrorState* error_state)
[email protected]ab09b612013-03-11 22:11:511932 : function_name_(function_name),
[email protected]40621eb52013-10-08 15:40:301933 error_state_(error_state) {
1934 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351935}
1936
1937ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]40621eb52013-10-08 15:40:301938 ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351939}
1940
[email protected]2b10c02d2014-01-29 16:43:021941static void RestoreCurrentTextureBindings(ContextState* state, GLenum target) {
[email protected]ce296892013-10-24 22:04:361942 TextureUnit& info = state->texture_units[0];
1943 GLuint last_id;
[email protected]2b10c02d2014-01-29 16:43:021944 scoped_refptr<TextureRef> texture_ref;
1945 switch (target) {
1946 case GL_TEXTURE_2D:
1947 texture_ref = info.bound_texture_2d;
1948 break;
1949 case GL_TEXTURE_CUBE_MAP:
1950 texture_ref = info.bound_texture_cube_map;
1951 break;
1952 case GL_TEXTURE_EXTERNAL_OES:
1953 texture_ref = info.bound_texture_external_oes;
1954 break;
1955 case GL_TEXTURE_RECTANGLE_ARB:
1956 texture_ref = info.bound_texture_rectangle_arb;
1957 break;
1958 default:
1959 NOTREACHED();
1960 break;
1961 }
1962 if (texture_ref.get()) {
1963 last_id = texture_ref->service_id();
[email protected]ce296892013-10-24 22:04:361964 } else {
1965 last_id = 0;
1966 }
1967
[email protected]2b10c02d2014-01-29 16:43:021968 glBindTexture(target, last_id);
[email protected]ce296892013-10-24 22:04:361969 glActiveTexture(GL_TEXTURE0 + state->active_texture_unit);
1970}
1971
[email protected]2b10c02d2014-01-29 16:43:021972ScopedTextureBinder::ScopedTextureBinder(ContextState* state,
1973 GLuint id,
1974 GLenum target)
1975 : state_(state),
1976 target_(target) {
[email protected]ab09b612013-03-11 22:11:511977 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021978 "ScopedTextureBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351979
1980 // TODO(apatrick): Check if there are any other states that need to be reset
1981 // before binding a new texture.
1982 glActiveTexture(GL_TEXTURE0);
[email protected]2b10c02d2014-01-29 16:43:021983 glBindTexture(target, id);
[email protected]6217d392010-03-25 22:08:351984}
1985
[email protected]2b10c02d2014-01-29 16:43:021986ScopedTextureBinder::~ScopedTextureBinder() {
[email protected]ab09b612013-03-11 22:11:511987 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021988 "ScopedTextureBinder::dtor", state_->GetErrorState());
1989 RestoreCurrentTextureBindings(state_, target_);
[email protected]6217d392010-03-25 22:08:351990}
1991
[email protected]18e785a2013-10-09 03:29:411992ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state,
[email protected]6217d392010-03-25 22:08:351993 GLuint id)
[email protected]18e785a2013-10-09 03:29:411994 : state_(state) {
[email protected]ab09b612013-03-11 22:11:511995 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411996 "ScopedRenderBufferBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351997 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1998}
1999
2000ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:512001 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:412002 "ScopedRenderBufferBinder::dtor", state_->GetErrorState());
2003 state_->RestoreRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:352004}
2005
2006ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
2007 GLuint id)
2008 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:512009 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302010 "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352011 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:452012 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:352013}
2014
2015ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:512016 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302017 "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]8e3e0662010-08-23 18:46:302018 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:352019}
2020
[email protected]34ff8b0c2010-10-01 20:06:022021ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:272022 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:522023 : decoder_(decoder) {
[email protected]9d3b2e12013-10-02 01:04:342024 resolve_and_bind_ = (
2025 decoder_->offscreen_target_frame_buffer_.get() &&
2026 decoder_->IsOffscreenBufferMultisampled() &&
2027 (!decoder_->framebuffer_state_.bound_read_framebuffer.get() ||
2028 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:022029 if (!resolve_and_bind_)
2030 return;
2031
[email protected]ab09b612013-03-11 22:11:512032 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302033 "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:022034 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
2035 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:272036 GLuint targetid;
2037 if (internal) {
2038 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
2039 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:352040 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:272041 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:352042 decoder_->offscreen_resolved_color_texture_.reset(
[email protected]ce296892013-10-24 22:04:362043 new BackTexture(decoder->memory_tracker(), &decoder->state_));
[email protected]de26b3c2011-08-03 21:54:272044 decoder_->offscreen_resolved_color_texture_->Create();
2045
2046 DCHECK(decoder_->offscreen_saved_color_format_);
2047 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:092048 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
2049 false);
[email protected]de26b3c2011-08-03 21:54:272050 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
2051 decoder_->offscreen_resolved_color_texture_.get());
2052 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
2053 GL_FRAMEBUFFER_COMPLETE) {
2054 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
2055 << "because offscreen resolved FBO was incomplete.";
2056 return;
2057 }
2058 }
2059 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
2060 } else {
2061 targetid = decoder_->offscreen_saved_frame_buffer_->id();
2062 }
2063 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:022064 const int width = decoder_->offscreen_size_.width();
2065 const int height = decoder_->offscreen_size_.height();
[email protected]454157e2014-05-03 02:49:452066 decoder->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f42f05b2013-11-15 21:46:182067 decoder->BlitFramebufferHelper(0,
2068 0,
2069 width,
2070 height,
2071 0,
2072 0,
2073 width,
2074 height,
2075 GL_COLOR_BUFFER_BIT,
2076 GL_NEAREST);
[email protected]de26b3c2011-08-03 21:54:272077 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:022078}
2079
2080ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
2081 if (!resolve_and_bind_)
2082 return;
2083
[email protected]ab09b612013-03-11 22:11:512084 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302085 "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:022086 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:222087 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:452088 decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]8c3e68782010-10-27 16:41:182089 }
[email protected]34ff8b0c2010-10-01 20:06:022090}
2091
[email protected]ce296892013-10-24 22:04:362092BackTexture::BackTexture(
2093 MemoryTracker* memory_tracker,
2094 ContextState* state)
2095 : memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2096 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482097 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252098 id_(0) {
[email protected]6217d392010-03-25 22:08:352099}
2100
[email protected]ed9f9cd2013-02-27 21:12:352101BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:352102 // This does not destroy the render texture because that would require that
2103 // the associated GL context was current. Just check that it was explicitly
2104 // destroyed.
2105 DCHECK_EQ(id_, 0u);
2106}
2107
[email protected]ed9f9cd2013-02-27 21:12:352108void BackTexture::Create() {
[email protected]40621eb52013-10-08 15:40:302109 ScopedGLErrorSuppressor suppressor("BackTexture::Create",
[email protected]ce296892013-10-24 22:04:362110 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352111 Destroy();
2112 glGenTextures(1, &id_);
[email protected]2b10c02d2014-01-29 16:43:022113 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]eeeb07b92014-08-16 07:46:262114 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2115 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
[email protected]3a4d0c52011-06-29 23:11:582116 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2117 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:162118
2119 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
2120 // never called on an offscreen context, no data will ever be uploaded to the
2121 // saved offscreen color texture (it is deferred until to when SwapBuffers
2122 // is called). My idea is that some nvidia drivers might have a bug where
2123 // deleting a texture that has never been populated might cause a
2124 // crash.
2125 glTexImage2D(
2126 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:482127
2128 bytes_allocated_ = 16u * 16u * 4u;
2129 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:352130}
2131
[email protected]ed9f9cd2013-02-27 21:12:352132bool BackTexture::AllocateStorage(
2133 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:352134 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302135 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage",
[email protected]ce296892013-10-24 22:04:362136 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022137 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]678a73f2012-12-19 19:22:092138 uint32 image_size = 0;
2139 GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:422140 size.width(), size.height(), 1, format, GL_UNSIGNED_BYTE, 8, &image_size,
[email protected]678a73f2012-12-19 19:22:092141 NULL, NULL);
2142
[email protected]7989c9e2013-01-23 06:39:262143 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
2144 return false;
2145 }
2146
[email protected]40d90a22013-04-09 03:39:552147 scoped_ptr<char[]> zero_data;
[email protected]678a73f2012-12-19 19:22:092148 if (zero) {
2149 zero_data.reset(new char[image_size]);
2150 memset(zero_data.get(), 0, image_size);
2151 }
[email protected]6217d392010-03-25 22:08:352152
[email protected]8f1d2aa2013-05-10 23:45:382153 glTexImage2D(GL_TEXTURE_2D,
2154 0, // mip level
2155 format,
2156 size.width(),
2157 size.height(),
2158 0, // border
2159 format,
2160 GL_UNSIGNED_BYTE,
2161 zero_data.get());
[email protected]6217d392010-03-25 22:08:352162
[email protected]d37231fa2010-04-09 21:16:022163 size_ = size;
2164
[email protected]1078f912011-12-23 13:12:142165 bool success = glGetError() == GL_NO_ERROR;
2166 if (success) {
[email protected]68e81a4a62012-12-13 01:16:482167 memory_tracker_.TrackMemFree(bytes_allocated_);
2168 bytes_allocated_ = image_size;
2169 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142170 }
2171 return success;
[email protected]6217d392010-03-25 22:08:352172}
2173
[email protected]ed9f9cd2013-02-27 21:12:352174void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:352175 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302176 ScopedGLErrorSuppressor suppressor("BackTexture::Copy",
[email protected]ce296892013-10-24 22:04:362177 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022178 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]6217d392010-03-25 22:08:352179 glCopyTexImage2D(GL_TEXTURE_2D,
2180 0, // level
[email protected]3a4d0c52011-06-29 23:11:582181 format,
[email protected]6217d392010-03-25 22:08:352182 0, 0,
2183 size.width(),
2184 size.height(),
2185 0); // border
2186}
2187
[email protected]ed9f9cd2013-02-27 21:12:352188void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:352189 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302190 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy",
[email protected]ce296892013-10-24 22:04:362191 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352192 glDeleteTextures(1, &id_);
2193 id_ = 0;
2194 }
[email protected]68e81a4a62012-12-13 01:16:482195 memory_tracker_.TrackMemFree(bytes_allocated_);
2196 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352197}
2198
[email protected]ed9f9cd2013-02-27 21:12:352199void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:052200 id_ = 0;
2201}
2202
[email protected]d5a28e452013-10-10 01:01:402203BackRenderbuffer::BackRenderbuffer(
2204 RenderbufferManager* renderbuffer_manager,
2205 MemoryTracker* memory_tracker,
2206 ContextState* state)
2207 : renderbuffer_manager_(renderbuffer_manager),
2208 memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2209 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482210 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252211 id_(0) {
[email protected]6217d392010-03-25 22:08:352212}
2213
[email protected]ed9f9cd2013-02-27 21:12:352214BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:352215 // This does not destroy the render buffer because that would require that
2216 // the associated GL context was current. Just check that it was explicitly
2217 // destroyed.
2218 DCHECK_EQ(id_, 0u);
2219}
2220
[email protected]ed9f9cd2013-02-27 21:12:352221void BackRenderbuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302222 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create",
[email protected]d5a28e452013-10-10 01:01:402223 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352224 Destroy();
2225 glGenRenderbuffersEXT(1, &id_);
2226}
2227
[email protected]f42f05b2013-11-15 21:46:182228bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info,
2229 const gfx::Size& size,
2230 GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:352231 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:512232 ScopedGLErrorSuppressor suppressor(
[email protected]d5a28e452013-10-10 01:01:402233 "BackRenderbuffer::AllocateStorage", state_->GetErrorState());
2234 ScopedRenderBufferBinder binder(state_, id_);
[email protected]7989c9e2013-01-23 06:39:262235
2236 uint32 estimated_size = 0;
[email protected]d5a28e452013-10-10 01:01:402237 if (!renderbuffer_manager_->ComputeEstimatedRenderbufferSize(
[email protected]8e102e102013-09-20 22:50:232238 size.width(), size.height(), samples, format, &estimated_size)) {
[email protected]7989c9e2013-01-23 06:39:262239 return false;
2240 }
2241
2242 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
2243 return false;
2244 }
2245
[email protected]34ff8b0c2010-10-01 20:06:022246 if (samples <= 1) {
2247 glRenderbufferStorageEXT(GL_RENDERBUFFER,
2248 format,
2249 size.width(),
2250 size.height());
2251 } else {
[email protected]f42f05b2013-11-15 21:46:182252 GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info,
2253 GL_RENDERBUFFER,
2254 samples,
2255 format,
2256 size.width(),
2257 size.height());
[email protected]34ff8b0c2010-10-01 20:06:022258 }
[email protected]1078f912011-12-23 13:12:142259 bool success = glGetError() == GL_NO_ERROR;
2260 if (success) {
[email protected]d5a28e452013-10-10 01:01:402261 // Mark the previously allocated bytes as free.
[email protected]68e81a4a62012-12-13 01:16:482262 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:262263 bytes_allocated_ = estimated_size;
[email protected]d5a28e452013-10-10 01:01:402264 // Track the newly allocated bytes.
[email protected]68e81a4a62012-12-13 01:16:482265 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142266 }
2267 return success;
[email protected]6217d392010-03-25 22:08:352268}
2269
[email protected]ed9f9cd2013-02-27 21:12:352270void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352271 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302272 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy",
[email protected]d5a28e452013-10-10 01:01:402273 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352274 glDeleteRenderbuffersEXT(1, &id_);
2275 id_ = 0;
2276 }
[email protected]68e81a4a62012-12-13 01:16:482277 memory_tracker_.TrackMemFree(bytes_allocated_);
2278 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352279}
2280
[email protected]ed9f9cd2013-02-27 21:12:352281void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052282 id_ = 0;
2283}
2284
[email protected]ed9f9cd2013-02-27 21:12:352285BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352286 : decoder_(decoder),
2287 id_(0) {
2288}
2289
[email protected]ed9f9cd2013-02-27 21:12:352290BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:352291 // This does not destroy the frame buffer because that would require that
2292 // the associated GL context was current. Just check that it was explicitly
2293 // destroyed.
2294 DCHECK_EQ(id_, 0u);
2295}
2296
[email protected]ed9f9cd2013-02-27 21:12:352297void BackFramebuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302298 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create",
2299 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352300 Destroy();
2301 glGenFramebuffersEXT(1, &id_);
2302}
2303
[email protected]ed9f9cd2013-02-27 21:12:352304void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:352305 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512306 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302307 "BackFramebuffer::AttachRenderTexture", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352308 ScopedFrameBufferBinder binder(decoder_, id_);
2309 GLuint attach_id = texture ? texture->id() : 0;
2310 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2311 GL_COLOR_ATTACHMENT0,
2312 GL_TEXTURE_2D,
2313 attach_id,
2314 0);
2315}
2316
[email protected]ed9f9cd2013-02-27 21:12:352317void BackFramebuffer::AttachRenderBuffer(GLenum target,
2318 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352319 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512320 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302321 "BackFramebuffer::AttachRenderBuffer", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352322 ScopedFrameBufferBinder binder(decoder_, id_);
2323 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2324 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152325 target,
[email protected]6217d392010-03-25 22:08:352326 GL_RENDERBUFFER,
2327 attach_id);
2328}
2329
[email protected]ed9f9cd2013-02-27 21:12:352330void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352331 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302332 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy",
2333 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352334 glDeleteFramebuffersEXT(1, &id_);
2335 id_ = 0;
2336 }
2337}
2338
[email protected]ed9f9cd2013-02-27 21:12:352339void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052340 id_ = 0;
2341}
2342
[email protected]ed9f9cd2013-02-27 21:12:352343GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352344 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302345 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus",
2346 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352347 ScopedFrameBufferBinder binder(decoder_, id_);
2348 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2349}
2350
[email protected]aa7666122011-09-02 19:45:522351GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2352 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322353}
2354
[email protected]aa7666122011-09-02 19:45:522355GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392356 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572357 group_(group),
[email protected]1d82e822013-04-10 21:32:322358 logger_(&debug_marker_manager_),
[email protected]828a3932014-04-02 14:43:132359 state_(group_->feature_info(), this, &logger_),
[email protected]43410e92012-04-20 17:06:282360 unpack_flip_y_(false),
2361 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172362 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242363 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492364 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242365 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402366 fixed_attrib_buffer_id_(0),
2367 fixed_attrib_buffer_size_(0),
[email protected]34ff8b0c2010-10-01 20:06:022368 offscreen_target_color_format_(0),
2369 offscreen_target_depth_format_(0),
2370 offscreen_target_stencil_format_(0),
2371 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562372 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052373 offscreen_saved_color_format_(0),
[email protected]32fe9aa2011-01-21 23:47:132374 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462375 back_buffer_has_depth_(false),
2376 back_buffer_has_stencil_(false),
achaulkcf5316f2014-09-26 19:28:422377 surfaceless_(false),
[email protected]60f22d32012-12-12 00:31:582378 backbuffer_needs_clear_bits_(0),
[email protected]a3a93e7b2010-08-28 00:48:562379 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052380 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112381 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002382 feature_info_(group_->feature_info()),
[email protected]38d139d2011-07-14 00:38:432383 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302384 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512385 reset_status_(GL_NO_ERROR),
[email protected]93a7d98f2013-07-11 00:04:222386 reset_by_robustness_extension_(false),
[email protected]b381ee32014-03-22 02:43:432387 supports_post_sub_buffer_(false),
[email protected]f0d74742011-10-03 16:31:042388 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102389 derivatives_explicitly_enabled_(false),
[email protected]70dc60932013-06-04 03:33:492390 frag_depth_explicitly_enabled_(false),
[email protected]aff39ac82013-06-08 04:53:132391 draw_buffers_explicitly_enabled_(false),
[email protected]93c2fd82014-04-16 02:46:062392 shader_texture_lod_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282393 compile_shader_always_succeeds_(false),
[email protected]828a3932014-04-02 14:43:132394 lose_context_when_out_of_memory_(false),
avi9ab037202014-12-22 23:49:532395 service_logging_(base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]cae20172012-12-07 00:06:192396 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022397 viewport_max_width_(0),
[email protected]4a4c18b2013-09-13 22:50:102398 viewport_max_height_(0),
[email protected]345ba902013-11-14 21:39:002399 texture_state_(group_->feature_info()
2400 ->workarounds()
2401 .texsubimage2d_faster_than_teximage2d),
vmiura1c2b1de2014-09-19 19:03:242402 cb_command_trace_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
2403 TRACE_DISABLED_BY_DEFAULT("cb_command"))),
dyencb86f2f2014-12-09 18:35:412404 gpu_decoder_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
2405 TRACE_DISABLED_BY_DEFAULT("gpu_decoder"))),
vmiura1c2b1de2014-09-19 19:03:242406 gpu_trace_level_(2),
2407 gpu_trace_commands_(false),
2408 gpu_debug_commands_(false),
[email protected]4a4c18b2013-09-13 22:50:102409 validation_texture_(0),
2410 validation_fbo_multisample_(0),
2411 validation_fbo_(0) {
[email protected]3b1ecc262011-08-03 22:49:572412 DCHECK(group);
2413
[email protected]b1122982010-05-17 23:04:242414 attrib_0_value_.v[0] = 0.0f;
2415 attrib_0_value_.v[1] = 0.0f;
2416 attrib_0_value_.v[2] = 0.0f;
2417 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152418
[email protected]c2f8c8402010-12-06 18:07:242419 // The shader translator is used for WebGL even when running on EGL
2420 // because additional restrictions are needed (like only enabling
2421 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562422 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2423 // the empty string to CompileShader and this is not a valid shader.
2424 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
avi9ab037202014-12-22 23:49:532425 base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]39ba4f02012-03-26 01:16:002426 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152427 use_shader_translator_ = false;
2428 }
[email protected]96449d2c2009-11-25 00:01:322429}
2430
[email protected]80eb6b52012-01-19 00:14:412431GLES2DecoderImpl::~GLES2DecoderImpl() {
2432}
2433
[email protected]c410da802011-03-14 19:17:412434bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382435 const scoped_refptr<gfx::GLSurface>& surface,
2436 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232437 bool offscreen,
[email protected]c410da802011-03-14 19:17:412438 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:292439 const DisallowedFeatures& disallowed_features,
[email protected]3c644d82011-06-20 19:58:242440 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322441 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382442 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302443 DCHECK(!context_.get());
2444
jbaumana7604692014-10-17 02:00:392445 surfaceless_ = surface->IsSurfaceless() && !offscreen;
achaulkcf5316f2014-09-26 19:28:422446
[email protected]55e136f2013-04-03 18:50:062447 set_initialized();
[email protected]b4af07d2014-08-20 00:11:572448 gpu_tracer_.reset(new GPUTracer(this));
[email protected]8f9b8dd2013-09-12 18:05:132449 gpu_state_tracer_ = GPUStateTracer::Create(&state_);
[email protected]fb97b662013-02-20 23:02:142450
avi9ab037202014-12-22 23:49:532451 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2452 switches::kEnableGPUDebugging)) {
[email protected]e844ae22012-01-14 03:36:262453 set_debug(true);
2454 }
2455
avi9ab037202014-12-22 23:49:532456 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2457 switches::kEnableGPUCommandLogging)) {
[email protected]39ba4f02012-03-26 01:16:002458 set_log_commands(true);
2459 }
2460
avi9ab037202014-12-22 23:49:532461 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2462 switches::kEnableUnsafeES3APIs)) {
zmo84c08202014-11-23 15:28:402463 set_unsafe_es3_apis_enabled(true);
2464 }
2465
avi9ab037202014-12-22 23:49:532466 compile_shader_always_succeeds_ =
2467 base::CommandLine::ForCurrentProcess()->HasSwitch(
2468 switches::kCompileShaderAlwaysSucceeds);
[email protected]062c38b2012-01-18 03:25:102469
[email protected]63c9b052012-05-17 18:27:382470 // Take ownership of the context and surface. The surface can be replaced with
2471 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382472 context_ = context;
[email protected]63c9b052012-05-17 18:27:382473 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182474
[email protected]65f7efe2013-11-28 03:11:472475 ContextCreationAttribHelper attrib_parser;
2476 if (!attrib_parser.Parse(attribs))
2477 return false;
2478
[email protected]828a3932014-04-02 14:43:132479 // Save the loseContextWhenOutOfMemory context creation attribute.
2480 lose_context_when_out_of_memory_ =
[email protected]845c4e32014-08-13 11:50:402481 attrib_parser.lose_context_when_out_of_memory;
[email protected]828a3932014-04-02 14:43:132482
[email protected]65f7efe2013-11-28 03:11:472483 // If the failIfMajorPerformanceCaveat context creation attribute was true
2484 // and we are using a software renderer, fail.
[email protected]845c4e32014-08-13 11:50:402485 if (attrib_parser.fail_if_major_perf_caveat &&
[email protected]65f7efe2013-11-28 03:11:472486 feature_info_->feature_flags().is_swiftshader) {
2487 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
2488 Destroy(true);
2489 return false;
2490 }
2491
[email protected]956aec52013-09-05 15:41:192492 if (!group_->Initialize(this, disallowed_features)) {
[email protected]09ddb91f2011-04-14 23:16:222493 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392494 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422495 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382496 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032497 return false;
[email protected]a3ded6d2010-10-19 06:44:392498 }
[email protected]b64c24952012-04-19 03:20:272499 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282500
[email protected]e82fb792011-09-22 00:33:292501 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502502
[email protected]af6380962012-11-29 23:24:132503 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]da364812014-05-09 21:39:482504 vertex_array_manager_.reset(new VertexArrayManager());
2505
2506 GLuint default_vertex_attrib_service_id = 0;
2507 if (features().native_vertex_array_object) {
2508 glGenVertexArraysOES(1, &default_vertex_attrib_service_id);
2509 glBindVertexArrayOES(default_vertex_attrib_service_id);
2510 }
2511
2512 state_.default_vertex_attrib_manager =
2513 CreateVertexAttribManager(0, default_vertex_attrib_service_id, false);
2514
[email protected]81f20a622014-04-18 01:54:522515 state_.default_vertex_attrib_manager->Initialize(
[email protected]94ba2e02014-03-12 10:32:002516 group_->max_vertex_attribs(),
2517 feature_info_->workarounds().init_vertex_attributes);
[email protected]944b62f32012-09-27 02:20:462518
[email protected]81f20a622014-04-18 01:54:522519 // vertex_attrib_manager is set to default_vertex_attrib_manager by this call
[email protected]ab4fd7282012-10-12 16:25:572520 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322521
[email protected]7cd76fd2013-06-02 21:11:112522 query_manager_.reset(new QueryManager(this, feature_info_.get()));
[email protected]882ba1e22012-03-08 19:02:532523
[email protected]b63f1d62014-07-18 15:40:592524 image_manager_.reset(new ImageManager);
2525
[email protected]302ce6d2011-07-07 23:28:112526 util_.set_num_compressed_texture_formats(
2527 validators_->compressed_texture_format.GetValues().size());
2528
[email protected]1071e572011-02-09 20:00:122529 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2530 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2531 // OpenGL ES 2.0 does not have this issue.
2532 glEnableVertexAttribArray(0);
2533 }
[email protected]b1122982010-05-17 23:04:242534 glGenBuffersARB(1, &attrib_0_buffer_id_);
2535 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2536 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2537 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402538 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082539
[email protected]1868a342012-11-07 15:56:022540 state_.texture_units.resize(group_->max_texture_units());
2541 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492542 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312543 // We want the last bind to be 2D.
[email protected]370eaf12013-05-18 09:19:492544 TextureRef* ref;
[email protected]62e155e2012-10-23 22:43:152545 if (features().oes_egl_image_external) {
[email protected]370eaf12013-05-18 09:19:492546 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072547 GL_TEXTURE_EXTERNAL_OES);
[email protected]370eaf12013-05-18 09:19:492548 state_.texture_units[tt].bound_texture_external_oes = ref;
[email protected]5ebf59f2014-04-08 03:51:572549 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref ? ref->service_id() : 0);
[email protected]61eeb33f2011-07-26 15:30:312550 }
[email protected]62e155e2012-10-23 22:43:152551 if (features().arb_texture_rectangle) {
[email protected]370eaf12013-05-18 09:19:492552 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072553 GL_TEXTURE_RECTANGLE_ARB);
[email protected]370eaf12013-05-18 09:19:492554 state_.texture_units[tt].bound_texture_rectangle_arb = ref;
[email protected]5ebf59f2014-04-08 03:51:572555 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref ? ref->service_id() : 0);
[email protected]e51bdf32011-11-23 22:21:462556 }
[email protected]370eaf12013-05-18 09:19:492557 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2558 state_.texture_units[tt].bound_texture_cube_map = ref;
[email protected]5ebf59f2014-04-08 03:51:572559 glBindTexture(GL_TEXTURE_CUBE_MAP, ref ? ref->service_id() : 0);
[email protected]370eaf12013-05-18 09:19:492560 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2561 state_.texture_units[tt].bound_texture_2d = ref;
[email protected]5ebf59f2014-04-08 03:51:572562 glBindTexture(GL_TEXTURE_2D, ref ? ref->service_id() : 0);
[email protected]1958e0e2010-04-22 05:17:152563 }
[email protected]00f893d2010-08-24 18:55:492564 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502565 CHECK_GL_ERROR();
2566
[email protected]069944672012-04-25 20:52:232567 if (offscreen) {
[email protected]845c4e32014-08-13 11:50:402568 if (attrib_parser.samples > 0 && attrib_parser.sample_buffers > 0 &&
[email protected]b0609652012-12-14 07:24:542569 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022570 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432571 // max_sample_count must be initialized to a sane value. If
2572 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2573 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022574 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
[email protected]845c4e32014-08-13 11:50:402575 offscreen_target_samples_ = std::min(attrib_parser.samples,
[email protected]34ff8b0c2010-10-01 20:06:022576 max_sample_count);
2577 } else {
2578 offscreen_target_samples_ = 1;
2579 }
[email protected]845c4e32014-08-13 11:50:402580 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved;
[email protected]34ff8b0c2010-10-01 20:06:022581
2582 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2583 const bool rgb8_supported =
2584 context_->HasExtension("GL_OES_rgb8_rgba8");
2585 // The only available default render buffer formats in GLES2 have very
2586 // little precision. Don't enable multisampling unless 8-bit render
2587 // buffer formats are available--instead fall back to 8-bit textures.
2588 if (rgb8_supported && offscreen_target_samples_ > 1) {
[email protected]845c4e32014-08-13 11:50:402589 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022590 GL_RGBA8 : GL_RGB8;
2591 } else {
2592 offscreen_target_samples_ = 1;
[email protected]845c4e32014-08-13 11:50:402593 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022594 GL_RGBA : GL_RGB;
2595 }
2596
2597 // ANGLE only supports packed depth/stencil formats, so use it if it is
2598 // available.
2599 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182600 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272601 VLOG(1) << "GL_OES_packed_depth_stencil "
2602 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]845c4e32014-08-13 11:50:402603 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002604 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022605 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2606 offscreen_target_stencil_format_ = 0;
2607 } else {
2608 // It may be the case that this depth/stencil combination is not
2609 // supported, but this will be checked later by CheckFramebufferStatus.
[email protected]845c4e32014-08-13 11:50:402610 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022611 GL_DEPTH_COMPONENT16 : 0;
[email protected]845c4e32014-08-13 11:50:402612 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022613 GL_STENCIL_INDEX8 : 0;
2614 }
2615 } else {
[email protected]845c4e32014-08-13 11:50:402616 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022617 GL_RGBA : GL_RGB;
2618
2619 // If depth is requested at all, use the packed depth stencil format if
2620 // it's available, as some desktop GL drivers don't support any non-packed
2621 // formats for depth attachments.
2622 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182623 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272624 VLOG(1) << "GL_EXT_packed_depth_stencil "
2625 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022626
[email protected]845c4e32014-08-13 11:50:402627 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002628 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022629 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2630 offscreen_target_stencil_format_ = 0;
2631 } else {
[email protected]845c4e32014-08-13 11:50:402632 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022633 GL_DEPTH_COMPONENT : 0;
[email protected]845c4e32014-08-13 11:50:402634 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022635 GL_STENCIL_INDEX : 0;
2636 }
2637 }
2638
[email protected]845c4e32014-08-13 11:50:402639 offscreen_saved_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]97872062010-11-03 19:07:052640 GL_RGBA : GL_RGB;
2641
[email protected]6217d392010-03-25 22:08:352642 // Create the target frame buffer. This is the one that the client renders
2643 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352644 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352645 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022646 // Due to GLES2 format limitations, either the color texture (for
2647 // non-multisampling) or the color render buffer (for multisampling) will be
2648 // attached to the offscreen frame buffer. The render buffer has more
2649 // limited formats available to it, but the texture can't do multisampling.
2650 if (IsOffscreenBufferMultisampled()) {
[email protected]d5a28e452013-10-10 01:01:402651 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(
2652 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022653 offscreen_target_color_render_buffer_->Create();
2654 } else {
[email protected]ce296892013-10-24 22:04:362655 offscreen_target_color_texture_.reset(new BackTexture(
2656 memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022657 offscreen_target_color_texture_->Create();
2658 }
[email protected]d5a28e452013-10-10 01:01:402659 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(
2660 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152661 offscreen_target_depth_render_buffer_->Create();
[email protected]d5a28e452013-10-10 01:01:402662 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(
2663 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152664 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352665
2666 // Create the saved offscreen texture. The target frame buffer is copied
2667 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352668 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022669 offscreen_saved_frame_buffer_->Create();
2670 //
[email protected]ce296892013-10-24 22:04:362671 offscreen_saved_color_texture_.reset(new BackTexture(
2672 memory_tracker(), &state_));
[email protected]6217d392010-03-25 22:08:352673 offscreen_saved_color_texture_->Create();
2674
[email protected]6217d392010-03-25 22:08:352675 // Allocate the render buffers at their initial size and check the status
2676 // of the frame buffers is okay.
[email protected]799b4b22011-08-22 17:09:592677 if (!ResizeOffscreenFrameBuffer(size)) {
[email protected]d0498742010-09-20 20:27:012678 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382679 Destroy(true);
[email protected]6217d392010-03-25 22:08:352680 return false;
2681 }
2682
[email protected]678a73f2012-12-19 19:22:092683 // Allocate the offscreen saved color texture.
2684 DCHECK(offscreen_saved_color_format_);
2685 offscreen_saved_color_texture_->AllocateStorage(
2686 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2687
2688 offscreen_saved_frame_buffer_->AttachRenderTexture(
2689 offscreen_saved_color_texture_.get());
2690 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2691 GL_FRAMEBUFFER_COMPLETE) {
2692 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2693 Destroy(true);
2694 return false;
2695 }
2696
[email protected]6217d392010-03-25 22:08:352697 // Bind to the new default frame buffer (the offscreen target frame buffer).
2698 // This should now be associated with ID zero.
2699 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
[email protected]62e65f02013-05-29 22:28:102700 } else {
2701 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
2702 // These are NOT if the back buffer has these proprorties. They are
2703 // if we want the command buffer to enforce them regardless of what
2704 // the real backbuffer is assuming the real back buffer gives us more than
2705 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2706 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2707 // can't do anything about that.
2708
achaulkcf5316f2014-09-26 19:28:422709 if (!surfaceless_) {
2710 GLint v = 0;
2711 glGetIntegerv(GL_ALPHA_BITS, &v);
2712 // This checks if the user requested RGBA and we have RGBA then RGBA. If
2713 // the user requested RGB then RGB. If the user did not specify a
2714 // preference than use whatever we were given. Same for DEPTH and STENCIL.
2715 back_buffer_color_format_ =
2716 (attrib_parser.alpha_size != 0 && v > 0) ? GL_RGBA : GL_RGB;
2717 glGetIntegerv(GL_DEPTH_BITS, &v);
2718 back_buffer_has_depth_ = attrib_parser.depth_size != 0 && v > 0;
2719 glGetIntegerv(GL_STENCIL_BITS, &v);
2720 back_buffer_has_stencil_ = attrib_parser.stencil_size != 0 && v > 0;
2721 }
[email protected]6217d392010-03-25 22:08:352722 }
2723
[email protected]76a0ee102010-04-07 21:03:042724 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2725 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2726 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372727 // mailing list archives. It also implicitly enables the desktop GL
2728 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2729 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152730 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2731 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372732 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152733 }
[email protected]de17df392010-04-23 21:09:412734
[email protected]706b69f2012-07-27 04:59:302735 has_robustness_extension_ =
2736 context->HasExtension("GL_ARB_robustness") ||
oetuaho37cc50e2014-10-31 11:19:202737 context->HasExtension("GL_KHR_robustness") ||
[email protected]706b69f2012-07-27 04:59:302738 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432739
[email protected]c2f8c8402010-12-06 18:07:242740 if (!InitializeShaderTranslator()) {
2741 return false;
[email protected]de17df392010-04-23 21:09:412742 }
[email protected]76a0ee102010-04-07 21:03:042743
[email protected]e259eb412012-10-13 05:47:242744 state_.viewport_width = size.width();
2745 state_.viewport_height = size.height();
[email protected]43410e92012-04-20 17:06:282746
[email protected]5904806b2012-05-08 18:10:222747 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282748 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022749 viewport_max_width_ = viewport_params[0];
2750 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282751
[email protected]88a61bf2012-10-27 13:00:422752 state_.scissor_width = state_.viewport_width;
2753 state_.scissor_height = state_.viewport_height;
2754
[email protected]11f3e702012-06-19 19:00:012755 // Set all the default state because some GL drivers get it wrong.
[email protected]88ba52f2014-04-09 12:39:342756 state_.InitCapabilities(NULL);
2757 state_.InitState(NULL);
[email protected]e259eb412012-10-13 05:47:242758 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]11f3e702012-06-19 19:00:012759
2760 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2761 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2762 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2763 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
orglofchcad5a6742014-11-07 19:51:122764 DoBindValueBufferCHROMIUM(GL_SUBSCRIBED_VALUES_BUFFER_CHROMIUM, 0);
[email protected]11f3e702012-06-19 19:00:012765
achaulkcf5316f2014-09-26 19:28:422766 bool call_gl_clear = !surfaceless_;
[email protected]88cfd132013-07-11 00:59:002767#if defined(OS_ANDROID)
2768 // Temporary workaround for Android WebView because this clear ignores the
2769 // clip and corrupts that external UI of the App. Not calling glClear is ok
2770 // because the system already clears the buffer before each draw. Proper
2771 // fix might be setting the scissor clip properly before initialize. See
2772 // crbug.com/259023 for details.
2773 call_gl_clear = surface_->GetHandle();
2774#endif
2775 if (call_gl_clear) {
2776 // Clear the backbuffer.
2777 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2778 }
[email protected]561cc0a62013-05-07 18:34:452779
[email protected]b381ee32014-03-22 02:43:432780 supports_post_sub_buffer_ = surface->SupportsPostSubBuffer();
2781 if (feature_info_->workarounds()
2782 .disable_post_sub_buffers_for_onscreen_surfaces &&
2783 !surface->IsOffscreen())
2784 supports_post_sub_buffer_ = false;
2785
[email protected]62e155e2012-10-23 22:43:152786 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462787 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2788 }
[email protected]dd289a5d62012-06-30 22:05:462789
[email protected]9b753992013-04-27 02:04:412790 if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2791 context_->SetUnbindFboOnMakeCurrent();
[email protected]85cb4682013-04-20 00:54:242792 }
[email protected]85cb4682013-04-20 00:54:242793
[email protected]97419c02013-04-10 02:52:382794 // Only compositor contexts are known to use only the subset of GL
2795 // that can be safely migrated between the iGPU and the dGPU. Mark
2796 // those contexts as safe to forcibly transition between the GPUs.
2797 // http://crbug.com/180876, http://crbug.com/227228
2798 if (!offscreen)
2799 context_->SetSafeToForceGpuSwitch();
2800
[email protected]85a4ac22013-05-31 01:58:472801 async_pixel_transfer_manager_.reset(
[email protected]498b5c072013-06-04 19:30:072802 AsyncPixelTransferManager::Create(context.get()));
2803 async_pixel_transfer_manager_->Initialize(texture_manager());
[email protected]32145a92012-12-17 09:01:592804
sievers2384f2b2014-11-18 02:10:352805 if (workarounds().gl_clear_broken) {
2806 DCHECK(!clear_framebuffer_blit_.get());
2807 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glClearWorkaroundInit");
2808 clear_framebuffer_blit_.reset(new ClearFramebufferResourceManager(this));
2809 if (LOCAL_PEEK_GL_ERROR("glClearWorkaroundInit") != GL_NO_ERROR)
2810 return false;
2811 }
2812
[email protected]91c94eb2013-10-22 10:32:542813 framebuffer_manager()->AddObserver(this);
2814
[email protected]246a70452010-03-05 21:53:502815 return true;
[email protected]96449d2c2009-11-25 00:01:322816}
2817
[email protected]6d668892013-12-04 21:37:122818Capabilities GLES2DecoderImpl::GetCapabilities() {
2819 DCHECK(initialized());
2820
2821 Capabilities caps;
piman1c2e0a852014-11-12 05:17:552822 caps.VisitPrecisions([](GLenum shader, GLenum type,
2823 Capabilities::ShaderPrecision* shader_precision) {
2824 GLint range[2] = {0, 0};
2825 GLint precision = 0;
2826 GetShaderPrecisionFormatImpl(shader, type, range, &precision);
2827 shader_precision->min_range = range[0];
2828 shader_precision->max_range = range[1];
2829 shader_precision->precision = precision;
2830 });
2831 DoGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
2832 &caps.max_combined_texture_image_units);
2833 DoGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &caps.max_cube_map_texture_size);
2834 DoGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS,
2835 &caps.max_fragment_uniform_vectors);
2836 DoGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &caps.max_renderbuffer_size);
2837 DoGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &caps.max_texture_image_units);
2838 DoGetIntegerv(GL_MAX_TEXTURE_SIZE, &caps.max_texture_size);
2839 DoGetIntegerv(GL_MAX_VARYING_VECTORS, &caps.max_varying_vectors);
2840 DoGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &caps.max_vertex_attribs);
2841 DoGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
2842 &caps.max_vertex_texture_image_units);
2843 DoGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS,
2844 &caps.max_vertex_uniform_vectors);
2845 DoGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS,
2846 &caps.num_compressed_texture_formats);
2847 DoGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &caps.num_shader_binary_formats);
2848 DoGetIntegerv(GL_BIND_GENERATES_RESOURCE_CHROMIUM,
2849 &caps.bind_generates_resource_chromium);
heejin.r.chung8f143292015-02-05 02:44:002850 if (unsafe_es3_apis_enabled()) {
2851 DoGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
2852 &caps.max_transform_feedback_separate_attribs);
2853 DoGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS,
2854 &caps.max_uniform_buffer_bindings);
2855 DoGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT,
2856 &caps.uniform_buffer_offset_alignment);
2857 }
[email protected]6d668892013-12-04 21:37:122858
[email protected]6d668892013-12-04 21:37:122859 caps.egl_image_external =
2860 feature_info_->feature_flags().oes_egl_image_external;
2861 caps.texture_format_bgra8888 =
2862 feature_info_->feature_flags().ext_texture_format_bgra8888;
2863 caps.texture_format_etc1 =
2864 feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture;
aeliasd880a3d2014-08-26 00:46:202865 caps.texture_format_etc1_npot =
2866 caps.texture_format_etc1 && !workarounds().etc1_power_of_two_only;
[email protected]6d668892013-12-04 21:37:122867 caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle;
2868 caps.texture_usage = feature_info_->feature_flags().angle_texture_usage;
2869 caps.texture_storage = feature_info_->feature_flags().ext_texture_storage;
2870 caps.discard_framebuffer =
2871 feature_info_->feature_flags().ext_discard_framebuffer;
[email protected]12c99ab02014-04-22 10:12:352872 caps.sync_query = feature_info_->feature_flags().chromium_sync_query;
[email protected]6d668892013-12-04 21:37:122873
2874#if defined(OS_MACOSX)
2875 // This is unconditionally true on mac, no need to test for it at runtime.
2876 caps.iosurface = true;
2877#endif
2878
[email protected]b381ee32014-03-22 02:43:432879 caps.post_sub_buffer = supports_post_sub_buffer_;
reveman340109182014-09-30 15:36:452880 caps.image = true;
[email protected]6d668892013-12-04 21:37:122881
ed9198b422014-10-23 15:01:372882 caps.blend_equation_advanced =
2883 feature_info_->feature_flags().blend_equation_advanced;
2884 caps.blend_equation_advanced_coherent =
2885 feature_info_->feature_flags().blend_equation_advanced_coherent;
hendrikwfc25ca6192014-12-02 06:05:132886 caps.texture_rg = feature_info_->feature_flags().ext_texture_rg;
[email protected]6d668892013-12-04 21:37:122887 return caps;
2888}
2889
[email protected]302ce6d2011-07-07 23:28:112890void GLES2DecoderImpl::UpdateCapabilities() {
2891 util_.set_num_compressed_texture_formats(
2892 validators_->compressed_texture_format.GetValues().size());
2893 util_.set_num_shader_binary_formats(
2894 validators_->shader_binary_format.GetValues().size());
2895}
2896
[email protected]c2f8c8402010-12-06 18:07:242897bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442898 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2899
[email protected]c2f8c8402010-12-06 18:07:242900 if (!use_shader_translator_) {
2901 return true;
2902 }
2903 ShBuiltInResources resources;
2904 ShInitBuiltInResources(&resources);
2905 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2906 resources.MaxVertexUniformVectors =
2907 group_->max_vertex_uniform_vectors();
2908 resources.MaxVaryingVectors = group_->max_varying_vectors();
2909 resources.MaxVertexTextureImageUnits =
2910 group_->max_vertex_texture_image_units();
2911 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2912 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2913 resources.MaxFragmentUniformVectors =
2914 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:492915 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]a0b78142013-05-23 00:47:242916 resources.MaxExpressionComplexity = 256;
2917 resources.MaxCallStackDepth = 256;
[email protected]f0d74742011-10-03 16:31:042918
[email protected]46c86752013-05-21 05:08:392919 GLint range[2] = { 0, 0 };
[email protected]8dc1bf92013-03-12 03:58:212920 GLint precision = 0;
2921 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
2922 range, &precision);
[email protected]448e459e2013-06-12 17:00:412923 resources.FragmentPrecisionHigh =
2924 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
[email protected]9e98f61b2013-03-05 02:21:142925
[email protected]f0d74742011-10-03 16:31:042926 if (force_webgl_glsl_validation_) {
2927 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:492928 resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:132929 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
[email protected]cd8f1892013-09-05 00:14:442930 if (!draw_buffers_explicitly_enabled_)
2931 resources.MaxDrawBuffers = 1;
[email protected]93c2fd82014-04-16 02:46:062932 resources.EXT_shader_texture_lod = shader_texture_lod_explicitly_enabled_;
oetuaho0decd442014-10-13 08:40:462933 resources.NV_draw_buffers =
2934 draw_buffers_explicitly_enabled_ && features().nv_draw_buffers;
[email protected]f0d74742011-10-03 16:31:042935 } else {
2936 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152937 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462938 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152939 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062940 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152941 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:492942 resources.EXT_draw_buffers =
2943 features().ext_draw_buffers ? 1 : 0;
[email protected]70dc60932013-06-04 03:33:492944 resources.EXT_frag_depth =
2945 features().ext_frag_depth ? 1 : 0;
[email protected]93c2fd82014-04-16 02:46:062946 resources.EXT_shader_texture_lod =
2947 features().ext_shader_texture_lod ? 1 : 0;
oetuaho0decd442014-10-13 08:40:462948 resources.NV_draw_buffers =
2949 features().nv_draw_buffers ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:042950 }
2951
[email protected]26b61442013-03-17 16:12:012952 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC
2953 : SH_GLES2_SPEC;
[email protected]6aedcdc2013-01-24 01:25:052954 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:022955 resources.HashFunction = &CityHash64;
[email protected]6aedcdc2013-01-24 01:25:052956 else
2957 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:122958 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2959 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2960 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
[email protected]a6739bc2013-09-07 04:45:212961 int driver_bug_workarounds = 0;
2962 if (workarounds().needs_glsl_built_in_function_emulation)
2963 driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS;
[email protected]81187c62013-09-09 23:54:542964 if (workarounds().init_gl_position_in_vertex_shader)
2965 driver_bug_workarounds |= SH_INIT_GL_POSITION;
[email protected]f0c87602013-10-17 19:34:112966 if (workarounds().unfold_short_circuit_as_ternary_operation)
2967 driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT;
[email protected]b03219d2014-02-12 11:17:052968 if (workarounds().init_varyings_without_static_use)
2969 driver_bug_workarounds |= SH_INIT_VARYINGS_WITHOUT_STATIC_USE;
[email protected]f4db2b12014-03-01 03:57:062970 if (workarounds().unroll_for_loop_with_sampler_array_index)
2971 driver_bug_workarounds |= SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX;
[email protected]711e90802014-07-22 20:40:252972 if (workarounds().scalarize_vec_and_mat_constructor_args)
2973 driver_bug_workarounds |= SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS;
[email protected]fa6d3982014-08-18 18:10:272974 if (workarounds().regenerate_struct_names)
2975 driver_bug_workarounds |= SH_REGENERATE_STRUCT_NAMES;
[email protected]87fb6ab2012-06-13 22:28:042976
avi9ab037202014-12-22 23:49:532977 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2978 switches::kEmulateShaderPrecision))
oetuahoaffd85abe2014-12-11 09:47:092979 resources.WEBGL_debug_shader_precision = true;
2980
[email protected]03cef9b2014-04-03 15:58:142981 vertex_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:262982 GL_VERTEX_SHADER,
[email protected]03cef9b2014-04-03 15:58:142983 shader_spec,
2984 &resources,
[email protected]a6739bc2013-09-07 04:45:212985 implementation_type,
2986 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042987 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242988 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:382989 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242990 return false;
2991 }
[email protected]87fb6ab2012-06-13 22:28:042992
[email protected]03cef9b2014-04-03 15:58:142993 fragment_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:262994 GL_FRAGMENT_SHADER,
[email protected]03cef9b2014-04-03 15:58:142995 shader_spec,
2996 &resources,
[email protected]a6739bc2013-09-07 04:45:212997 implementation_type,
2998 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042999 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:243000 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:383001 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:243002 return false;
3003 }
3004 return true;
3005}
3006
[email protected]ae51d192010-04-27 00:48:033007bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:473008 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353009 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033010 return false;
3011 }
3012 }
[email protected]40d90a22013-04-09 03:39:553013 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033014 glGenBuffersARB(n, service_ids.get());
3015 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353016 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033017 }
3018 return true;
3019}
3020
3021bool GLES2DecoderImpl::GenFramebuffersHelper(
3022 GLsizei n, const GLuint* client_ids) {
3023 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353024 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033025 return false;
3026 }
3027 }
[email protected]40d90a22013-04-09 03:39:553028 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033029 glGenFramebuffersEXT(n, service_ids.get());
3030 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353031 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033032 }
3033 return true;
3034}
3035
3036bool GLES2DecoderImpl::GenRenderbuffersHelper(
3037 GLsizei n, const GLuint* client_ids) {
3038 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353039 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033040 return false;
3041 }
3042 }
[email protected]40d90a22013-04-09 03:39:553043 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033044 glGenRenderbuffersEXT(n, service_ids.get());
3045 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353046 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033047 }
3048 return true;
3049}
3050
orglofchcad5a6742014-11-07 19:51:123051bool GLES2DecoderImpl::GenValuebuffersCHROMIUMHelper(GLsizei n,
3052 const GLuint* client_ids) {
3053 for (GLsizei ii = 0; ii < n; ++ii) {
3054 if (GetValuebuffer(client_ids[ii])) {
3055 return false;
3056 }
3057 }
3058 for (GLsizei ii = 0; ii < n; ++ii) {
3059 CreateValuebuffer(client_ids[ii]);
3060 }
3061 return true;
3062}
3063
[email protected]ae51d192010-04-27 00:48:033064bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
3065 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353066 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033067 return false;
3068 }
3069 }
[email protected]40d90a22013-04-09 03:39:553070 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033071 glGenTextures(n, service_ids.get());
3072 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353073 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033074 }
3075 return true;
3076}
3077
3078void GLES2DecoderImpl::DeleteBuffersHelper(
3079 GLsizei n, const GLuint* client_ids) {
3080 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:213081 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103082 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:243083 state_.vertex_attrib_manager->Unbind(buffer);
[email protected]7cd76fd2013-06-02 21:11:113084 if (state_.bound_array_buffer.get() == buffer) {
[email protected]e259eb412012-10-13 05:47:243085 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:103086 }
[email protected]ed9f9cd2013-02-27 21:12:353087 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033088 }
[email protected]a93bb842010-02-16 23:03:473089 }
[email protected]07f54fcc2009-12-22 02:46:303090}
3091
[email protected]ae51d192010-04-27 00:48:033092void GLES2DecoderImpl::DeleteFramebuffersHelper(
3093 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453094 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153095 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:113096
[email protected]a25fa872010-03-25 02:57:583097 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353098 Framebuffer* framebuffer =
3099 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103100 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]9d3b2e12013-10-02 01:04:343101 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]ebfb73c2012-08-15 02:37:453102 GLenum target = supports_separate_framebuffer_binds ?
3103 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
vmiura7d08fee52015-02-18 18:39:343104
3105 // Unbind attachments on FBO before deletion.
3106 if (workarounds().unbind_attachments_on_bound_render_fbo_delete)
3107 framebuffer->DoUnbindGLAttachmentsForWorkaround(target);
3108
[email protected]b177ae22011-11-01 03:29:113109 glBindFramebufferEXT(target, GetBackbufferServiceId());
vmiura7d08fee52015-02-18 18:39:343110 framebuffer_state_.bound_draw_framebuffer = NULL;
3111 framebuffer_state_.clear_state_dirty = true;
[email protected]b177ae22011-11-01 03:29:113112 }
[email protected]9d3b2e12013-10-02 01:04:343113 if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) {
3114 framebuffer_state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:453115 GLenum target = supports_separate_framebuffer_binds ?
3116 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:113117 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:463118 }
[email protected]70d34263c2013-01-09 00:27:453119 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:353120 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033121 }
[email protected]a25fa872010-03-25 02:57:583122 }
[email protected]07f54fcc2009-12-22 02:46:303123}
3124
[email protected]ae51d192010-04-27 00:48:033125void GLES2DecoderImpl::DeleteRenderbuffersHelper(
3126 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453127 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153128 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:583129 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353130 Renderbuffer* renderbuffer =
3131 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103132 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:113133 if (state_.bound_renderbuffer.get() == renderbuffer) {
[email protected]e259eb412012-10-13 05:47:243134 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:103135 }
3136 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:453137 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:343138 if (framebuffer_state_.bound_read_framebuffer.get()) {
3139 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113140 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103141 }
[email protected]9d3b2e12013-10-02 01:04:343142 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3143 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113144 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103145 }
3146 } else {
[email protected]9d3b2e12013-10-02 01:04:343147 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3148 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113149 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103150 }
3151 }
[email protected]c986af502013-08-14 01:04:443152 framebuffer_state_.clear_state_dirty = true;
[email protected]ed9f9cd2013-02-27 21:12:353153 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033154 }
[email protected]a25fa872010-03-25 02:57:583155 }
[email protected]07f54fcc2009-12-22 02:46:303156}
3157
orglofchcad5a6742014-11-07 19:51:123158void GLES2DecoderImpl::DeleteValuebuffersCHROMIUMHelper(
3159 GLsizei n,
3160 const GLuint* client_ids) {
3161 for (GLsizei ii = 0; ii < n; ++ii) {
3162 Valuebuffer* valuebuffer = GetValuebuffer(client_ids[ii]);
3163 if (valuebuffer) {
3164 if (state_.bound_valuebuffer.get() == valuebuffer) {
3165 state_.bound_valuebuffer = NULL;
3166 }
3167 RemoveValuebuffer(client_ids[ii]);
3168 }
3169 }
3170}
3171
[email protected]ae51d192010-04-27 00:48:033172void GLES2DecoderImpl::DeleteTexturesHelper(
3173 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453174 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153175 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:473176 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]370eaf12013-05-18 09:19:493177 TextureRef* texture_ref = GetTexture(client_ids[ii]);
3178 if (texture_ref) {
3179 Texture* texture = texture_ref->texture();
[email protected]a0b78dc2011-11-11 10:43:103180 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:443181 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463182 }
[email protected]370eaf12013-05-18 09:19:493183 // Unbind texture_ref from texture_ref units.
[email protected]1868a342012-11-07 15:56:023184 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]370eaf12013-05-18 09:19:493185 state_.texture_units[jj].Unbind(texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103186 }
3187 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:453188 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:343189 if (framebuffer_state_.bound_read_framebuffer.get()) {
3190 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113191 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103192 }
[email protected]9d3b2e12013-10-02 01:04:343193 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3194 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113195 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103196 }
3197 } else {
[email protected]9d3b2e12013-10-02 01:04:343198 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3199 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113200 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103201 }
3202 }
[email protected]e51bdf32011-11-23 22:21:463203#if defined(OS_MACOSX)
[email protected]4f9958142013-07-02 03:58:073204 GLuint service_id = texture->service_id();
[email protected]e51bdf32011-11-23 22:21:463205 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
3206 ReleaseIOSurfaceForTexture(service_id);
3207 }
3208#endif
[email protected]ed9f9cd2013-02-27 21:12:353209 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033210 }
[email protected]a93bb842010-02-16 23:03:473211 }
[email protected]07f54fcc2009-12-22 02:46:303212}
3213
[email protected]43f28f832010-02-03 02:28:483214// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:323215
[email protected]eb54a562010-01-20 21:55:183216bool GLES2DecoderImpl::MakeCurrent() {
[email protected]177d1342013-12-07 04:20:343217 if (!context_.get())
[email protected]63c9b052012-05-17 18:27:383218 return false;
3219
[email protected]177d1342013-12-07 04:20:343220 if (!context_->MakeCurrent(surface_.get()) || WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:433221 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]e9f0ca82013-04-01 23:52:293222
jbauman7a059312014-10-16 19:30:543223 MaybeExitOnContextLost();
[email protected]e9f0ca82013-04-01 23:52:293224
[email protected]63c9b052012-05-17 18:27:383225 return false;
[email protected]38d139d2011-07-14 00:38:433226 }
3227
[email protected]69a8701e2013-03-07 21:31:093228 ProcessFinishedAsyncTransfers();
[email protected]69a8701e2013-03-07 21:31:093229
[email protected]9b753992013-04-27 02:04:413230 // Rebind the FBO if it was unbound by the context.
3231 if (workarounds().unbind_fbo_on_context_switch)
3232 RestoreFramebufferBindings();
3233
[email protected]c986af502013-08-14 01:04:443234 framebuffer_state_.clear_state_dirty = true;
[email protected]370eaf12013-05-18 09:19:493235
[email protected]69a8701e2013-03-07 21:31:093236 return true;
3237}
3238
3239void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]5a36dc132013-07-23 23:17:553240 ProcessPendingReadPixels();
[email protected]fe8d73c2013-02-16 22:37:323241 if (engine() && query_manager_.get())
3242 query_manager_->ProcessPendingTransferQueries();
3243
[email protected]5b3a8e02013-03-13 05:36:443244 // TODO(epenner): Is there a better place to do this?
3245 // This needs to occur before we execute any batch of commands
3246 // from the client, as the client may have recieved an async
3247 // completion while issuing those commands.
3248 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]b68b100752013-06-05 08:34:483249 async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
[email protected]eb54a562010-01-20 21:55:183250}
3251
[email protected]8e3e0662010-08-23 18:46:303252static void RebindCurrentFramebuffer(
3253 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:063254 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:243255 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:063256 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:463257
[email protected]a3783712012-01-20 22:18:243258 if (framebuffer_id == 0) {
3259 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:303260 }
[email protected]297ca1c2011-06-20 23:08:463261
[email protected]8e3e0662010-08-23 18:46:303262 glBindFramebufferEXT(target, framebuffer_id);
3263}
3264
3265void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]c986af502013-08-14 01:04:443266 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463267
[email protected]62e155e2012-10-23 22:43:153268 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:303269 RebindCurrentFramebuffer(
3270 GL_FRAMEBUFFER,
[email protected]9d3b2e12013-10-02 01:04:343271 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243272 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303273 } else {
3274 RebindCurrentFramebuffer(
3275 GL_READ_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343276 framebuffer_state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243277 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303278 RebindCurrentFramebuffer(
3279 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343280 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243281 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303282 }
[email protected]70d34263c2013-01-09 00:27:453283 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:303284}
3285
[email protected]0d6bfdc2011-11-02 01:32:203286bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:353287 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:203288 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:103289 if (!framebuffer) {
achaulkcf5316f2014-09-26 19:28:423290 if (surfaceless_)
3291 return false;
[email protected]60f22d32012-12-12 00:31:583292 if (backbuffer_needs_clear_bits_) {
3293 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
pkasting45796dc2014-10-17 04:18:323294 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1.f);
[email protected]454157e2014-05-03 02:49:453295 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]60f22d32012-12-12 00:31:583296 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473297 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3298 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]60f22d32012-12-12 00:31:583299 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:453300 state_.SetDeviceDepthMask(GL_TRUE);
3301 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]ee757922014-06-06 05:21:423302 bool reset_draw_buffer = false;
brucedawson18249152014-10-31 23:02:323303 if ((backbuffer_needs_clear_bits_ & GL_COLOR_BUFFER_BIT) != 0 &&
[email protected]ee757922014-06-06 05:21:423304 group_->draw_buffer() == GL_NONE) {
3305 reset_draw_buffer = true;
3306 GLenum buf = GL_BACK;
3307 if (GetBackbufferServiceId() != 0) // emulated backbuffer
3308 buf = GL_COLOR_ATTACHMENT0;
3309 glDrawBuffersARB(1, &buf);
3310 }
[email protected]60f22d32012-12-12 00:31:583311 glClear(backbuffer_needs_clear_bits_);
[email protected]ee757922014-06-06 05:21:423312 if (reset_draw_buffer) {
3313 GLenum buf = GL_NONE;
3314 glDrawBuffersARB(1, &buf);
3315 }
[email protected]60f22d32012-12-12 00:31:583316 backbuffer_needs_clear_bits_ = 0;
3317 RestoreClearState();
3318 }
[email protected]0d6bfdc2011-11-02 01:32:203319 return true;
3320 }
3321
[email protected]968351b2011-12-20 08:26:513322 if (framebuffer_manager()->IsComplete(framebuffer)) {
3323 return true;
3324 }
3325
[email protected]0d6bfdc2011-11-02 01:32:203326 GLenum completeness = framebuffer->IsPossiblyComplete();
3327 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513328 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433329 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:273330 return false;
3331 }
[email protected]0d6bfdc2011-11-02 01:32:203332
3333 // Are all the attachments cleared?
3334 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
3335 texture_manager()->HaveUnclearedMips()) {
3336 if (!framebuffer->IsCleared()) {
3337 // Can we clear them?
[email protected]73276522012-11-09 05:50:203338 if (framebuffer->GetStatus(texture_manager(), target) !=
3339 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513340 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433341 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3342 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:203343 return false;
3344 }
3345 ClearUnclearedAttachments(target, framebuffer);
3346 }
3347 }
3348
[email protected]968351b2011-12-20 08:26:513349 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:203350 if (framebuffer->GetStatus(texture_manager(), target) !=
3351 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513352 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433353 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3354 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:513355 return false;
3356 }
3357 framebuffer_manager()->MarkAsComplete(framebuffer);
3358 }
3359
[email protected]0d6bfdc2011-11-02 01:32:203360 // NOTE: At this point we don't know if the framebuffer is complete but
3361 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:273362 return true;
3363}
3364
[email protected]0d6bfdc2011-11-02 01:32:203365bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:153366 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:513367 bool valid = CheckFramebufferValid(
[email protected]9d3b2e12013-10-02 01:04:343368 framebuffer_state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT,
3369 func_name);
[email protected]28718a92013-04-04 12:12:513370
3371 if (valid)
3372 OnUseFramebuffer();
3373
3374 return valid;
[email protected]0d6bfdc2011-11-02 01:32:203375 }
[email protected]9d3b2e12013-10-02 01:04:343376 return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113377 GL_DRAW_FRAMEBUFFER_EXT,
3378 func_name) &&
[email protected]9d3b2e12013-10-02 01:04:343379 CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113380 GL_READ_FRAMEBUFFER_EXT,
3381 func_name);
[email protected]0d6bfdc2011-11-02 01:32:203382}
3383
[email protected]2ea5950d2014-07-09 18:20:343384bool GLES2DecoderImpl::CheckBoundReadFramebufferColorAttachment(
3385 const char* func_name) {
3386 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3387 framebuffer_state_.bound_read_framebuffer.get() :
3388 framebuffer_state_.bound_draw_framebuffer.get();
3389 if (!framebuffer)
3390 return true;
3391 if (framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL) {
3392 LOCAL_SET_GL_ERROR(
3393 GL_INVALID_OPERATION, func_name, "no color image attached");
3394 return false;
3395 }
3396 return true;
3397}
3398
zmo383512cf2014-10-14 00:11:003399bool GLES2DecoderImpl::FormsTextureCopyingFeedbackLoop(
3400 TextureRef* texture, GLint level) {
3401 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3402 framebuffer_state_.bound_read_framebuffer.get() :
3403 framebuffer_state_.bound_draw_framebuffer.get();
3404 if (!framebuffer)
3405 return false;
3406 const Framebuffer::Attachment* attachment = framebuffer->GetAttachment(
3407 GL_COLOR_ATTACHMENT0);
3408 if (!attachment)
3409 return false;
3410 return attachment->FormsFeedbackLoop(texture, level);
3411}
3412
[email protected]8e3e0662010-08-23 18:46:303413gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:353414 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453415 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203416 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:353417 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:203418 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:263419 if (attachment) {
3420 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:503421 }
[email protected]9edc6b22010-12-23 02:00:263422 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:023423 } else if (offscreen_target_frame_buffer_.get()) {
3424 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:353425 } else {
[email protected]f62a5ab2011-05-23 20:34:153426 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:023427 }
[email protected]246a70452010-03-05 21:53:503428}
3429
[email protected]68586372013-12-11 01:27:593430GLenum GLES2DecoderImpl::GetBoundReadFrameBufferTextureType() {
3431 Framebuffer* framebuffer =
3432 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
3433 if (framebuffer != NULL) {
3434 return framebuffer->GetColorAttachmentTextureType();
3435 } else {
3436 return GL_UNSIGNED_BYTE;
3437 }
3438}
3439
[email protected]9edc6b22010-12-23 02:00:263440GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353441 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453442 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203443 if (framebuffer != NULL) {
3444 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:463445 } else if (offscreen_target_frame_buffer_.get()) {
3446 return offscreen_target_color_format_;
3447 } else {
3448 return back_buffer_color_format_;
3449 }
3450}
3451
3452GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353453 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453454 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203455 if (framebuffer != NULL) {
3456 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:263457 } else if (offscreen_target_frame_buffer_.get()) {
3458 return offscreen_target_color_format_;
3459 } else {
[email protected]32fe9aa2011-01-21 23:47:133460 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:263461 }
3462}
3463
[email protected]9a5afa432011-07-22 18:16:393464void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]2ad674132013-06-05 07:48:513465 if (!offscreen_saved_color_texture_info_.get())
3466 return;
3467 GLenum target = offscreen_saved_color_texture_info_->texture()->target();
3468 glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
3469 texture_manager()->SetLevelInfo(
3470 offscreen_saved_color_texture_info_.get(),
3471 GL_TEXTURE_2D,
3472 0, // level
3473 GL_RGBA,
3474 offscreen_size_.width(),
3475 offscreen_size_.height(),
3476 1, // depth
3477 0, // border
3478 GL_RGBA,
3479 GL_UNSIGNED_BYTE,
3480 true);
[email protected]737191ee72014-03-09 08:02:423481 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513482 "UpdateParentTextureInfo",
3483 GetErrorState(),
3484 offscreen_saved_color_texture_info_.get(),
3485 GL_TEXTURE_MAG_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263486 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423487 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513488 "UpdateParentTextureInfo",
3489 GetErrorState(),
3490 offscreen_saved_color_texture_info_.get(),
3491 GL_TEXTURE_MIN_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263492 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423493 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513494 "UpdateParentTextureInfo",
3495 GetErrorState(),
3496 offscreen_saved_color_texture_info_.get(),
3497 GL_TEXTURE_WRAP_S,
3498 GL_CLAMP_TO_EDGE);
[email protected]737191ee72014-03-09 08:02:423499 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513500 "UpdateParentTextureInfo",
3501 GetErrorState(),
3502 offscreen_saved_color_texture_info_.get(),
3503 GL_TEXTURE_WRAP_T,
3504 GL_CLAMP_TO_EDGE);
[email protected]c986af502013-08-14 01:04:443505 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
3506 &state_, target);
[email protected]2ad674132013-06-05 07:48:513507 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
[email protected]6217d392010-03-25 22:08:353508}
3509
[email protected]799b4b22011-08-22 17:09:593510void GLES2DecoderImpl::SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:073511 const base::Callback<void(gfx::Size, float)>& callback) {
[email protected]9d37f062011-11-22 01:24:523512 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:003513}
3514
[email protected]1d82e822013-04-10 21:32:323515Logger* GLES2DecoderImpl::GetLogger() {
3516 return &logger_;
[email protected]6b6e7ee2011-12-13 08:04:523517}
3518
[email protected]cac16542014-01-15 17:53:513519void GLES2DecoderImpl::BeginDecoding() {
3520 gpu_tracer_->BeginDecoding();
dyencb86f2f2014-12-09 18:35:413521 gpu_trace_commands_ = gpu_tracer_->IsTracing() && *gpu_decoder_category_;
vmiura1c2b1de2014-09-19 19:03:243522 gpu_debug_commands_ = log_commands() || debug() || gpu_trace_commands_ ||
3523 (*cb_command_trace_category_ != 0);
[email protected]cac16542014-01-15 17:53:513524}
3525
3526void GLES2DecoderImpl::EndDecoding() {
3527 gpu_tracer_->EndDecoding();
3528}
3529
[email protected]d3eba342013-04-18 21:11:503530ErrorState* GLES2DecoderImpl::GetErrorState() {
3531 return state_.GetErrorState();
3532}
3533
[email protected]e3932abb2013-03-13 00:01:373534void GLES2DecoderImpl::SetShaderCacheCallback(
3535 const ShaderCacheCallback& callback) {
3536 shader_cache_callback_ = callback;
3537}
3538
[email protected]840a7e462013-02-27 01:29:513539void GLES2DecoderImpl::SetWaitSyncPointCallback(
3540 const WaitSyncPointCallback& callback) {
3541 wait_sync_point_callback_ = callback;
3542}
3543
[email protected]85a4ac22013-05-31 01:58:473544AsyncPixelTransferManager*
3545 GLES2DecoderImpl::GetAsyncPixelTransferManager() {
3546 return async_pixel_transfer_manager_.get();
3547}
3548
3549void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
3550 async_pixel_transfer_manager_.reset();
[email protected]32145a92012-12-17 09:01:593551}
3552
[email protected]498b5c072013-06-04 19:30:073553void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest(
3554 AsyncPixelTransferManager* manager) {
3555 async_pixel_transfer_manager_ = make_scoped_ptr(manager);
3556}
3557
[email protected]1318e922010-09-17 22:03:163558bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3559 uint32* service_texture_id) {
[email protected]370eaf12013-05-18 09:19:493560 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3561 if (texture_ref) {
3562 *service_texture_id = texture_ref->service_id();
[email protected]1318e922010-09-17 22:03:163563 return true;
3564 }
3565 return false;
3566}
3567
[email protected]63b465922012-09-06 02:04:523568uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]c986af502013-08-14 01:04:443569 return texture_state_.texture_upload_count +
[email protected]b68b100752013-06-05 08:34:483570 async_pixel_transfer_manager_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523571}
3572
3573base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]c986af502013-08-14 01:04:443574 return texture_state_.total_texture_upload_time +
[email protected]b68b100752013-06-05 08:34:483575 async_pixel_transfer_manager_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523576}
3577
3578base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3579 return total_processing_commands_time_;
3580}
3581
[email protected]dc25dda2012-09-27 21:36:303582void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3583 total_processing_commands_time_ += time;
3584}
3585
[email protected]63c9b052012-05-17 18:27:383586void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063587 if (!initialized())
3588 return;
3589
[email protected]63c9b052012-05-17 18:27:383590 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053591
[email protected]80eb6b52012-01-19 00:14:413592 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243593 state_.vertex_attrib_manager = NULL;
[email protected]81f20a622014-04-18 01:54:523594 state_.default_vertex_attrib_manager = NULL;
[email protected]1868a342012-11-07 15:56:023595 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243596 state_.bound_array_buffer = NULL;
[email protected]8ebd46c2014-01-08 12:06:133597 state_.current_queries.clear();
[email protected]9d3b2e12013-10-02 01:04:343598 framebuffer_state_.bound_read_framebuffer = NULL;
3599 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]e259eb412012-10-13 05:47:243600 state_.bound_renderbuffer = NULL;
orglofchcad5a6742014-11-07 19:51:123601 state_.bound_valuebuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413602
[email protected]cadac622013-06-11 16:46:363603 if (offscreen_saved_color_texture_info_.get()) {
[email protected]2ad674132013-06-05 07:48:513604 DCHECK(offscreen_target_color_texture_);
3605 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
3606 offscreen_saved_color_texture_->id());
3607 offscreen_saved_color_texture_->Invalidate();
3608 offscreen_saved_color_texture_info_ = NULL;
3609 }
[email protected]eadc96792010-10-27 19:39:393610 if (have_context) {
[email protected]c322e882012-05-23 18:06:183611 if (copy_texture_CHROMIUM_.get()) {
3612 copy_texture_CHROMIUM_->Destroy();
3613 copy_texture_CHROMIUM_.reset();
3614 }
[email protected]43410e92012-04-20 17:06:283615
sievers2384f2b2014-11-18 02:10:353616 clear_framebuffer_blit_.reset();
3617
[email protected]7cd76fd2013-06-02 21:11:113618 if (state_.current_program.get()) {
3619 program_manager()->UnuseProgram(shader_manager(),
3620 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:143621 }
3622
[email protected]b1122982010-05-17 23:04:243623 if (attrib_0_buffer_id_) {
3624 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3625 }
[email protected]8fbedc02010-11-18 18:43:403626 if (fixed_attrib_buffer_id_) {
3627 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3628 }
[email protected]b1122982010-05-17 23:04:243629
[email protected]4a4c18b2013-09-13 22:50:103630 if (validation_texture_) {
3631 glDeleteTextures(1, &validation_texture_);
3632 glDeleteFramebuffersEXT(1, &validation_fbo_multisample_);
3633 glDeleteFramebuffersEXT(1, &validation_fbo_);
3634 }
3635
[email protected]97872062010-11-03 19:07:053636 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543637 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053638 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543639 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053640 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023641 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053642 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153643 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053644 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153645 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053646 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023647 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053648 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543649 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273650 if (offscreen_resolved_frame_buffer_.get())
3651 offscreen_resolved_frame_buffer_->Destroy();
3652 if (offscreen_resolved_color_texture_.get())
3653 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053654 } else {
3655 if (offscreen_target_frame_buffer_.get())
3656 offscreen_target_frame_buffer_->Invalidate();
3657 if (offscreen_target_color_texture_.get())
3658 offscreen_target_color_texture_->Invalidate();
3659 if (offscreen_target_color_render_buffer_.get())
3660 offscreen_target_color_render_buffer_->Invalidate();
3661 if (offscreen_target_depth_render_buffer_.get())
3662 offscreen_target_depth_render_buffer_->Invalidate();
3663 if (offscreen_target_stencil_render_buffer_.get())
3664 offscreen_target_stencil_render_buffer_->Invalidate();
3665 if (offscreen_saved_frame_buffer_.get())
3666 offscreen_saved_frame_buffer_->Invalidate();
3667 if (offscreen_saved_color_texture_.get())
3668 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273669 if (offscreen_resolved_frame_buffer_.get())
3670 offscreen_resolved_frame_buffer_->Invalidate();
3671 if (offscreen_resolved_color_texture_.get())
3672 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023673 }
[email protected]83a52d032013-07-24 10:30:373674
3675 // Current program must be cleared after calling ProgramManager::UnuseProgram.
3676 // Otherwise, we can leak objects. http://crbug.com/258772.
3677 // state_.current_program must be reset before group_ is reset because
3678 // the later deletes the ProgramManager object that referred by
3679 // state_.current_program object.
3680 state_.current_program = NULL;
3681
[email protected]43410e92012-04-20 17:06:283682 copy_texture_CHROMIUM_.reset();
sievers2384f2b2014-11-18 02:10:353683 clear_framebuffer_blit_.reset();
[email protected]97872062010-11-03 19:07:053684
[email protected]882ba1e22012-03-08 19:02:533685 if (query_manager_.get()) {
3686 query_manager_->Destroy(have_context);
3687 query_manager_.reset();
3688 }
3689
[email protected]944b62f32012-09-27 02:20:463690 if (vertex_array_manager_ .get()) {
3691 vertex_array_manager_->Destroy(have_context);
3692 vertex_array_manager_.reset();
3693 }
3694
[email protected]d2eaf52f2014-07-31 15:01:243695 if (image_manager_.get()) {
3696 image_manager_->Destroy(have_context);
3697 image_manager_.reset();
3698 }
3699
[email protected]97872062010-11-03 19:07:053700 offscreen_target_frame_buffer_.reset();
3701 offscreen_target_color_texture_.reset();
3702 offscreen_target_color_render_buffer_.reset();
3703 offscreen_target_depth_render_buffer_.reset();
3704 offscreen_target_stencil_render_buffer_.reset();
3705 offscreen_saved_frame_buffer_.reset();
3706 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273707 offscreen_resolved_frame_buffer_.reset();
3708 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463709
[email protected]03cef9b2014-04-03 15:58:143710 // Need to release these before releasing |group_| which may own the
3711 // ShaderTranslatorCache.
3712 fragment_translator_ = NULL;
3713 vertex_translator_ = NULL;
3714
[email protected]85a4ac22013-05-31 01:58:473715 // Should destroy the transfer manager before the texture manager held
3716 // by the context group.
3717 async_pixel_transfer_manager_.reset();
3718
[email protected]7cd76fd2013-06-02 21:11:113719 if (group_.get()) {
[email protected]ac5e4022014-01-24 12:44:393720 framebuffer_manager()->RemoveObserver(this);
[email protected]2d9d3b92013-01-18 01:07:233721 group_->Destroy(this, have_context);
3722 group_ = NULL;
3723 }
3724
3725 if (context_.get()) {
3726 context_->ReleaseCurrent(NULL);
3727 context_ = NULL;
3728 }
3729
[email protected]e51bdf32011-11-23 22:21:463730#if defined(OS_MACOSX)
3731 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3732 it != texture_to_io_surface_map_.end(); ++it) {
3733 CFRelease(it->second);
3734 }
3735 texture_to_io_surface_map_.clear();
3736#endif
[email protected]96449d2c2009-11-25 00:01:323737}
3738
[email protected]63c9b052012-05-17 18:27:383739void GLES2DecoderImpl::SetSurface(
3740 const scoped_refptr<gfx::GLSurface>& surface) {
3741 DCHECK(context_->IsCurrent(NULL));
3742 DCHECK(surface_.get());
3743 surface_ = surface;
3744 RestoreCurrentFramebufferBindings();
3745}
3746
[email protected]aba551b2014-02-08 03:38:323747void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
3748 if (!offscreen_saved_color_texture_.get()) {
3749 LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context";
3750 return;
3751 }
[email protected]2ad674132013-06-05 07:48:513752 if (!offscreen_saved_color_texture_info_.get()) {
[email protected]3c644d82011-06-20 19:58:243753 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]f46476932013-06-08 05:36:073754 offscreen_saved_color_texture_info_ = TextureRef::Create(
3755 texture_manager(), 0, service_id);
[email protected]2ad674132013-06-05 07:48:513756 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(),
3757 GL_TEXTURE_2D);
[email protected]9a5afa432011-07-22 18:16:393758 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243759 }
[email protected]aba551b2014-02-08 03:38:323760 mailbox_manager()->ProduceTexture(
sievers8b373ec52014-10-24 23:04:063761 mailbox, offscreen_saved_color_texture_info_->texture());
[email protected]3c644d82011-06-20 19:58:243762}
3763
[email protected]799b4b22011-08-22 17:09:593764bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3765 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3766 if (!is_offscreen) {
3767 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3768 << " with an onscreen framebuffer.";
3769 return false;
3770 }
3771
3772 if (offscreen_size_ == size)
3773 return true;
3774
3775 offscreen_size_ = size;
3776 int w = offscreen_size_.width();
3777 int h = offscreen_size_.height();
3778 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3779 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3780 << "to allocate storage due to excessive dimensions.";
3781 return false;
3782 }
3783
3784 // Reallocate the offscreen target buffers.
3785 DCHECK(offscreen_target_color_format_);
3786 if (IsOffscreenBufferMultisampled()) {
3787 if (!offscreen_target_color_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253788 feature_info_.get(),
3789 offscreen_size_,
3790 offscreen_target_color_format_,
3791 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593792 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3793 << "to allocate storage for offscreen target color buffer.";
3794 return false;
3795 }
3796 } else {
3797 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093798 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593799 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3800 << "to allocate storage for offscreen target color texture.";
3801 return false;
3802 }
3803 }
3804 if (offscreen_target_depth_format_ &&
3805 !offscreen_target_depth_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253806 feature_info_.get(),
3807 offscreen_size_,
3808 offscreen_target_depth_format_,
3809 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593810 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3811 << "to allocate storage for offscreen target depth buffer.";
3812 return false;
3813 }
3814 if (offscreen_target_stencil_format_ &&
3815 !offscreen_target_stencil_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253816 feature_info_.get(),
3817 offscreen_size_,
3818 offscreen_target_stencil_format_,
3819 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593820 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3821 << "to allocate storage for offscreen target stencil buffer.";
3822 return false;
3823 }
3824
3825 // Attach the offscreen target buffers to the target frame buffer.
3826 if (IsOffscreenBufferMultisampled()) {
3827 offscreen_target_frame_buffer_->AttachRenderBuffer(
3828 GL_COLOR_ATTACHMENT0,
3829 offscreen_target_color_render_buffer_.get());
3830 } else {
3831 offscreen_target_frame_buffer_->AttachRenderTexture(
3832 offscreen_target_color_texture_.get());
3833 }
3834 if (offscreen_target_depth_format_) {
3835 offscreen_target_frame_buffer_->AttachRenderBuffer(
3836 GL_DEPTH_ATTACHMENT,
3837 offscreen_target_depth_render_buffer_.get());
3838 }
3839 const bool packed_depth_stencil =
3840 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3841 if (packed_depth_stencil) {
3842 offscreen_target_frame_buffer_->AttachRenderBuffer(
3843 GL_STENCIL_ATTACHMENT,
3844 offscreen_target_depth_render_buffer_.get());
3845 } else if (offscreen_target_stencil_format_) {
3846 offscreen_target_frame_buffer_->AttachRenderBuffer(
3847 GL_STENCIL_ATTACHMENT,
3848 offscreen_target_stencil_render_buffer_.get());
3849 }
3850
3851 if (offscreen_target_frame_buffer_->CheckStatus() !=
3852 GL_FRAMEBUFFER_COMPLETE) {
3853 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3854 << "because offscreen FBO was incomplete.";
3855 return false;
3856 }
3857
3858 // Clear the target frame buffer.
3859 {
3860 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3861 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
pkasting45796dc2014-10-17 04:18:323862 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1.f);
[email protected]454157e2014-05-03 02:49:453863 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]799b4b22011-08-22 17:09:593864 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473865 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3866 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]799b4b22011-08-22 17:09:593867 glClearDepth(0);
[email protected]454157e2014-05-03 02:49:453868 state_.SetDeviceDepthMask(GL_TRUE);
3869 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]799b4b22011-08-22 17:09:593870 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3871 RestoreClearState();
3872 }
[email protected]d85ef76d2011-09-08 22:21:433873
3874 // Destroy the offscreen resolved framebuffers.
3875 if (offscreen_resolved_frame_buffer_.get())
3876 offscreen_resolved_frame_buffer_->Destroy();
3877 if (offscreen_resolved_color_texture_.get())
3878 offscreen_resolved_color_texture_->Destroy();
3879 offscreen_resolved_color_texture_.reset();
3880 offscreen_resolved_frame_buffer_.reset();
3881
[email protected]799b4b22011-08-22 17:09:593882 return true;
[email protected]6217d392010-03-25 22:08:353883}
3884
vmiuracd108592014-09-08 14:36:343885error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(uint32 immediate_data_size,
3886 const void* cmd_data) {
3887 const gles2::cmds::ResizeCHROMIUM& c =
3888 *static_cast<const gles2::cmds::ResizeCHROMIUM*>(cmd_data);
[email protected]09e17272012-11-30 10:30:443889 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023890 return error::kDeferCommandUntilLater;
3891
[email protected]799b4b22011-08-22 17:09:593892 GLuint width = static_cast<GLuint>(c.width);
3893 GLuint height = static_cast<GLuint>(c.height);
[email protected]729c0b42013-05-26 02:05:073894 GLfloat scale_factor = c.scale_factor;
[email protected]799b4b22011-08-22 17:09:593895 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:413896
3897 width = std::max(1U, width);
3898 height = std::max(1U, height);
3899
[email protected]a0d989162011-11-22 13:15:073900#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3901 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003902 // Make sure that we are done drawing to the back buffer before resizing.
3903 glFinish();
3904#endif
[email protected]799b4b22011-08-22 17:09:593905 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3906 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493907 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3908 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3909 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593910 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493911 }
[email protected]7ff86b92010-11-25 17:50:003912 }
[email protected]799b4b22011-08-22 17:09:593913
[email protected]9d37f062011-11-22 01:24:523914 if (!resize_callback_.is_null()) {
[email protected]729c0b42013-05-26 02:05:073915 resize_callback_.Run(gfx::Size(width, height), scale_factor);
[email protected]0e9346b2013-03-16 16:35:443916 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493917 if (!context_->IsCurrent(surface_.get())) {
3918 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3919 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053920 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493921 }
[email protected]658f7562011-09-09 05:24:053922 }
[email protected]799b4b22011-08-22 17:09:593923
3924 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393925}
3926
[email protected]96449d2c2009-11-25 00:01:323927const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3928 if (command_id > kStartPoint && command_id < kNumCommands) {
3929 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3930 }
3931 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3932}
3933
vmiura8266ca72014-09-09 21:37:003934// Decode a command, and call the corresponding GL functions.
3935// NOTE: DoCommand() is slower than calling DoCommands() on larger batches
3936// of commands at once, and is now only used for tests that need to track
3937// individual commands.
3938error::Error GLES2DecoderImpl::DoCommand(unsigned int command,
3939 unsigned int arg_count,
3940 const void* cmd_data) {
3941 return DoCommands(1, cmd_data, arg_count + 1, 0);
3942}
3943
3944// Decode multiple commands, and call the corresponding GL functions.
3945// NOTE: 'buffer' is a pointer to the command buffer. As such, it could be
3946// changed by a (malicious) client at any time, so if validation has to happen,
3947// it should operate on a copy of them.
3948// NOTE: This is duplicating code from AsyncAPIInterface::DoCommands() in the
3949// interest of performance in this critical execution loop.
vmiura1c2b1de2014-09-19 19:03:243950template <bool DebugImpl>
3951error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands,
3952 const void* buffer,
3953 int num_entries,
3954 int* entries_processed) {
vmiura8266ca72014-09-09 21:37:003955 commands_to_process_ = num_commands;
[email protected]f7a64ee2010-02-01 22:24:143956 error::Error result = error::kNoError;
vmiura8266ca72014-09-09 21:37:003957 const CommandBufferEntry* cmd_data =
3958 static_cast<const CommandBufferEntry*>(buffer);
3959 int process_pos = 0;
3960 unsigned int command = 0;
3961
3962 while (process_pos < num_entries && result == error::kNoError &&
3963 commands_to_process_--) {
3964 const unsigned int size = cmd_data->value_header.size;
3965 command = cmd_data->value_header.command;
3966
3967 if (size == 0) {
3968 result = error::kInvalidSize;
3969 break;
3970 }
3971
3972 if (static_cast<int>(size) + process_pos > num_entries) {
3973 result = error::kOutOfBounds;
3974 break;
3975 }
3976
vmiura1c2b1de2014-09-19 19:03:243977 if (DebugImpl) {
3978 TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
3979 GetCommandName(command));
vmiura8266ca72014-09-09 21:37:003980
vmiura1c2b1de2014-09-19 19:03:243981 if (log_commands()) {
3982 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]"
3983 << "cmd: " << GetCommandName(command);
3984 }
vmiura8266ca72014-09-09 21:37:003985 }
3986
3987 const unsigned int arg_count = size - 1;
3988 unsigned int command_index = command - kStartPoint - 1;
3989 if (command_index < arraysize(command_info)) {
3990 const CommandInfo& info = command_info[command_index];
3991 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3992 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3993 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
3994 bool doing_gpu_trace = false;
vmiura1c2b1de2014-09-19 19:03:243995 if (DebugImpl && gpu_trace_commands_) {
vmiura8266ca72014-09-09 21:37:003996 if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) {
3997 doing_gpu_trace = true;
dyencb86f2f2014-12-09 18:35:413998 gpu_tracer_->Begin(TRACE_DISABLED_BY_DEFAULT("gpu_decoder"),
3999 GetCommandName(command),
4000 kTraceDecoder);
vmiura8266ca72014-09-09 21:37:004001 }
[email protected]cac16542014-01-15 17:53:514002 }
[email protected]cac16542014-01-15 17:53:514003
vmiura8266ca72014-09-09 21:37:004004 uint32 immediate_data_size = (arg_count - info_arg_count) *
4005 sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:324006
vmiura8266ca72014-09-09 21:37:004007 result = (this->*info.cmd_handler)(immediate_data_size, cmd_data);
[email protected]cac16542014-01-15 17:53:514008
vmiura1c2b1de2014-09-19 19:03:244009 if (DebugImpl && doing_gpu_trace)
vmiura8266ca72014-09-09 21:37:004010 gpu_tracer_->End(kTraceDecoder);
[email protected]cac16542014-01-15 17:53:514011
vmiura1c2b1de2014-09-19 19:03:244012 if (DebugImpl && debug()) {
vmiura8266ca72014-09-09 21:37:004013 GLenum error;
4014 while ((error = glGetError()) != GL_NO_ERROR) {
4015 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
4016 << "GL ERROR: " << GLES2Util::GetStringEnum(error)
4017 << " : " << GetCommandName(command);
4018 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
4019 }
[email protected]b9849abf2009-11-25 19:13:194020 }
vmiura8266ca72014-09-09 21:37:004021 } else {
4022 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:324023 }
4024 } else {
vmiura8266ca72014-09-09 21:37:004025 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:324026 }
vmiura1c2b1de2014-09-19 19:03:244027
4028 if (DebugImpl) {
4029 TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
4030 GetCommandName(command));
4031 }
4032
vmiura8266ca72014-09-09 21:37:004033 if (result == error::kNoError &&
4034 current_decoder_error_ != error::kNoError) {
[email protected]a3a93e7b2010-08-28 00:48:564035 result = current_decoder_error_;
4036 current_decoder_error_ = error::kNoError;
vmiura8266ca72014-09-09 21:37:004037 }
4038
4039 if (result != error::kDeferCommandUntilLater) {
4040 process_pos += size;
4041 cmd_data += size;
4042 }
[email protected]a3a93e7b2010-08-28 00:48:564043 }
vmiura8266ca72014-09-09 21:37:004044
4045 if (entries_processed)
4046 *entries_processed = process_pos;
4047
4048 if (error::IsError(result)) {
4049 LOG(ERROR) << "Error: " << result << " for Command "
4050 << GetCommandName(command);
4051 }
4052
[email protected]b9849abf2009-11-25 19:13:194053 return result;
[email protected]96449d2c2009-11-25 00:01:324054}
4055
vmiura1c2b1de2014-09-19 19:03:244056error::Error GLES2DecoderImpl::DoCommands(unsigned int num_commands,
4057 const void* buffer,
4058 int num_entries,
4059 int* entries_processed) {
4060 if (gpu_debug_commands_) {
4061 return DoCommandsImpl<true>(
4062 num_commands, buffer, num_entries, entries_processed);
4063 } else {
4064 return DoCommandsImpl<false>(
4065 num_commands, buffer, num_entries, entries_processed);
4066 }
4067}
4068
[email protected]ed9f9cd2013-02-27 21:12:354069void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
4070 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:504071}
4072
[email protected]882ba1e22012-03-08 19:02:534073void GLES2DecoderImpl::DoFinish() {
4074 glFinish();
[email protected]5a36dc132013-07-23 23:17:554075 ProcessPendingReadPixels();
revemancc241eb2014-11-11 03:30:374076 ProcessPendingQueries(true);
[email protected]882ba1e22012-03-08 19:02:534077}
4078
4079void GLES2DecoderImpl::DoFlush() {
4080 glFlush();
revemancc241eb2014-11-11 03:30:374081 ProcessPendingQueries(false);
[email protected]882ba1e22012-03-08 19:02:534082}
4083
[email protected]3916c97e2010-02-25 03:20:504084void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:454085 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:024086 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:514087 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:534088 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:504089 return;
4090 }
[email protected]e259eb412012-10-13 05:47:244091 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:454092 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:504093}
4094
[email protected]051b1372010-04-12 02:42:084095void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:074096 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:084097 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034098 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:074099 buffer = GetBuffer(client_id);
4100 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:354101 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224102 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4103 "glBindBuffer",
4104 "id not generated by glGenBuffers");
[email protected]bf5a8d132011-08-16 08:39:354105 return;
4106 }
4107
[email protected]b10492f2013-03-08 05:24:074108 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:034109 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354110 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:074111 buffer = GetBuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034112 }
[email protected]051b1372010-04-12 02:42:084113 }
[email protected]b10492f2013-03-08 05:24:074114 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
4115 if (buffer) {
4116 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:514117 LOCAL_SET_GL_ERROR(
4118 GL_INVALID_OPERATION,
4119 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:474120 return;
4121 }
[email protected]b10492f2013-03-08 05:24:074122 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:474123 }
[email protected]96449d2c2009-11-25 00:01:324124 switch (target) {
4125 case GL_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:074126 state_.bound_array_buffer = buffer;
[email protected]96449d2c2009-11-25 00:01:324127 break;
4128 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:074129 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
[email protected]96449d2c2009-11-25 00:01:324130 break;
4131 default:
[email protected]a93bb842010-02-16 23:03:474132 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:324133 break;
4134 }
[email protected]051b1372010-04-12 02:42:084135 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:324136}
4137
[email protected]f3b191b2013-06-19 03:43:544138bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha(
4139 bool all_draw_buffers) {
4140 Framebuffer* framebuffer =
4141 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
4142 if (!all_draw_buffers || !framebuffer) {
4143 return (GLES2Util::GetChannelsForFormat(
4144 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
4145 }
4146 return framebuffer->HasAlphaMRT();
[email protected]297ca1c2011-06-20 23:08:464147}
4148
4149bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:354150 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454151 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204152 if (framebuffer) {
4153 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:464154 }
4155 if (offscreen_target_frame_buffer_.get()) {
4156 return offscreen_target_depth_format_ != 0;
4157 }
4158 return back_buffer_has_depth_;
4159}
4160
4161bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:354162 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454163 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204164 if (framebuffer) {
4165 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:464166 }
4167 if (offscreen_target_frame_buffer_.get()) {
4168 return offscreen_target_stencil_format_ != 0 ||
4169 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
4170 }
4171 return back_buffer_has_stencil_;
4172}
4173
4174void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]c986af502013-08-14 01:04:444175 if (framebuffer_state_.clear_state_dirty) {
[email protected]454157e2014-05-03 02:49:454176 bool have_alpha = BoundFramebufferHasColorAttachmentWithAlpha(true);
4177 state_.SetDeviceColorMask(state_.color_mask_red,
4178 state_.color_mask_green,
4179 state_.color_mask_blue,
4180 state_.color_mask_alpha && have_alpha);
4181
[email protected]297ca1c2011-06-20 23:08:464182 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]454157e2014-05-03 02:49:454183 state_.SetDeviceDepthMask(state_.depth_mask && have_depth);
4184
[email protected]297ca1c2011-06-20 23:08:464185 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]454157e2014-05-03 02:49:454186 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424187 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]454157e2014-05-03 02:49:454188 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424189 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]454157e2014-05-03 02:49:454190
4191 state_.SetDeviceCapabilityState(
4192 GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
4193 state_.SetDeviceCapabilityState(
[email protected]f731b9462012-10-30 00:35:224194 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
[email protected]c986af502013-08-14 01:04:444195 framebuffer_state_.clear_state_dirty = false;
[email protected]297ca1c2011-06-20 23:08:464196 }
4197}
4198
[email protected]1868a342012-11-07 15:56:024199GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]7cd76fd2013-06-02 21:11:114200 return (offscreen_target_frame_buffer_.get())
4201 ? offscreen_target_frame_buffer_->id()
4202 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0);
[email protected]1868a342012-11-07 15:56:024203}
4204
[email protected]8875a5f2014-06-27 08:33:474205void GLES2DecoderImpl::RestoreState(const ContextState* prev_state) {
[email protected]962bfbe72013-05-24 11:16:144206 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
4207 "context", logger_.GetLogPrefix());
[email protected]29a4d902013-02-26 20:18:064208 // Restore the Framebuffer first because of bugs in Intel drivers.
4209 // Intel drivers incorrectly clip the viewport settings to
4210 // the size of the current framebuffer object.
4211 RestoreFramebufferBindings();
[email protected]5baa86bc2014-01-16 04:33:164212 state_.RestoreState(prev_state);
[email protected]29a4d902013-02-26 20:18:064213}
4214
4215void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]9d3b2e12013-10-02 01:04:344216 GLuint service_id =
4217 framebuffer_state_.bound_draw_framebuffer.get()
4218 ? framebuffer_state_.bound_draw_framebuffer->service_id()
4219 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064220 if (!features().chromium_framebuffer_multisample) {
4221 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
4222 } else {
4223 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
[email protected]9d3b2e12013-10-02 01:04:344224 service_id = framebuffer_state_.bound_read_framebuffer.get()
4225 ? framebuffer_state_.bound_read_framebuffer->service_id()
[email protected]7cd76fd2013-06-02 21:11:114226 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064227 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
4228 }
[email protected]70d34263c2013-01-09 00:27:454229 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:064230}
4231
[email protected]8875a5f2014-06-27 08:33:474232void GLES2DecoderImpl::RestoreRenderbufferBindings() {
4233 state_.RestoreRenderbufferBindings();
4234}
4235
[email protected]29a4d902013-02-26 20:18:064236void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
[email protected]62e65f02013-05-29 22:28:104237 Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
4238 if (texture) {
[email protected]9bc9a2e82013-04-03 03:56:254239 GLenum target = texture->target();
4240 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:064241 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254242 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:064243 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254244 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:064245 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254246 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:064247 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254248 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:064249 RestoreTextureUnitBindings(state_.active_texture_unit);
4250 }
[email protected]70d34263c2013-01-09 00:27:454251}
4252
[email protected]cd2ef752014-02-12 23:16:034253void GLES2DecoderImpl::ClearAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524254 // Must use native VAO 0, as RestoreAllAttributes can't fully restore
4255 // other VAOs.
4256 if (feature_info_->feature_flags().native_vertex_array_object)
4257 glBindVertexArrayOES(0);
4258
[email protected]cd2ef752014-02-12 23:16:034259 for (uint32 i = 0; i < group_->max_vertex_attribs(); ++i) {
4260 if (i != 0) // Never disable attribute 0
4261 glDisableVertexAttribArray(i);
4262 if(features().angle_instanced_arrays)
4263 glVertexAttribDivisorANGLE(i, 0);
4264 }
4265}
4266
4267void GLES2DecoderImpl::RestoreAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524268 state_.RestoreVertexAttribs();
[email protected]cd2ef752014-02-12 23:16:034269}
4270
[email protected]454157e2014-05-03 02:49:454271void GLES2DecoderImpl::SetIgnoreCachedStateForTest(bool ignore) {
4272 state_.SetIgnoreCachedStateForTest(ignore);
4273}
4274
[email protected]70d34263c2013-01-09 00:27:454275void GLES2DecoderImpl::OnFboChanged() const {
4276 if (workarounds().restore_scissor_on_fbo_change)
[email protected]28718a92013-04-04 12:12:514277 state_.fbo_binding_for_scissor_workaround_dirty_ = true;
ccameron4ff12a732014-12-12 21:38:194278
4279 if (workarounds().gl_begin_gl_end_on_fbo_change_to_backbuffer) {
4280 GLint bound_fbo_unsigned = -1;
4281 glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &bound_fbo_unsigned);
4282 GLuint bound_fbo = static_cast<GLuint>(bound_fbo_unsigned);
4283 if (surface_ && surface_->GetBackingFrameBufferObject() == bound_fbo)
4284 surface_->NotifyWasBound();
4285 }
[email protected]28718a92013-04-04 12:12:514286}
4287
4288// Called after the FBO is checked for completeness.
4289void GLES2DecoderImpl::OnUseFramebuffer() const {
4290 if (state_.fbo_binding_for_scissor_workaround_dirty_) {
4291 state_.fbo_binding_for_scissor_workaround_dirty_ = false;
[email protected]81fc9d02013-03-14 23:53:324292 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:514293 glScissor(state_.scissor_x,
4294 state_.scissor_y,
4295 state_.scissor_width,
4296 state_.scissor_height);
4297
4298 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
4299 // it's unclear how this bug works.
4300 glFlush();
4301 }
[email protected]b177ae22011-11-01 03:29:114302}
4303
[email protected]051b1372010-04-12 02:42:084304void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:064305 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:084306 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034307 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:064308 framebuffer = GetFramebuffer(client_id);
4309 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:354310 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224311 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4312 "glBindFramebuffer",
4313 "id not generated by glGenFramebuffers");
4314 return;
[email protected]bf5a8d132011-08-16 08:39:354315 }
4316
[email protected]4d8f0dd2013-03-09 14:37:064317 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:034318 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354319 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:064320 framebuffer = GetFramebuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034321 } else {
[email protected]4d8f0dd2013-03-09 14:37:064322 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:084323 }
[email protected]4d8f0dd2013-03-09 14:37:064324 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084325 }
[email protected]4d8f0dd2013-03-09 14:37:064326 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:304327
4328 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344329 framebuffer_state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304330 }
[email protected]cac16542014-01-15 17:53:514331
4332 // vmiura: This looks like dup code
[email protected]8e3e0662010-08-23 18:46:304333 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344334 framebuffer_state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304335 }
[email protected]6217d392010-03-25 22:08:354336
[email protected]c986af502013-08-14 01:04:444337 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:464338
[email protected]b177ae22011-11-01 03:29:114339 // If we are rendering to the backbuffer get the FBO id for any simulated
4340 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:064341 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:114342 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:464343 }
[email protected]6217d392010-03-25 22:08:354344
[email protected]051b1372010-04-12 02:42:084345 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:454346 OnFboChanged();
[email protected]86093972010-03-11 00:13:564347}
4348
[email protected]051b1372010-04-12 02:42:084349void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:274350 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:084351 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034352 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:274353 renderbuffer = GetRenderbuffer(client_id);
4354 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:354355 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224356 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4357 "glBindRenderbuffer",
4358 "id not generated by glGenRenderbuffers");
[email protected]bf5a8d132011-08-16 08:39:354359 return;
4360 }
4361
[email protected]8875a5f2014-06-27 08:33:474362 // It's a new id so make a renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:034363 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354364 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:274365 renderbuffer = GetRenderbuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034366 } else {
[email protected]ee2a79c32013-03-10 03:50:274367 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:084368 }
[email protected]ee2a79c32013-03-10 03:50:274369 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084370 }
[email protected]caa13ed2014-02-17 11:29:204371 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenderbuffer");
[email protected]ee2a79c32013-03-10 03:50:274372 state_.bound_renderbuffer = renderbuffer;
[email protected]8875a5f2014-06-27 08:33:474373 state_.bound_renderbuffer_valid = true;
4374 glBindRenderbufferEXT(GL_RENDERBUFFER, service_id);
[email protected]86093972010-03-11 00:13:564375}
4376
[email protected]051b1372010-04-12 02:42:084377void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:494378 TextureRef* texture_ref = NULL;
[email protected]051b1372010-04-12 02:42:084379 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034380 if (client_id != 0) {
[email protected]370eaf12013-05-18 09:19:494381 texture_ref = GetTexture(client_id);
4382 if (!texture_ref) {
[email protected]bf5a8d132011-08-16 08:39:354383 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224384 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4385 "glBindTexture",
4386 "id not generated by glGenTextures");
4387 return;
[email protected]bf5a8d132011-08-16 08:39:354388 }
4389
[email protected]02965c22013-03-09 02:40:074390 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:034391 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:414392 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:354393 CreateTexture(client_id, service_id);
[email protected]370eaf12013-05-18 09:19:494394 texture_ref = GetTexture(client_id);
[email protected]ae51d192010-04-27 00:48:034395 }
4396 } else {
[email protected]370eaf12013-05-18 09:19:494397 texture_ref = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:084398 }
[email protected]ae51d192010-04-27 00:48:034399
[email protected]1958e0e2010-04-22 05:17:154400 // Check the texture exists
[email protected]5ebf59f2014-04-08 03:51:574401 if (texture_ref) {
4402 Texture* texture = texture_ref->texture();
4403 // Check that we are not trying to bind it to a different target.
4404 if (texture->target() != 0 && texture->target() != target) {
4405 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4406 "glBindTexture",
4407 "texture bound to more than 1 target.");
4408 return;
4409 }
4410 LogClientServiceForInfo(texture, client_id, "glBindTexture");
4411 if (texture->target() == 0) {
4412 texture_manager()->SetTarget(texture_ref, target);
4413 }
4414 glBindTexture(target, texture->service_id());
4415 } else {
4416 glBindTexture(target, 0);
[email protected]1958e0e2010-04-22 05:17:154417 }
[email protected]32145a92012-12-17 09:01:594418
[email protected]e259eb412012-10-13 05:47:244419 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:504420 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:474421 switch (target) {
4422 case GL_TEXTURE_2D:
[email protected]370eaf12013-05-18 09:19:494423 unit.bound_texture_2d = texture_ref;
[email protected]a93bb842010-02-16 23:03:474424 break;
4425 case GL_TEXTURE_CUBE_MAP:
[email protected]370eaf12013-05-18 09:19:494426 unit.bound_texture_cube_map = texture_ref;
[email protected]a93bb842010-02-16 23:03:474427 break;
[email protected]61eeb33f2011-07-26 15:30:314428 case GL_TEXTURE_EXTERNAL_OES:
[email protected]370eaf12013-05-18 09:19:494429 unit.bound_texture_external_oes = texture_ref;
[email protected]61eeb33f2011-07-26 15:30:314430 break;
[email protected]e51bdf32011-11-23 22:21:464431 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]370eaf12013-05-18 09:19:494432 unit.bound_texture_rectangle_arb = texture_ref;
[email protected]e51bdf32011-11-23 22:21:464433 break;
[email protected]a93bb842010-02-16 23:03:474434 default:
4435 NOTREACHED(); // Validation should prevent us getting here.
4436 break;
4437 }
4438}
4439
[email protected]07f54fcc2009-12-22 02:46:304440void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244441 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:124442 if (index != 0 ||
4443 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:244444 glDisableVertexAttribArray(index);
4445 }
[email protected]07f54fcc2009-12-22 02:46:304446 } else {
[email protected]ab09b612013-03-11 22:11:514447 LOCAL_SET_GL_ERROR(
4448 GL_INVALID_VALUE,
4449 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304450 }
4451}
4452
[email protected]60f22d32012-12-12 00:31:584453void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
4454 GLsizei numAttachments,
4455 const GLenum* attachments) {
[email protected]ed9f9cd2013-02-27 21:12:354456 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:584457 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4458
4459 // Validates the attachments. If one of them fails
4460 // the whole command fails.
4461 for (GLsizei i = 0; i < numAttachments; ++i) {
4462 if ((framebuffer &&
4463 !validators_->attachment.IsValid(attachments[i])) ||
4464 (!framebuffer &&
4465 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:514466 LOCAL_SET_GL_ERROR_INVALID_ENUM(
4467 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:584468 return;
4469 }
4470 }
4471
4472 // Marks each one of them as not cleared
4473 for (GLsizei i = 0; i < numAttachments; ++i) {
4474 if (framebuffer) {
4475 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
4476 texture_manager(),
4477 attachments[i],
4478 false);
4479 } else {
4480 switch (attachments[i]) {
4481 case GL_COLOR_EXT:
4482 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
4483 break;
4484 case GL_DEPTH_EXT:
4485 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
4486 case GL_STENCIL_EXT:
4487 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
4488 break;
4489 default:
4490 NOTREACHED();
4491 break;
4492 }
4493 }
4494 }
4495
[email protected]d49c5402013-09-11 15:39:024496 // If the default framebuffer is bound but we are still rendering to an
4497 // FBO, translate attachment names that refer to default framebuffer
4498 // channels to corresponding framebuffer attachments.
4499 scoped_ptr<GLenum[]> translated_attachments(new GLenum[numAttachments]);
4500 for (GLsizei i = 0; i < numAttachments; ++i) {
4501 GLenum attachment = attachments[i];
4502 if (!framebuffer && GetBackbufferServiceId()) {
4503 switch (attachment) {
4504 case GL_COLOR_EXT:
4505 attachment = GL_COLOR_ATTACHMENT0;
4506 break;
4507 case GL_DEPTH_EXT:
4508 attachment = GL_DEPTH_ATTACHMENT;
4509 break;
4510 case GL_STENCIL_EXT:
4511 attachment = GL_STENCIL_ATTACHMENT;
4512 break;
4513 default:
4514 NOTREACHED();
4515 return;
4516 }
4517 }
4518 translated_attachments[i] = attachment;
4519 }
4520
boliu2e7d8a7a2014-10-16 20:35:204521 ScopedRenderTo do_render(framebuffer);
zmo68fcdc62014-12-05 21:51:494522 if (feature_info_->gl_version_info().is_es3) {
4523 glInvalidateFramebuffer(
4524 target, numAttachments, translated_attachments.get());
4525 } else {
4526 glDiscardFramebufferEXT(
4527 target, numAttachments, translated_attachments.get());
4528 }
[email protected]60f22d32012-12-12 00:31:584529}
4530
[email protected]07f54fcc2009-12-22 02:46:304531void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244532 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:304533 glEnableVertexAttribArray(index);
4534 } else {
[email protected]ab09b612013-03-11 22:11:514535 LOCAL_SET_GL_ERROR(
4536 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304537 }
4538}
4539
[email protected]a93bb842010-02-16 23:03:474540void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]c986af502013-08-14 01:04:444541 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
4542 &state_, target);
[email protected]370eaf12013-05-18 09:19:494543 if (!texture_ref ||
4544 !texture_manager()->CanGenerateMipmaps(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:514545 LOCAL_SET_GL_ERROR(
4546 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:474547 return;
4548 }
[email protected]38c0a972012-05-12 00:48:024549
[email protected]12d95352012-12-14 07:23:544550 if (target == GL_TEXTURE_CUBE_MAP) {
4551 for (int i = 0; i < 6; ++i) {
4552 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]370eaf12013-05-18 09:19:494553 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
[email protected]ab09b612013-03-11 22:11:514554 LOCAL_SET_GL_ERROR(
4555 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544556 return;
4557 }
4558 }
4559 } else {
[email protected]370eaf12013-05-18 09:19:494560 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
[email protected]ab09b612013-03-11 22:11:514561 LOCAL_SET_GL_ERROR(
4562 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544563 return;
4564 }
[email protected]7687479c2012-05-14 23:54:044565 }
4566
[email protected]ab09b612013-03-11 22:11:514567 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:194568 // Workaround for Mac driver bug. In the large scheme of things setting
4569 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:564570 // hit so there's probably no need to make this conditional. The bug appears
4571 // to be that if the filtering mode is set to something that doesn't require
4572 // mipmaps for rendering, or is never set to something other than the default,
4573 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:154574 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:194575 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4576 }
[email protected]a93bb842010-02-16 23:03:474577 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:154578 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]370eaf12013-05-18 09:19:494579 glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
4580 texture_ref->texture()->min_filter());
[email protected]c892a4e12012-05-08 18:20:194581 }
[email protected]ab09b612013-03-11 22:11:514582 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:024583 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:494584 texture_manager()->MarkMipmapsGenerated(texture_ref);
[email protected]38c0a972012-05-12 00:48:024585 }
[email protected]a93bb842010-02-16 23:03:474586}
4587
[email protected]b273e432010-04-12 17:23:584588bool GLES2DecoderImpl::GetHelper(
4589 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:584590 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:154591 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4592 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434593 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4594 *num_written = 1;
[email protected]c959a09a2014-03-27 11:44:214595 // Return the GL implementation's preferred format and (see below type)
4596 // if we have the GL extension that exposes this. This allows the GPU
4597 // client to use the implementation's preferred format for glReadPixels
4598 // for optimisation.
4599 //
4600 // A conflicting extension (GL_ARB_ES2_compatibility) specifies an error
4601 // case when requested on integer/floating point buffers but which is
4602 // acceptable on GLES2 and with the GL_OES_read_format extension.
4603 //
4604 // Therefore if an error occurs we swallow the error and use the
4605 // internal implementation.
[email protected]ad84a3a2012-06-08 21:42:434606 if (params) {
[email protected]c959a09a2014-03-27 11:44:214607 if (context_->HasExtension("GL_OES_read_format")) {
4608 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4609 GetErrorState());
4610 glGetIntegerv(pname, params);
4611 if (glGetError() == GL_NO_ERROR)
4612 return true;
4613 }
[email protected]68586372013-12-11 01:27:594614 *params = GLES2Util::GetPreferredGLReadPixelsFormat(
4615 GetBoundReadFrameBufferInternalFormat());
[email protected]ad84a3a2012-06-08 21:42:434616 }
4617 return true;
4618 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4619 *num_written = 1;
4620 if (params) {
[email protected]c959a09a2014-03-27 11:44:214621 if (context_->HasExtension("GL_OES_read_format")) {
4622 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4623 GetErrorState());
4624 glGetIntegerv(pname, params);
4625 if (glGetError() == GL_NO_ERROR)
4626 return true;
4627 }
[email protected]68586372013-12-11 01:27:594628 *params = GLES2Util::GetPreferredGLReadPixelsType(
4629 GetBoundReadFrameBufferInternalFormat(),
4630 GetBoundReadFrameBufferTextureType());
[email protected]ad84a3a2012-06-08 21:42:434631 }
4632 return true;
4633 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4634 *num_written = 1;
4635 if (params) {
4636 *params = group_->max_fragment_uniform_vectors();
4637 }
4638 return true;
4639 case GL_MAX_VARYING_VECTORS:
4640 *num_written = 1;
4641 if (params) {
4642 *params = group_->max_varying_vectors();
4643 }
4644 return true;
4645 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4646 *num_written = 1;
4647 if (params) {
4648 *params = group_->max_vertex_uniform_vectors();
4649 }
4650 return true;
[email protected]4e8a5b122010-05-08 22:00:104651 }
[email protected]5cb735d2011-10-13 01:37:234652 }
4653 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:244654 case GL_MAX_VIEWPORT_DIMS:
4655 if (offscreen_target_frame_buffer_.get()) {
4656 *num_written = 2;
4657 if (params) {
4658 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4659 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4660 }
4661 return true;
4662 }
[email protected]5cb735d2011-10-13 01:37:234663 return false;
[email protected]84afefa2011-10-19 21:45:534664 case GL_MAX_SAMPLES:
4665 *num_written = 1;
4666 if (params) {
4667 params[0] = renderbuffer_manager()->max_samples();
4668 }
4669 return true;
4670 case GL_MAX_RENDERBUFFER_SIZE:
4671 *num_written = 1;
4672 if (params) {
4673 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4674 }
4675 return true;
[email protected]5cb735d2011-10-13 01:37:234676 case GL_MAX_TEXTURE_SIZE:
4677 *num_written = 1;
4678 if (params) {
4679 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4680 }
4681 return true;
4682 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4683 *num_written = 1;
4684 if (params) {
4685 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4686 }
4687 return true;
[email protected]2f143d482013-03-14 18:04:494688 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4689 *num_written = 1;
4690 if (params) {
4691 params[0] = group_->max_color_attachments();
4692 }
4693 return true;
4694 case GL_MAX_DRAW_BUFFERS_ARB:
4695 *num_written = 1;
4696 if (params) {
4697 params[0] = group_->max_draw_buffers();
4698 }
4699 return true;
[email protected]297ca1c2011-06-20 23:08:464700 case GL_ALPHA_BITS:
4701 *num_written = 1;
4702 if (params) {
4703 GLint v = 0;
4704 glGetIntegerv(GL_ALPHA_BITS, &v);
[email protected]f3b191b2013-06-19 03:43:544705 params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
[email protected]297ca1c2011-06-20 23:08:464706 }
4707 return true;
4708 case GL_DEPTH_BITS:
4709 *num_written = 1;
4710 if (params) {
4711 GLint v = 0;
4712 glGetIntegerv(GL_DEPTH_BITS, &v);
4713 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4714 }
4715 return true;
4716 case GL_STENCIL_BITS:
4717 *num_written = 1;
4718 if (params) {
4719 GLint v = 0;
4720 glGetIntegerv(GL_STENCIL_BITS, &v);
4721 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4722 }
4723 return true;
[email protected]656dcaad2010-05-07 17:18:374724 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114725 *num_written = validators_->compressed_texture_format.GetValues().size();
4726 if (params) {
4727 for (GLint ii = 0; ii < *num_written; ++ii) {
4728 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4729 }
4730 }
[email protected]656dcaad2010-05-07 17:18:374731 return true;
[email protected]b273e432010-04-12 17:23:584732 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4733 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104734 if (params) {
[email protected]302ce6d2011-07-07 23:28:114735 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104736 }
[email protected]b273e432010-04-12 17:23:584737 return true;
4738 case GL_NUM_SHADER_BINARY_FORMATS:
4739 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104740 if (params) {
[email protected]302ce6d2011-07-07 23:28:114741 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104742 }
[email protected]b273e432010-04-12 17:23:584743 return true;
4744 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114745 *num_written = validators_->shader_binary_format.GetValues().size();
4746 if (params) {
4747 for (GLint ii = 0; ii < *num_written; ++ii) {
4748 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4749 }
4750 }
4751 return true;
[email protected]b273e432010-04-12 17:23:584752 case GL_SHADER_COMPILER:
4753 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104754 if (params) {
4755 *params = GL_TRUE;
4756 }
[email protected]b273e432010-04-12 17:23:584757 return true;
[email protected]6b8cf1a2010-05-06 16:13:584758 case GL_ARRAY_BUFFER_BINDING:
4759 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104760 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114761 if (state_.bound_array_buffer.get()) {
[email protected]4e8a5b122010-05-08 22:00:104762 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:244763 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:104764 &client_id);
4765 *params = client_id;
4766 } else {
4767 *params = 0;
4768 }
[email protected]6b8cf1a2010-05-06 16:13:584769 }
4770 return true;
4771 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4772 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104773 if (params) {
[email protected]e259eb412012-10-13 05:47:244774 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:104775 GLuint client_id = 0;
4776 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:254777 state_.vertex_attrib_manager->element_array_buffer()->
4778 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104779 *params = client_id;
4780 } else {
4781 *params = 0;
4782 }
[email protected]6b8cf1a2010-05-06 16:13:584783 }
4784 return true;
4785 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304786 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584787 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104788 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354789 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454790 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204791 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104792 GLuint client_id = 0;
4793 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204794 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304795 *params = client_id;
4796 } else {
4797 *params = 0;
4798 }
4799 }
4800 return true;
[email protected]ebfb73c2012-08-15 02:37:454801 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304802 *num_written = 1;
4803 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354804 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454805 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204806 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304807 GLuint client_id = 0;
4808 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204809 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104810 *params = client_id;
4811 } else {
4812 *params = 0;
4813 }
[email protected]6b8cf1a2010-05-06 16:13:584814 }
4815 return true;
4816 case GL_RENDERBUFFER_BINDING:
4817 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104818 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354819 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204820 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4821 if (renderbuffer) {
[email protected]62e65f02013-05-29 22:28:104822 *params = renderbuffer->client_id();
[email protected]4e8a5b122010-05-08 22:00:104823 } else {
4824 *params = 0;
4825 }
[email protected]6b8cf1a2010-05-06 16:13:584826 }
4827 return true;
4828 case GL_CURRENT_PROGRAM:
4829 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104830 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114831 if (state_.current_program.get()) {
[email protected]4e8a5b122010-05-08 22:00:104832 GLuint client_id = 0;
4833 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244834 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104835 *params = client_id;
4836 } else {
4837 *params = 0;
4838 }
[email protected]6b8cf1a2010-05-06 16:13:584839 }
4840 return true;
[email protected]bf835842012-11-19 15:21:514841 case GL_VERTEX_ARRAY_BINDING_OES:
4842 *num_written = 1;
4843 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114844 if (state_.vertex_attrib_manager.get() !=
[email protected]81f20a622014-04-18 01:54:524845 state_.default_vertex_attrib_manager.get()) {
[email protected]bf835842012-11-19 15:21:514846 GLuint client_id = 0;
4847 vertex_array_manager_->GetClientId(
4848 state_.vertex_attrib_manager->service_id(), &client_id);
4849 *params = client_id;
4850 } else {
4851 *params = 0;
4852 }
4853 }
4854 return true;
[email protected]4e8a5b122010-05-08 22:00:104855 case GL_TEXTURE_BINDING_2D:
4856 *num_written = 1;
4857 if (params) {
[email protected]e259eb412012-10-13 05:47:244858 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114859 if (unit.bound_texture_2d.get()) {
[email protected]62e65f02013-05-29 22:28:104860 *params = unit.bound_texture_2d->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584861 } else {
4862 *params = 0;
4863 }
[email protected]6b8cf1a2010-05-06 16:13:584864 }
[email protected]4e8a5b122010-05-08 22:00:104865 return true;
4866 case GL_TEXTURE_BINDING_CUBE_MAP:
4867 *num_written = 1;
4868 if (params) {
[email protected]e259eb412012-10-13 05:47:244869 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114870 if (unit.bound_texture_cube_map.get()) {
[email protected]62e65f02013-05-29 22:28:104871 *params = unit.bound_texture_cube_map->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584872 } else {
4873 *params = 0;
4874 }
[email protected]6b8cf1a2010-05-06 16:13:584875 }
[email protected]4e8a5b122010-05-08 22:00:104876 return true;
[email protected]61eeb33f2011-07-26 15:30:314877 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4878 *num_written = 1;
4879 if (params) {
[email protected]e259eb412012-10-13 05:47:244880 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114881 if (unit.bound_texture_external_oes.get()) {
[email protected]62e65f02013-05-29 22:28:104882 *params = unit.bound_texture_external_oes->client_id();
[email protected]61eeb33f2011-07-26 15:30:314883 } else {
4884 *params = 0;
4885 }
4886 }
4887 return true;
[email protected]e51bdf32011-11-23 22:21:464888 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4889 *num_written = 1;
4890 if (params) {
[email protected]e259eb412012-10-13 05:47:244891 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114892 if (unit.bound_texture_rectangle_arb.get()) {
[email protected]62e65f02013-05-29 22:28:104893 *params = unit.bound_texture_rectangle_arb->client_id();
[email protected]e51bdf32011-11-23 22:21:464894 } else {
4895 *params = 0;
4896 }
4897 }
4898 return true;
[email protected]6c75c712012-06-19 15:43:174899 case GL_UNPACK_FLIP_Y_CHROMIUM:
4900 *num_written = 1;
4901 if (params) {
4902 params[0] = unpack_flip_y_;
4903 }
4904 return true;
4905 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4906 *num_written = 1;
4907 if (params) {
4908 params[0] = unpack_premultiply_alpha_;
4909 }
4910 return true;
4911 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4912 *num_written = 1;
4913 if (params) {
4914 params[0] = unpack_unpremultiply_alpha_;
4915 }
4916 return true;
[email protected]6eda6822014-04-03 23:00:504917 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
4918 *num_written = 1;
4919 if (params) {
4920 params[0] = group_->bind_generates_resource() ? 1 : 0;
4921 }
4922 return true;
[email protected]b273e432010-04-12 17:23:584923 default:
[email protected]2f143d482013-03-14 18:04:494924 if (pname >= GL_DRAW_BUFFER0_ARB &&
4925 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
4926 *num_written = 1;
4927 if (params) {
4928 Framebuffer* framebuffer =
4929 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4930 if (framebuffer) {
4931 params[0] = framebuffer->GetDrawBuffer(pname);
4932 } else { // backbuffer
4933 if (pname == GL_DRAW_BUFFER0_ARB)
4934 params[0] = group_->draw_buffer();
4935 else
4936 params[0] = GL_NONE;
4937 }
4938 }
4939 return true;
4940 }
[email protected]4e8a5b122010-05-08 22:00:104941 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534942 return false;
[email protected]b273e432010-04-12 17:23:584943 }
4944}
4945
[email protected]4e8a5b122010-05-08 22:00:104946bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4947 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264948 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534949 return true;
4950 }
[email protected]4e8a5b122010-05-08 22:00:104951 return GetHelper(pname, NULL, num_values);
4952}
4953
[email protected]7d3c36e2013-07-12 14:13:164954GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) {
4955 if (GL_MAX_SAMPLES == pname &&
4956 features().use_img_for_multisampled_render_to_texture) {
4957 return GL_MAX_SAMPLES_IMG;
4958 }
4959 return pname;
4960}
4961
[email protected]b273e432010-04-12 17:23:584962void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4963 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104964 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534965 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554966 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:264967 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:534968 GetHelper(pname, values.get(), &num_written);
4969 }
[email protected]b273e432010-04-12 17:23:584970 for (GLsizei ii = 0; ii < num_written; ++ii) {
4971 params[ii] = static_cast<GLboolean>(values[ii]);
4972 }
4973 } else {
[email protected]7d3c36e2013-07-12 14:13:164974 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584975 glGetBooleanv(pname, params);
4976 }
4977}
4978
4979void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4980 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104981 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:264982 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:534983 if (GetHelper(pname, NULL, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554984 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]f63b1232012-10-31 07:03:534985 GetHelper(pname, values.get(), &num_written);
4986 for (GLsizei ii = 0; ii < num_written; ++ii) {
4987 params[ii] = static_cast<GLfloat>(values[ii]);
4988 }
4989 } else {
[email protected]7d3c36e2013-07-12 14:13:164990 pname = AdjustGetPname(pname);
[email protected]f63b1232012-10-31 07:03:534991 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:584992 }
[email protected]b273e432010-04-12 17:23:584993 }
4994}
4995
4996void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4997 DCHECK(params);
4998 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:264999 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:535000 !GetHelper(pname, params, &num_written)) {
[email protected]7d3c36e2013-07-12 14:13:165001 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:585002 glGetIntegerv(pname, params);
5003 }
5004}
5005
[email protected]a0c3e972010-04-21 00:49:135006void GLES2DecoderImpl::DoGetProgramiv(
5007 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:425008 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
5009 if (!program) {
[email protected]a0c3e972010-04-21 00:49:135010 return;
5011 }
[email protected]df37b9932013-03-08 05:21:425012 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:135013}
5014
[email protected]17cfbe0e2013-03-07 01:26:085015void GLES2DecoderImpl::DoGetBufferParameteriv(
5016 GLenum target, GLenum pname, GLint* params) {
[email protected]0fbba3732013-07-17 15:40:135017 // Just delegate it. Some validation is actually done before this.
5018 buffer_manager()->ValidateAndDoGetBufferParameteriv(
5019 &state_, target, pname, params);
[email protected]17cfbe0e2013-03-07 01:26:085020}
5021
[email protected]258a3313f2011-10-18 20:13:575022void GLES2DecoderImpl::DoBindAttribLocation(
[email protected]df37b9932013-03-08 05:21:425023 GLuint program_id, GLuint index, const char* name) {
[email protected]258a3313f2011-10-18 20:13:575024 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:515025 LOCAL_SET_GL_ERROR(
5026 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:575027 return;
5028 }
[email protected]68dcb1f2012-04-07 00:14:565029 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:515030 LOCAL_SET_GL_ERROR(
5031 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:565032 return;
5033 }
5034 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:515035 LOCAL_SET_GL_ERROR(
5036 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:565037 return;
5038 }
[email protected]df37b9932013-03-08 05:21:425039 Program* program = GetProgramInfoNotShader(
5040 program_id, "glBindAttribLocation");
5041 if (!program) {
[email protected]258a3313f2011-10-18 20:13:575042 return;
[email protected]558847a2010-03-24 07:02:545043 }
zmo460b593e2014-10-13 23:07:455044 // At this point, the program's shaders may not be translated yet,
5045 // therefore, we may not find the hashed attribute name.
5046 // glBindAttribLocation call with original name is useless.
5047 // So instead, we should simply cache the binding, and then call
5048 // Program::ExecuteBindAttribLocationCalls() right before link.
[email protected]df37b9932013-03-08 05:21:425049 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
zmo460b593e2014-10-13 23:07:455050 // TODO(zmo): Get rid of the following glBindAttribLocation call.
[email protected]df37b9932013-03-08 05:21:425051 glBindAttribLocation(program->service_id(), index, name);
[email protected]258a3313f2011-10-18 20:13:575052}
5053
[email protected]558847a2010-03-24 07:02:545054error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
vmiuracd108592014-09-08 14:36:345055 uint32 immediate_data_size,
5056 const void* cmd_data) {
5057 const gles2::cmds::BindAttribLocationBucket& c =
5058 *static_cast<const gles2::cmds::BindAttribLocationBucket*>(cmd_data);
[email protected]6b8cf1a2010-05-06 16:13:585059 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:545060 GLuint index = static_cast<GLuint>(c.index);
5061 Bucket* bucket = GetBucket(c.name_bucket_id);
5062 if (!bucket || bucket->size() == 0) {
5063 return error::kInvalidArguments;
5064 }
5065 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:185066 if (!bucket->GetAsString(&name_str)) {
5067 return error::kInvalidArguments;
5068 }
[email protected]258a3313f2011-10-18 20:13:575069 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:545070 return error::kNoError;
5071}
5072
[email protected]2be6abf32012-06-26 00:28:335073void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:425074 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:335075 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:515076 LOCAL_SET_GL_ERROR(
5077 GL_INVALID_VALUE,
5078 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:335079 return;
5080 }
5081 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:515082 LOCAL_SET_GL_ERROR(
5083 GL_INVALID_OPERATION,
5084 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:335085 return;
5086 }
5087 if (location < 0 || static_cast<uint32>(location) >=
5088 (group_->max_fragment_uniform_vectors() +
5089 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:515090 LOCAL_SET_GL_ERROR(
5091 GL_INVALID_VALUE,
5092 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:335093 return;
5094 }
[email protected]df37b9932013-03-08 05:21:425095 Program* program = GetProgramInfoNotShader(
5096 program_id, "glBindUniformLocationCHROMIUM");
5097 if (!program) {
[email protected]2be6abf32012-06-26 00:28:335098 return;
5099 }
[email protected]df37b9932013-03-08 05:21:425100 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:515101 LOCAL_SET_GL_ERROR(
5102 GL_INVALID_VALUE,
5103 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:335104 }
5105}
5106
[email protected]2be6abf32012-06-26 00:28:335107error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
5108 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:345109 const void* cmd_data) {
5110 const gles2::cmds::BindUniformLocationCHROMIUMBucket& c =
5111 *static_cast<const gles2::cmds::BindUniformLocationCHROMIUMBucket*>(
5112 cmd_data);
[email protected]2be6abf32012-06-26 00:28:335113 GLuint program = static_cast<GLuint>(c.program);
5114 GLint location = static_cast<GLint>(c.location);
5115 Bucket* bucket = GetBucket(c.name_bucket_id);
5116 if (!bucket || bucket->size() == 0) {
5117 return error::kInvalidArguments;
5118 }
5119 std::string name_str;
5120 if (!bucket->GetAsString(&name_str)) {
5121 return error::kInvalidArguments;
5122 }
5123 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
5124 return error::kNoError;
5125}
5126
vmiuracd108592014-09-08 14:36:345127error::Error GLES2DecoderImpl::HandleDeleteShader(uint32 immediate_data_size,
5128 const void* cmd_data) {
5129 const gles2::cmds::DeleteShader& c =
5130 *static_cast<const gles2::cmds::DeleteShader*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:035131 GLuint client_id = c.shader;
5132 if (client_id) {
[email protected]df37b9932013-03-08 05:21:425133 Shader* shader = GetShader(client_id);
5134 if (shader) {
5135 if (!shader->IsDeleted()) {
5136 glDeleteShader(shader->service_id());
5137 shader_manager()->MarkAsDeleted(shader);
[email protected]ca488e12010-12-13 20:06:145138 }
[email protected]ae51d192010-04-27 00:48:035139 } else {
[email protected]ab09b612013-03-11 22:11:515140 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:035141 }
[email protected]96449d2c2009-11-25 00:01:325142 }
[email protected]f7a64ee2010-02-01 22:24:145143 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:325144}
5145
vmiuracd108592014-09-08 14:36:345146error::Error GLES2DecoderImpl::HandleDeleteProgram(uint32 immediate_data_size,
5147 const void* cmd_data) {
5148 const gles2::cmds::DeleteProgram& c =
5149 *static_cast<const gles2::cmds::DeleteProgram*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:035150 GLuint client_id = c.program;
5151 if (client_id) {
[email protected]df37b9932013-03-08 05:21:425152 Program* program = GetProgram(client_id);
5153 if (program) {
5154 if (!program->IsDeleted()) {
5155 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:145156 }
[email protected]ae51d192010-04-27 00:48:035157 } else {
[email protected]ab09b612013-03-11 22:11:515158 LOCAL_SET_GL_ERROR(
5159 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:035160 }
[email protected]96449d2c2009-11-25 00:01:325161 }
[email protected]f7a64ee2010-02-01 22:24:145162 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:325163}
5164
[email protected]a7266a92012-06-28 02:11:085165error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:445166 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:205167 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]297ca1c2011-06-20 23:08:465168 ApplyDirtyState();
boliu2e7d8a7a2014-10-16 20:35:205169 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
sievers2384f2b2014-11-18 02:10:355170 if (workarounds().gl_clear_broken) {
5171 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::ClearWorkaround",
5172 GetErrorState());
5173 if (!BoundFramebufferHasDepthAttachment())
5174 mask &= ~GL_DEPTH_BUFFER_BIT;
5175 if (!BoundFramebufferHasStencilAttachment())
5176 mask &= ~GL_STENCIL_BUFFER_BIT;
5177 clear_framebuffer_blit_->ClearFramebuffer(
5178 this, GetBoundReadFrameBufferSize(), mask, state_.color_clear_red,
5179 state_.color_clear_green, state_.color_clear_blue,
5180 state_.color_clear_alpha, state_.depth_clear, state_.stencil_clear);
5181 return error::kNoError;
5182 }
[email protected]3a03a8f2011-03-19 00:51:275183 glClear(mask);
5184 }
[email protected]a7266a92012-06-28 02:11:085185 return error::kNoError;
5186}
5187
[email protected]36cef8ce2010-03-16 07:34:455188void GLES2DecoderImpl::DoFramebufferRenderbuffer(
5189 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:035190 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:065191 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5192 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515193 LOCAL_SET_GL_ERROR(
5194 GL_INVALID_OPERATION,
5195 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455196 return;
5197 }
[email protected]ae51d192010-04-27 00:48:035198 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:275199 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:035200 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:275201 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
5202 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515203 LOCAL_SET_GL_ERROR(
5204 GL_INVALID_OPERATION,
5205 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:035206 return;
5207 }
[email protected]ee2a79c32013-03-10 03:50:275208 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:035209 }
[email protected]ab09b612013-03-11 22:11:515210 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:035211 glFramebufferRenderbufferEXT(
5212 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:515213 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:265214 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:275215 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:285216 }
[email protected]9d3b2e12013-10-02 01:04:345217 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445218 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465219 }
[email protected]81fc9d02013-03-14 23:53:325220 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:285221}
5222
[email protected]3a2e7c7b2010-08-06 01:12:285223void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465224 if (SetCapabilityState(cap, false)) {
5225 glDisable(cap);
5226 }
[email protected]3a2e7c7b2010-08-06 01:12:285227}
5228
5229void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465230 if (SetCapabilityState(cap, true)) {
5231 glEnable(cap);
5232 }
[email protected]3a2e7c7b2010-08-06 01:12:285233}
5234
[email protected]88a61bf2012-10-27 13:00:425235void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
5236 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
5237 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
5238 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:285239}
5240
[email protected]b04e24c2013-01-08 18:35:255241void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:425242 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
5243 state_.sample_coverage_invert = (invert != 0);
5244 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:285245}
5246
[email protected]0d6bfdc2011-11-02 01:32:205247// Assumes framebuffer is complete.
5248void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:065249 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:305250 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:205251 // bind this to the DRAW point, clear then bind back to READ
5252 // TODO(gman): I don't think there is any guarantee that an FBO that
5253 // is complete on the READ attachment will be complete as a DRAW
5254 // attachment.
5255 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:065256 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:305257 }
[email protected]3a2e7c7b2010-08-06 01:12:285258 GLbitfield clear_bits = 0;
[email protected]ee757922014-06-06 05:21:425259 if (framebuffer->HasUnclearedColorAttachments()) {
[email protected]297ca1c2011-06-20 23:08:465260 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:205261 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:465262 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:065263 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
5264 1.0f);
[email protected]454157e2014-05-03 02:49:455265 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285266 clear_bits |= GL_COLOR_BUFFER_BIT;
[email protected]0e58af82014-08-08 14:02:535267 if (feature_info_->feature_flags().ext_draw_buffers)
5268 framebuffer->PrepareDrawBuffersForClear();
[email protected]3a2e7c7b2010-08-06 01:12:285269 }
5270
[email protected]4d8f0dd2013-03-09 14:37:065271 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
5272 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285273 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:475274 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
5275 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]3a2e7c7b2010-08-06 01:12:285276 clear_bits |= GL_STENCIL_BUFFER_BIT;
5277 }
5278
[email protected]4d8f0dd2013-03-09 14:37:065279 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
5280 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285281 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:455282 state_.SetDeviceDepthMask(GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285283 clear_bits |= GL_DEPTH_BUFFER_BIT;
5284 }
5285
[email protected]454157e2014-05-03 02:49:455286 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]3a2e7c7b2010-08-06 01:12:285287 glClear(clear_bits);
5288
brucedawson18249152014-10-31 23:02:325289 if ((clear_bits & GL_COLOR_BUFFER_BIT) != 0 &&
[email protected]0e58af82014-08-08 14:02:535290 feature_info_->feature_flags().ext_draw_buffers)
[email protected]ee757922014-06-06 05:21:425291 framebuffer->RestoreDrawBuffersAfterClear();
5292
[email protected]968351b2011-12-20 08:26:515293 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:065294 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:285295
[email protected]c007aa02010-09-02 22:22:405296 RestoreClearState();
5297
5298 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:065299 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
5300 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:485301 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:065302 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
5303 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:485304 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:405305 }
5306}
5307
5308void GLES2DecoderImpl::RestoreClearState() {
[email protected]c986af502013-08-14 01:04:445309 framebuffer_state_.clear_state_dirty = true;
[email protected]e259eb412012-10-13 05:47:245310 glClearColor(
5311 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
5312 state_.color_clear_alpha);
5313 glClearStencil(state_.stencil_clear);
5314 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:225315 if (state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:455316 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]3a2e7c7b2010-08-06 01:12:285317 }
[email protected]36cef8ce2010-03-16 07:34:455318}
5319
5320GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:355321 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:305322 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:205323 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:455324 return GL_FRAMEBUFFER_COMPLETE;
5325 }
[email protected]0d6bfdc2011-11-02 01:32:205326 GLenum completeness = framebuffer->IsPossiblyComplete();
5327 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
5328 return completeness;
5329 }
[email protected]73276522012-11-09 05:50:205330 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:455331}
5332
5333void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:035334 GLenum target, GLenum attachment, GLenum textarget,
5335 GLuint client_texture_id, GLint level) {
[email protected]7d3c36e2013-07-12 14:13:165336 DoFramebufferTexture2DCommon(
5337 "glFramebufferTexture2D", target, attachment,
5338 textarget, client_texture_id, level, 0);
5339}
5340
5341void GLES2DecoderImpl::DoFramebufferTexture2DMultisample(
5342 GLenum target, GLenum attachment, GLenum textarget,
5343 GLuint client_texture_id, GLint level, GLsizei samples) {
[email protected]7d3c36e2013-07-12 14:13:165344 DoFramebufferTexture2DCommon(
5345 "glFramebufferTexture2DMultisample", target, attachment,
5346 textarget, client_texture_id, level, samples);
5347}
5348
5349void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
5350 const char* name, GLenum target, GLenum attachment, GLenum textarget,
5351 GLuint client_texture_id, GLint level, GLsizei samples) {
5352 if (samples > renderbuffer_manager()->max_samples()) {
5353 LOCAL_SET_GL_ERROR(
5354 GL_INVALID_VALUE,
5355 "glFramebufferTexture2DMultisample", "samples too large");
5356 return;
5357 }
[email protected]4d8f0dd2013-03-09 14:37:065358 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5359 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515360 LOCAL_SET_GL_ERROR(
5361 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165362 name, "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:455363 return;
5364 }
[email protected]ae51d192010-04-27 00:48:035365 GLuint service_id = 0;
[email protected]370eaf12013-05-18 09:19:495366 TextureRef* texture_ref = NULL;
[email protected]ae51d192010-04-27 00:48:035367 if (client_texture_id) {
[email protected]370eaf12013-05-18 09:19:495368 texture_ref = GetTexture(client_texture_id);
5369 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:515370 LOCAL_SET_GL_ERROR(
5371 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165372 name, "unknown texture_ref");
[email protected]ae51d192010-04-27 00:48:035373 return;
5374 }
[email protected]370eaf12013-05-18 09:19:495375 service_id = texture_ref->service_id();
[email protected]ae51d192010-04-27 00:48:035376 }
[email protected]0d6bfdc2011-11-02 01:32:205377
[email protected]80eb6b52012-01-19 00:14:415378 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:515379 LOCAL_SET_GL_ERROR(
5380 GL_INVALID_VALUE,
[email protected]7d3c36e2013-07-12 14:13:165381 name, "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:205382 return;
5383 }
5384
[email protected]91c94eb2013-10-22 10:32:545385 if (texture_ref)
5386 DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget);
5387
[email protected]7d3c36e2013-07-12 14:13:165388 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
5389 if (0 == samples) {
5390 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
5391 } else {
5392 if (features().use_img_for_multisampled_render_to_texture) {
5393 glFramebufferTexture2DMultisampleIMG(target, attachment, textarget,
5394 service_id, level, samples);
5395 } else {
5396 glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
5397 service_id, level, samples);
5398 }
5399 }
5400 GLenum error = LOCAL_PEEK_GL_ERROR(name);
[email protected]9edc6b22010-12-23 02:00:265401 if (error == GL_NO_ERROR) {
[email protected]7d3c36e2013-07-12 14:13:165402 framebuffer->AttachTexture(attachment, texture_ref, textarget, level,
5403 samples);
[email protected]3a2e7c7b2010-08-06 01:12:285404 }
[email protected]9d3b2e12013-10-02 01:04:345405 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445406 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465407 }
[email protected]91c94eb2013-10-22 10:32:545408
5409 if (texture_ref)
5410 DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget);
5411
[email protected]81fc9d02013-03-14 23:53:325412 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:455413}
5414
zmo84c08202014-11-23 15:28:405415void GLES2DecoderImpl::DoFramebufferTextureLayer(
5416 GLenum target, GLenum attachment, GLuint client_texture_id,
5417 GLint level, GLint layer) {
5418 // TODO(zmo): Unsafe ES3 API, missing states update.
5419 GLuint service_id = 0;
5420 TextureRef* texture_ref = NULL;
5421 if (client_texture_id) {
5422 texture_ref = GetTexture(client_texture_id);
5423 if (!texture_ref) {
5424 LOCAL_SET_GL_ERROR(
5425 GL_INVALID_OPERATION,
5426 "glFramebufferTextureLayer", "unknown texture_ref");
5427 return;
5428 }
5429 service_id = texture_ref->service_id();
5430 }
5431 glFramebufferTextureLayer(target, attachment, service_id, level, layer);
5432}
5433
[email protected]36cef8ce2010-03-16 07:34:455434void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
5435 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:065436 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5437 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515438 LOCAL_SET_GL_ERROR(
5439 GL_INVALID_OPERATION,
[email protected]caa13ed2014-02-17 11:29:205440 "glGetFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455441 return;
5442 }
[email protected]74c1ec42010-08-12 01:55:575443 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
[email protected]62e65f02013-05-29 22:28:105444 const Framebuffer::Attachment* attachment_object =
5445 framebuffer->GetAttachment(attachment);
5446 *params = attachment_object ? attachment_object->object_name() : 0;
5447 } else {
[email protected]7d3c36e2013-07-12 14:13:165448 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT &&
5449 features().use_img_for_multisampled_render_to_texture) {
5450 pname = GL_TEXTURE_SAMPLES_IMG;
5451 }
[email protected]62e65f02013-05-29 22:28:105452 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:575453 }
[email protected]36cef8ce2010-03-16 07:34:455454}
5455
5456void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
5457 GLenum target, GLenum pname, GLint* params) {
[email protected]ed9f9cd2013-02-27 21:12:355458 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205459 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5460 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515461 LOCAL_SET_GL_ERROR(
5462 GL_INVALID_OPERATION,
5463 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455464 return;
5465 }
[email protected]8875a5f2014-06-27 08:33:475466
5467 EnsureRenderbufferBound();
[email protected]3a03a8f2011-03-19 00:51:275468 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:435469 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5470 *params = renderbuffer->internal_format();
5471 break;
5472 case GL_RENDERBUFFER_WIDTH:
5473 *params = renderbuffer->width();
5474 break;
5475 case GL_RENDERBUFFER_HEIGHT:
5476 *params = renderbuffer->height();
5477 break;
[email protected]7d3c36e2013-07-12 14:13:165478 case GL_RENDERBUFFER_SAMPLES_EXT:
5479 if (features().use_img_for_multisampled_render_to_texture) {
5480 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG,
5481 params);
5482 } else {
5483 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT,
5484 params);
5485 }
[email protected]ad84a3a2012-06-08 21:42:435486 default:
5487 glGetRenderbufferParameterivEXT(target, pname, params);
5488 break;
[email protected]b71f52c2010-06-18 22:20:205489 }
[email protected]36cef8ce2010-03-16 07:34:455490}
5491
[email protected]49cabed2013-11-13 18:15:185492void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:305493 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
5494 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5495 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:445496 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]0c16343f2013-03-08 20:40:165497
[email protected]49cabed2013-11-13 18:15:185498 if (!CheckBoundFramebuffersValid("glBlitFramebufferCHROMIUM")) {
[email protected]0c16343f2013-03-08 20:40:165499 return;
5500 }
5501
[email protected]454157e2014-05-03 02:49:455502 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
boliu2e7d8a7a2014-10-16 20:35:205503 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]f42f05b2013-11-15 21:46:185504 BlitFramebufferHelper(
5505 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]454157e2014-05-03 02:49:455506 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST,
5507 state_.enable_flags.scissor_test);
[email protected]f42f05b2013-11-15 21:46:185508}
5509
[email protected]8875a5f2014-06-27 08:33:475510void GLES2DecoderImpl::EnsureRenderbufferBound() {
5511 if (!state_.bound_renderbuffer_valid) {
5512 state_.bound_renderbuffer_valid = true;
5513 glBindRenderbufferEXT(GL_RENDERBUFFER,
5514 state_.bound_renderbuffer.get()
5515 ? state_.bound_renderbuffer->service_id()
5516 : 0);
5517 }
5518}
5519
[email protected]f42f05b2013-11-15 21:46:185520void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(
5521 const FeatureInfo* feature_info,
5522 GLenum target,
5523 GLsizei samples,
5524 GLenum internal_format,
5525 GLsizei width,
5526 GLsizei height) {
5527 // TODO(sievers): This could be resolved at the GL binding level, but the
5528 // binding process is currently a bit too 'brute force'.
zmo68fcdc62014-12-05 21:51:495529 if (feature_info->gl_version_info().is_angle) {
[email protected]f42f05b2013-11-15 21:46:185530 glRenderbufferStorageMultisampleANGLE(
5531 target, samples, internal_format, width, height);
5532 } else if (feature_info->feature_flags().use_core_framebuffer_multisample) {
5533 glRenderbufferStorageMultisample(
5534 target, samples, internal_format, width, height);
5535 } else {
5536 glRenderbufferStorageMultisampleEXT(
5537 target, samples, internal_format, width, height);
5538 }
5539}
5540
5541void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0,
5542 GLint srcY0,
5543 GLint srcX1,
5544 GLint srcY1,
5545 GLint dstX0,
5546 GLint dstY0,
5547 GLint dstX1,
5548 GLint dstY1,
5549 GLbitfield mask,
5550 GLenum filter) {
5551 // TODO(sievers): This could be resolved at the GL binding level, but the
5552 // binding process is currently a bit too 'brute force'.
zmo68fcdc62014-12-05 21:51:495553 if (feature_info_->gl_version_info().is_angle) {
[email protected]5094b0f2010-11-09 19:45:245554 glBlitFramebufferANGLE(
5555 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]f42f05b2013-11-15 21:46:185556 } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) {
5557 glBlitFramebuffer(
5558 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]5094b0f2010-11-09 19:45:245559 } else {
5560 glBlitFramebufferEXT(
5561 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5562 }
[email protected]8e3e0662010-08-23 18:46:305563}
5564
[email protected]49cabed2013-11-13 18:15:185565bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample(
5566 GLsizei samples,
5567 GLenum internalformat,
5568 GLsizei width,
5569 GLsizei height) {
[email protected]84afefa2011-10-19 21:45:535570 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:515571 LOCAL_SET_GL_ERROR(
5572 GL_INVALID_VALUE,
5573 "glRenderbufferStorageMultisample", "samples too large");
[email protected]49cabed2013-11-13 18:15:185574 return false;
[email protected]84afefa2011-10-19 21:45:535575 }
5576
5577 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5578 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515579 LOCAL_SET_GL_ERROR(
5580 GL_INVALID_VALUE,
5581 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185582 return false;
[email protected]84afefa2011-10-19 21:45:535583 }
5584
[email protected]7989c9e2013-01-23 06:39:265585 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235586 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5587 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515588 LOCAL_SET_GL_ERROR(
5589 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205590 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185591 return false;
[email protected]8e3e0662010-08-23 18:46:305592 }
5593
[email protected]7989c9e2013-01-23 06:39:265594 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515595 LOCAL_SET_GL_ERROR(
5596 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205597 "glRenderbufferStorageMultisample", "out of memory");
[email protected]49cabed2013-11-13 18:15:185598 return false;
5599 }
5600
5601 return true;
5602}
5603
5604void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM(
5605 GLenum target, GLsizei samples, GLenum internalformat,
5606 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185607 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5608 if (!renderbuffer) {
5609 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5610 "glRenderbufferStorageMultisampleCHROMIUM",
5611 "no renderbuffer bound");
5612 return;
5613 }
5614
5615 if (!ValidateRenderbufferStorageMultisample(
5616 samples, internalformat, width, height)) {
[email protected]7989c9e2013-01-23 06:39:265617 return;
5618 }
5619
[email protected]8875a5f2014-06-27 08:33:475620 EnsureRenderbufferBound();
[email protected]8e102e102013-09-20 22:50:235621 GLenum impl_format =
5622 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5623 internalformat);
[email protected]49cabed2013-11-13 18:15:185624 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(
5625 "glRenderbufferStorageMultisampleCHROMIUM");
[email protected]f42f05b2013-11-15 21:46:185626 RenderbufferStorageMultisampleHelper(
Daniel Cheng3d7ce9f2014-08-26 00:26:255627 feature_info_.get(), target, samples, impl_format, width, height);
[email protected]49cabed2013-11-13 18:15:185628 GLenum error =
5629 LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM");
[email protected]9edc6b22010-12-23 02:00:265630 if (error == GL_NO_ERROR) {
[email protected]4a4c18b2013-09-13 22:50:105631
5632 if (workarounds().validate_multisample_buffer_allocation) {
5633 if (!VerifyMultisampleRenderbufferIntegrity(
5634 renderbuffer->service_id(), impl_format)) {
5635 LOCAL_SET_GL_ERROR(
5636 GL_OUT_OF_MEMORY,
[email protected]49cabed2013-11-13 18:15:185637 "glRenderbufferStorageMultisampleCHROMIUM", "out of memory");
[email protected]4a4c18b2013-09-13 22:50:105638 return;
5639 }
5640 }
5641
[email protected]968351b2011-12-20 08:26:515642 // TODO(gman): If renderbuffers tracked which framebuffers they were
5643 // attached to we could just mark those framebuffers as not complete.
5644 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205645 renderbuffer_manager()->SetInfo(
5646 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265647 }
[email protected]8e3e0662010-08-23 18:46:305648}
5649
[email protected]49cabed2013-11-13 18:15:185650// This is the handler for multisampled_render_to_texture extensions.
5651void GLES2DecoderImpl::DoRenderbufferStorageMultisampleEXT(
5652 GLenum target, GLsizei samples, GLenum internalformat,
5653 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185654 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5655 if (!renderbuffer) {
5656 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5657 "glRenderbufferStorageMultisampleEXT",
5658 "no renderbuffer bound");
5659 return;
5660 }
5661
5662 if (!ValidateRenderbufferStorageMultisample(
5663 samples, internalformat, width, height)) {
5664 return;
5665 }
5666
[email protected]8875a5f2014-06-27 08:33:475667 EnsureRenderbufferBound();
[email protected]49cabed2013-11-13 18:15:185668 GLenum impl_format =
5669 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5670 internalformat);
5671 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT");
5672 if (features().use_img_for_multisampled_render_to_texture) {
5673 glRenderbufferStorageMultisampleIMG(
5674 target, samples, impl_format, width, height);
5675 } else {
5676 glRenderbufferStorageMultisampleEXT(
5677 target, samples, impl_format, width, height);
5678 }
5679 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT");
5680 if (error == GL_NO_ERROR) {
5681 // TODO(gman): If renderbuffers tracked which framebuffers they were
5682 // attached to we could just mark those framebuffers as not complete.
5683 framebuffer_manager()->IncFramebufferStateChangeCount();
5684 renderbuffer_manager()->SetInfo(
5685 renderbuffer, samples, internalformat, width, height);
5686 }
5687}
5688
[email protected]4a4c18b2013-09-13 22:50:105689// This function validates the allocation of a multisampled renderbuffer
5690// by clearing it to a key color, blitting the contents to a texture, and
5691// reading back the color to ensure it matches the key.
5692bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity(
5693 GLuint renderbuffer, GLenum format) {
5694
5695 // Only validate color buffers.
5696 // These formats have been selected because they are very common or are known
5697 // to be used by the WebGL backbuffer. If problems are observed with other
5698 // color formats they can be added here.
5699 switch(format) {
5700 case GL_RGB:
5701 case GL_RGB8:
5702 case GL_RGBA:
5703 case GL_RGBA8:
5704 break;
5705 default:
5706 return true;
5707 }
5708
5709 GLint draw_framebuffer, read_framebuffer;
5710
5711 // Cache framebuffer and texture bindings.
5712 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer);
5713 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer);
5714
5715 if (!validation_texture_) {
5716 GLint bound_texture;
5717 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
5718
5719 // Create additional resources needed for the verification.
5720 glGenTextures(1, &validation_texture_);
5721 glGenFramebuffersEXT(1, &validation_fbo_multisample_);
5722 glGenFramebuffersEXT(1, &validation_fbo_);
5723
5724 // Texture only needs to be 1x1.
5725 glBindTexture(GL_TEXTURE_2D, validation_texture_);
5726 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB,
5727 GL_UNSIGNED_BYTE, NULL);
5728
5729 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5730 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5731 GL_TEXTURE_2D, validation_texture_, 0);
5732
5733 glBindTexture(GL_TEXTURE_2D, bound_texture);
5734 }
5735
5736 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5737 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5738 GL_RENDERBUFFER, renderbuffer);
5739
5740 // Cache current state and reset it to the values we require.
5741 GLboolean scissor_enabled = false;
5742 glGetBooleanv(GL_SCISSOR_TEST, &scissor_enabled);
5743 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455744 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]4a4c18b2013-09-13 22:50:105745
[email protected]454157e2014-05-03 02:49:455746 GLboolean color_mask[4] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
[email protected]4a4c18b2013-09-13 22:50:105747 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask);
[email protected]454157e2014-05-03 02:49:455748 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]4a4c18b2013-09-13 22:50:105749
5750 GLfloat clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5751 glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color);
5752 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
5753
5754 // Clear the buffer to the desired key color.
5755 glClear(GL_COLOR_BUFFER_BIT);
5756
5757 // Blit from the multisample buffer to a standard texture.
5758 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, validation_fbo_multisample_);
5759 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, validation_fbo_);
5760
[email protected]f42f05b2013-11-15 21:46:185761 BlitFramebufferHelper(
5762 0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
[email protected]4a4c18b2013-09-13 22:50:105763
5764 // Read a pixel from the buffer.
5765 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5766
5767 unsigned char pixel[3] = {0, 0, 0};
5768 glReadPixels(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);
5769
5770 // Detach the renderbuffer.
5771 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5772 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5773 GL_RENDERBUFFER, 0);
5774
5775 // Restore cached state.
5776 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455777 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]4a4c18b2013-09-13 22:50:105778
[email protected]454157e2014-05-03 02:49:455779 state_.SetDeviceColorMask(
5780 color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
[email protected]4a4c18b2013-09-13 22:50:105781 glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
5782 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, draw_framebuffer);
5783 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, read_framebuffer);
5784
5785 // Return true if the pixel matched the desired key color.
5786 return (pixel[0] == 0xFF &&
5787 pixel[1] == 0x00 &&
5788 pixel[2] == 0xFF);
5789}
5790
[email protected]36cef8ce2010-03-16 07:34:455791void GLES2DecoderImpl::DoRenderbufferStorage(
5792 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:355793 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205794 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5795 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515796 LOCAL_SET_GL_ERROR(
5797 GL_INVALID_OPERATION,
5798 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455799 return;
5800 }
[email protected]876f6fee2010-08-02 23:10:325801
[email protected]84afefa2011-10-19 21:45:535802 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5803 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515804 LOCAL_SET_GL_ERROR(
5805 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535806 return;
5807 }
5808
[email protected]7989c9e2013-01-23 06:39:265809 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235810 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5811 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515812 LOCAL_SET_GL_ERROR(
5813 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265814 return;
5815 }
5816
5817 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515818 LOCAL_SET_GL_ERROR(
5819 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265820 return;
[email protected]b71f52c2010-06-18 22:20:205821 }
[email protected]876f6fee2010-08-02 23:10:325822
[email protected]8875a5f2014-06-27 08:33:475823 EnsureRenderbufferBound();
[email protected]ab09b612013-03-11 22:11:515824 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:265825 glRenderbufferStorageEXT(
[email protected]8e102e102013-09-20 22:50:235826 target,
5827 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5828 internalformat),
5829 width,
5830 height);
[email protected]ab09b612013-03-11 22:11:515831 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:265832 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515833 // TODO(gman): If tetxures tracked which framebuffers they were attached to
5834 // we could just mark those framebuffers as not complete.
5835 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205836 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:265837 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265838 }
[email protected]36cef8ce2010-03-16 07:34:455839}
5840
[email protected]df37b9932013-03-08 05:21:425841void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:385842 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:425843 Program* program = GetProgramInfoNotShader(
5844 program_id, "glLinkProgram");
5845 if (!program) {
[email protected]a93bb842010-02-16 23:03:475846 return;
5847 }
[email protected]05afda12011-01-20 00:17:345848
[email protected]df37b9932013-03-08 05:21:425849 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]df37b9932013-03-08 05:21:425850 if (program->Link(shader_manager(),
[email protected]008401532014-02-07 00:10:505851 workarounds().count_all_in_varyings_packing ?
5852 Program::kCountAll : Program::kCountOnlyStaticallyUsed,
[email protected]7cd76fd2013-06-02 21:11:115853 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:425854 if (program == state_.current_program.get()) {
[email protected]b05955552014-02-06 18:41:185855 if (workarounds().use_current_program_after_successful_link)
[email protected]df37b9932013-03-08 05:21:425856 glUseProgram(program->service_id());
[email protected]b05955552014-02-06 18:41:185857 if (workarounds().clear_uniforms_before_first_program_use)
5858 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:545859 }
5860 }
vmiura8266ca72014-09-09 21:37:005861
5862 // LinkProgram can be very slow. Exit command processing to allow for
5863 // context preemption and GPU watchdog checks.
5864 ExitCommandProcessingEarly();
[email protected]07f54fcc2009-12-22 02:46:305865};
5866
zmobcb3fdd62014-12-11 00:49:035867void GLES2DecoderImpl::DoSamplerParameterfv(
5868 GLuint sampler, GLenum pname, const GLfloat* params) {
5869 DCHECK(params);
5870 glSamplerParameterf(sampler, pname, params[0]);
5871}
5872
5873void GLES2DecoderImpl::DoSamplerParameteriv(
5874 GLuint sampler, GLenum pname, const GLint* params) {
5875 DCHECK(params);
5876 glSamplerParameteri(sampler, pname, params[0]);
5877}
5878
[email protected]3916c97e2010-02-25 03:20:505879void GLES2DecoderImpl::DoTexParameterf(
5880 GLenum target, GLenum pname, GLfloat param) {
[email protected]c986af502013-08-14 01:04:445881 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5882 &state_, target);
[email protected]02965c22013-03-09 02:40:075883 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515884 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245885 return;
[email protected]07f54fcc2009-12-22 02:46:305886 }
[email protected]cbb22e42011-05-12 23:36:245887
[email protected]737191ee72014-03-09 08:02:425888 texture_manager()->SetParameterf(
5889 "glTexParameterf", GetErrorState(), texture, pname, param);
[email protected]07f54fcc2009-12-22 02:46:305890}
5891
[email protected]3916c97e2010-02-25 03:20:505892void GLES2DecoderImpl::DoTexParameteri(
5893 GLenum target, GLenum pname, GLint param) {
[email protected]c986af502013-08-14 01:04:445894 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5895 &state_, target);
[email protected]02965c22013-03-09 02:40:075896 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515897 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245898 return;
[email protected]3916c97e2010-02-25 03:20:505899 }
[email protected]cbb22e42011-05-12 23:36:245900
[email protected]737191ee72014-03-09 08:02:425901 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505902 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:505903}
5904
5905void GLES2DecoderImpl::DoTexParameterfv(
5906 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]c986af502013-08-14 01:04:445907 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5908 &state_, target);
[email protected]02965c22013-03-09 02:40:075909 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515910 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245911 return;
[email protected]3916c97e2010-02-25 03:20:505912 }
[email protected]cbb22e42011-05-12 23:36:245913
[email protected]737191ee72014-03-09 08:02:425914 texture_manager()->SetParameterf(
5915 "glTexParameterfv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505916}
5917
5918void GLES2DecoderImpl::DoTexParameteriv(
5919 GLenum target, GLenum pname, const GLint* params) {
[email protected]c986af502013-08-14 01:04:445920 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5921 &state_, target);
[email protected]02965c22013-03-09 02:40:075922 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515923 LOCAL_SET_GL_ERROR(
5924 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245925 return;
[email protected]3916c97e2010-02-25 03:20:505926 }
[email protected]cbb22e42011-05-12 23:36:245927
[email protected]737191ee72014-03-09 08:02:425928 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505929 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505930}
5931
orglofchcad5a6742014-11-07 19:51:125932bool GLES2DecoderImpl::CheckCurrentValuebuffer(const char* function_name) {
5933 if (!state_.bound_valuebuffer.get()) {
5934 // There is no valuebuffer bound
5935 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
5936 "no valuebuffer in use");
5937 return false;
5938 }
5939 return true;
5940}
5941
5942bool GLES2DecoderImpl::CheckCurrentValuebufferForSubscription(
5943 GLenum subscription,
5944 const char* function_name) {
5945 if (!CheckCurrentValuebuffer(function_name)) {
5946 return false;
5947 }
5948 if (!state_.bound_valuebuffer.get()->IsSubscribed(subscription)) {
5949 // The valuebuffer is not subscribed to the target
5950 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
5951 "valuebuffer is not subscribed");
5952 return false;
5953 }
5954 return true;
5955}
5956
5957bool GLES2DecoderImpl::CheckSubscriptionTarget(GLint location,
5958 GLenum subscription,
5959 const char* function_name) {
5960 if (!CheckCurrentProgramForUniform(location, function_name)) {
5961 return false;
5962 }
5963 GLint real_location = -1;
5964 GLint array_index = -1;
5965 const Program::UniformInfo* info =
5966 state_.current_program->GetUniformInfoByFakeLocation(
5967 location, &real_location, &array_index);
5968 if (!info) {
5969 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "unknown location");
5970 return false;
5971 }
5972 if ((ValuebufferManager::ApiTypeForSubscriptionTarget(subscription) &
5973 info->accepts_api_type) == 0) {
5974 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
5975 "wrong type for subscription");
5976 return false;
5977 }
5978 return true;
5979}
5980
[email protected]939e7362010-05-13 20:49:105981bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]7cd76fd2013-06-02 21:11:115982 if (!state_.current_program.get()) {
[email protected]ad84a3a2012-06-08 21:42:435983 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:515984 LOCAL_SET_GL_ERROR(
5985 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:435986 return false;
[email protected]939e7362010-05-13 20:49:105987 }
[email protected]e259eb412012-10-13 05:47:245988 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:515989 LOCAL_SET_GL_ERROR(
5990 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:105991 return false;
5992 }
5993 return true;
5994}
5995
5996bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
5997 GLint location, const char* function_name) {
5998 if (!CheckCurrentProgram(function_name)) {
5999 return false;
6000 }
6001 return location != -1;
6002}
6003
zmof9a81360f2014-10-17 00:06:146004bool GLES2DecoderImpl::CheckDrawingFeedbackLoops() {
6005 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
6006 if (!framebuffer)
6007 return false;
6008 const Framebuffer::Attachment* attachment =
6009 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
6010 if (!attachment)
6011 return false;
6012
6013 DCHECK(state_.current_program.get());
6014 const Program::SamplerIndices& sampler_indices =
6015 state_.current_program->sampler_indices();
6016 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
6017 const Program::UniformInfo* uniform_info =
6018 state_.current_program->GetUniformInfo(sampler_indices[ii]);
6019 DCHECK(uniform_info);
6020 if (uniform_info->type != GL_SAMPLER_2D)
6021 continue;
6022 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6023 GLuint texture_unit_index = uniform_info->texture_units[jj];
6024 if (texture_unit_index >= state_.texture_units.size())
6025 continue;
6026 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
6027 TextureRef* texture_ref =
6028 texture_unit.GetInfoForSamplerType(GL_SAMPLER_2D).get();
6029 if (attachment->IsTexture(texture_ref))
6030 return true;
6031 }
6032 }
6033 return false;
6034}
6035
orglofchcad5a6742014-11-07 19:51:126036bool GLES2DecoderImpl::CheckUniformForApiType(
6037 const Program::UniformInfo* info,
6038 const char* function_name,
6039 Program::UniformApiType api_type) {
6040 DCHECK(info);
6041 if ((api_type & info->accepts_api_type) == 0) {
6042 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6043 "wrong uniform function for type");
6044 return false;
6045 }
6046 return true;
6047}
6048
[email protected]43c2f1f2011-03-25 18:35:366049bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]9b1f1b52014-03-12 10:40:136050 GLint fake_location,
6051 const char* function_name,
6052 Program::UniformApiType api_type,
6053 GLint* real_location,
6054 GLenum* type,
6055 GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:366056 DCHECK(type);
6057 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:126058 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:526059
[email protected]1b0a6752012-02-22 03:44:126060 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:106061 return false;
6062 }
[email protected]43c2f1f2011-03-25 18:35:366063 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:356064 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:246065 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:126066 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:366067 if (!info) {
[email protected]ab09b612013-03-11 22:11:516068 LOCAL_SET_GL_ERROR(
6069 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:106070 return false;
6071 }
orglofchcad5a6742014-11-07 19:51:126072 if (!CheckUniformForApiType(info, function_name, api_type)) {
[email protected]476ccb72012-12-06 15:52:526073 return false;
6074 }
[email protected]43c2f1f2011-03-25 18:35:366075 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:516076 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436077 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:366078 return false;
6079 }
6080 *count = std::min(info->size - array_index, *count);
6081 if (*count <= 0) {
6082 return false;
6083 }
6084 *type = info->type;
[email protected]939e7362010-05-13 20:49:106085 return true;
6086}
6087
[email protected]1b0a6752012-02-22 03:44:126088void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
6089 GLenum type = 0;
6090 GLsizei count = 1;
6091 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136092 if (!PrepForSetUniformByLocation(fake_location,
6093 "glUniform1i",
6094 Program::kUniform1i,
6095 &real_location,
6096 &type,
6097 &count)) {
[email protected]3916c97e2010-02-25 03:20:506098 return;
6099 }
[email protected]e259eb412012-10-13 05:47:246100 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:026101 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:516102 LOCAL_SET_GL_ERROR(
6103 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:466104 return;
6105 }
[email protected]1b0a6752012-02-22 03:44:126106 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:506107}
6108
6109void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:126110 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:366111 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126112 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136113 if (!PrepForSetUniformByLocation(fake_location,
6114 "glUniform1iv",
6115 Program::kUniform1i,
6116 &real_location,
6117 &type,
6118 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366119 return;
6120 }
[email protected]74727112012-06-13 21:18:086121 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
6122 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:246123 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:026124 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:516125 LOCAL_SET_GL_ERROR(
6126 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:466127 return;
6128 }
[email protected]43c2f1f2011-03-25 18:35:366129 }
[email protected]1b0a6752012-02-22 03:44:126130 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:506131}
6132
[email protected]939e7362010-05-13 20:49:106133void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:126134 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366135 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126136 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136137 if (!PrepForSetUniformByLocation(fake_location,
6138 "glUniform1fv",
6139 Program::kUniform1f,
6140 &real_location,
6141 &type,
6142 &count)) {
[email protected]939e7362010-05-13 20:49:106143 return;
6144 }
6145 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:556146 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:106147 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:536148 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106149 }
[email protected]1b0a6752012-02-22 03:44:126150 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106151 } else {
[email protected]1b0a6752012-02-22 03:44:126152 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106153 }
6154}
6155
6156void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:126157 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366158 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126159 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136160 if (!PrepForSetUniformByLocation(fake_location,
6161 "glUniform2fv",
6162 Program::kUniform2f,
6163 &real_location,
6164 &type,
6165 &count)) {
[email protected]939e7362010-05-13 20:49:106166 return;
6167 }
6168 if (type == GL_BOOL_VEC2) {
6169 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:556170 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106171 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536172 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106173 }
[email protected]1b0a6752012-02-22 03:44:126174 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106175 } else {
[email protected]1b0a6752012-02-22 03:44:126176 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106177 }
6178}
6179
6180void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:126181 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366182 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126183 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136184 if (!PrepForSetUniformByLocation(fake_location,
6185 "glUniform3fv",
6186 Program::kUniform3f,
6187 &real_location,
6188 &type,
6189 &count)) {
[email protected]939e7362010-05-13 20:49:106190 return;
6191 }
6192 if (type == GL_BOOL_VEC3) {
6193 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:556194 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106195 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536196 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106197 }
[email protected]1b0a6752012-02-22 03:44:126198 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106199 } else {
[email protected]1b0a6752012-02-22 03:44:126200 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106201 }
6202}
6203
6204void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:126205 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366206 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126207 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136208 if (!PrepForSetUniformByLocation(fake_location,
6209 "glUniform4fv",
6210 Program::kUniform4f,
6211 &real_location,
6212 &type,
6213 &count)) {
[email protected]939e7362010-05-13 20:49:106214 return;
6215 }
6216 if (type == GL_BOOL_VEC4) {
6217 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:556218 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106219 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536220 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106221 }
[email protected]1b0a6752012-02-22 03:44:126222 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106223 } else {
[email protected]1b0a6752012-02-22 03:44:126224 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106225 }
6226}
6227
[email protected]43c2f1f2011-03-25 18:35:366228void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:126229 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366230 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126231 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136232 if (!PrepForSetUniformByLocation(fake_location,
6233 "glUniform2iv",
6234 Program::kUniform2i,
6235 &real_location,
6236 &type,
6237 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366238 return;
6239 }
[email protected]1b0a6752012-02-22 03:44:126240 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366241}
6242
6243void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:126244 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366245 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126246 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136247 if (!PrepForSetUniformByLocation(fake_location,
6248 "glUniform3iv",
6249 Program::kUniform3i,
6250 &real_location,
6251 &type,
6252 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366253 return;
6254 }
[email protected]1b0a6752012-02-22 03:44:126255 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366256}
6257
6258void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:126259 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366260 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126261 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136262 if (!PrepForSetUniformByLocation(fake_location,
6263 "glUniform4iv",
6264 Program::kUniform4i,
6265 &real_location,
6266 &type,
6267 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366268 return;
6269 }
[email protected]1b0a6752012-02-22 03:44:126270 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366271}
6272
6273void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:126274 GLint fake_location, GLsizei count, GLboolean transpose,
6275 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366276 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126277 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136278 if (!PrepForSetUniformByLocation(fake_location,
6279 "glUniformMatrix2fv",
6280 Program::kUniformMatrix2f,
6281 &real_location,
6282 &type,
6283 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366284 return;
6285 }
[email protected]1b0a6752012-02-22 03:44:126286 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366287}
6288
6289void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:126290 GLint fake_location, GLsizei count, GLboolean transpose,
6291 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366292 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126293 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136294 if (!PrepForSetUniformByLocation(fake_location,
6295 "glUniformMatrix3fv",
6296 Program::kUniformMatrix3f,
6297 &real_location,
6298 &type,
6299 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366300 return;
6301 }
[email protected]1b0a6752012-02-22 03:44:126302 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366303}
6304
6305void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:126306 GLint fake_location, GLsizei count, GLboolean transpose,
6307 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366308 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126309 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136310 if (!PrepForSetUniformByLocation(fake_location,
6311 "glUniformMatrix4fv",
6312 Program::kUniformMatrix4f,
6313 &real_location,
6314 &type,
6315 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366316 return;
6317 }
[email protected]1b0a6752012-02-22 03:44:126318 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366319}
6320
[email protected]df37b9932013-03-08 05:21:426321void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:036322 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:426323 Program* program = NULL;
6324 if (program_id) {
6325 program = GetProgramInfoNotShader(program_id, "glUseProgram");
6326 if (!program) {
[email protected]ae51d192010-04-27 00:48:036327 return;
6328 }
[email protected]df37b9932013-03-08 05:21:426329 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:506330 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:516331 LOCAL_SET_GL_ERROR(
6332 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:506333 return;
6334 }
[email protected]df37b9932013-03-08 05:21:426335 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:506336 }
[email protected]7cd76fd2013-06-02 21:11:116337 if (state_.current_program.get()) {
6338 program_manager()->UnuseProgram(shader_manager(),
6339 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:146340 }
[email protected]df37b9932013-03-08 05:21:426341 state_.current_program = program;
6342 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:546343 glUseProgram(service_id);
[email protected]7cd76fd2013-06-02 21:11:116344 if (state_.current_program.get()) {
6345 program_manager()->UseProgram(state_.current_program.get());
[email protected]b05955552014-02-06 18:41:186346 if (workarounds().clear_uniforms_before_first_program_use)
6347 program_manager()->ClearUniforms(program);
[email protected]ca488e12010-12-13 20:06:146348 }
[email protected]3916c97e2010-02-25 03:20:506349}
6350
[email protected]ab09b612013-03-11 22:11:516351void GLES2DecoderImpl::RenderWarning(
6352 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:326353 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016354}
6355
[email protected]ab09b612013-03-11 22:11:516356void GLES2DecoderImpl::PerformanceWarning(
6357 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:506358 logger_.LogMessage(filename, line,
6359 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016360}
6361
[email protected]91c94eb2013-10-22 10:32:546362void GLES2DecoderImpl::DoWillUseTexImageIfNeeded(
6363 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546364 // Image is already in use if texture is attached to a framebuffer.
6365 if (texture && !texture->IsAttachedToFramebuffer()) {
6366 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6367 if (image) {
6368 ScopedGLErrorSuppressor suppressor(
6369 "GLES2DecoderImpl::DoWillUseTexImageIfNeeded",
6370 GetErrorState());
6371 glBindTexture(textarget, texture->service_id());
6372 image->WillUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026373 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546374 }
6375 }
6376}
6377
6378void GLES2DecoderImpl::DoDidUseTexImageIfNeeded(
6379 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546380 // Image is still in use if texture is attached to a framebuffer.
6381 if (texture && !texture->IsAttachedToFramebuffer()) {
6382 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6383 if (image) {
6384 ScopedGLErrorSuppressor suppressor(
6385 "GLES2DecoderImpl::DoDidUseTexImageIfNeeded",
6386 GetErrorState());
6387 glBindTexture(textarget, texture->service_id());
6388 image->DidUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026389 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546390 }
6391 }
6392}
6393
[email protected]e56131d22013-07-28 16:14:116394bool GLES2DecoderImpl::PrepareTexturesForRender() {
[email protected]7cd76fd2013-06-02 21:11:116395 DCHECK(state_.current_program.get());
[email protected]91c94eb2013-10-22 10:32:546396 if (!texture_manager()->HaveUnrenderableTextures() &&
[email protected]7bffe9e12014-01-27 23:02:556397 !texture_manager()->HaveImages()) {
[email protected]e56131d22013-07-28 16:14:116398 return true;
[email protected]ef526492010-06-02 23:12:256399 }
[email protected]e2367b42013-05-31 03:37:216400
[email protected]ef526492010-06-02 23:12:256401 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:356402 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:246403 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506404 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356405 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246406 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506407 DCHECK(uniform_info);
6408 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6409 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026410 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246411 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]91c94eb2013-10-22 10:32:546412 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366413 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]91c94eb2013-10-22 10:32:546414 GLenum textarget = GetBindTargetForSamplerType(uniform_info->type);
6415 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]ef526492010-06-02 23:12:256416 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:506417 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6418 glBindTexture(
[email protected]91c94eb2013-10-22 10:32:546419 textarget,
[email protected]00f893d2010-08-24 18:55:496420 texture_manager()->black_texture_id(uniform_info->type));
dongseong.hwang7d87d722015-01-14 20:02:406421 if (!texture_ref) {
6422 LOCAL_RENDER_WARNING(
6423 std::string("there is no texture bound to the unit ") +
6424 base::IntToString(texture_unit_index));
6425 } else {
6426 LOCAL_RENDER_WARNING(
6427 std::string("texture bound to texture unit ") +
6428 base::IntToString(texture_unit_index) +
6429 " is not renderable. It maybe non-power-of-2 and have"
6430 " incompatible texture filtering.");
6431 }
[email protected]91c94eb2013-10-22 10:32:546432 continue;
[email protected]3916c97e2010-02-25 03:20:506433 }
[email protected]91c94eb2013-10-22 10:32:546434
[email protected]4e7b89202014-01-28 01:44:066435 if (textarget != GL_TEXTURE_CUBE_MAP) {
6436 Texture* texture = texture_ref->texture();
6437 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6438 if (image && !texture->IsAttachedToFramebuffer()) {
6439 ScopedGLErrorSuppressor suppressor(
6440 "GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState());
6441 textures_set = true;
6442 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6443 image->WillUseTexImage();
6444 continue;
6445 }
[email protected]91c94eb2013-10-22 10:32:546446 }
[email protected]3916c97e2010-02-25 03:20:506447 }
6448 // else: should this be an error?
6449 }
6450 }
[email protected]e56131d22013-07-28 16:14:116451 return !textures_set;
[email protected]3916c97e2010-02-25 03:20:506452}
6453
[email protected]91c94eb2013-10-22 10:32:546454void GLES2DecoderImpl::RestoreStateForTextures() {
[email protected]7cd76fd2013-06-02 21:11:116455 DCHECK(state_.current_program.get());
[email protected]ed9f9cd2013-02-27 21:12:356456 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116457 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506458 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356459 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246460 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506461 DCHECK(uniform_info);
6462 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6463 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026464 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246465 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]7cd76fd2013-06-02 21:11:116466 TextureRef* texture_ref =
[email protected]91c94eb2013-10-22 10:32:546467 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496468 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]3916c97e2010-02-25 03:20:506469 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]370eaf12013-05-18 09:19:496470 // Get the texture_ref info that was previously bound here.
[email protected]7cd76fd2013-06-02 21:11:116471 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D
6472 ? texture_unit.bound_texture_2d.get()
6473 : texture_unit.bound_texture_cube_map.get();
[email protected]3916c97e2010-02-25 03:20:506474 glBindTexture(texture_unit.bind_target,
[email protected]370eaf12013-05-18 09:19:496475 texture_ref ? texture_ref->service_id() : 0);
[email protected]91c94eb2013-10-22 10:32:546476 continue;
6477 }
6478
[email protected]4e7b89202014-01-28 01:44:066479 if (texture_unit.bind_target != GL_TEXTURE_CUBE_MAP) {
6480 Texture* texture = texture_ref->texture();
6481 gfx::GLImage* image =
6482 texture->GetLevelImage(texture_unit.bind_target, 0);
6483 if (image && !texture->IsAttachedToFramebuffer()) {
6484 ScopedGLErrorSuppressor suppressor(
6485 "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState());
6486 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6487 image->DidUseTexImage();
6488 continue;
6489 }
[email protected]3916c97e2010-02-25 03:20:506490 }
6491 }
6492 }
6493 }
6494 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:246495 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:306496}
6497
[email protected]0d6bfdc2011-11-02 01:32:206498bool GLES2DecoderImpl::ClearUnclearedTextures() {
6499 // Only check if there are some uncleared textures.
6500 if (!texture_manager()->HaveUnsafeTextures()) {
6501 return true;
6502 }
6503
6504 // 1: Check all textures we are about to render with.
[email protected]7cd76fd2013-06-02 21:11:116505 if (state_.current_program.get()) {
[email protected]ed9f9cd2013-02-27 21:12:356506 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116507 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:206508 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356509 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246510 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:206511 DCHECK(uniform_info);
6512 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6513 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026514 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246515 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:496516 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366517 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496518 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
6519 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
[email protected]0d6bfdc2011-11-02 01:32:206520 return false;
6521 }
6522 }
6523 }
6524 }
6525 }
6526 }
6527 return true;
6528}
6529
[email protected]c6aef902012-02-14 03:31:426530bool GLES2DecoderImpl::IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:106531 const char* function_name, GLuint max_vertex_accessed, bool instanced,
6532 GLsizei primcount) {
6533 DCHECK(instanced || primcount == 1);
6534
[email protected]689fa1c52010-06-09 18:35:036535 // NOTE: We specifically do not check current_program->IsValid() because
6536 // it could never be invalid since glUseProgram would have failed. While
6537 // glLinkProgram could later mark the program as invalid the previous
6538 // valid program will still function if it is still the current program.
[email protected]7cd76fd2013-06-02 21:11:116539 if (!state_.current_program.get()) {
[email protected]3916c97e2010-02-25 03:20:506540 // The program does not exist.
6541 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:516542 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:506543 return false;
6544 }
[email protected]c6aef902012-02-14 03:31:426545
zmof9a81360f2014-10-17 00:06:146546 if (CheckDrawingFeedbackLoops()) {
6547 LOCAL_SET_GL_ERROR(
6548 GL_INVALID_OPERATION, function_name,
6549 "Source and destination textures of the draw are the same.");
6550 return false;
6551 }
6552
[email protected]7cd76fd2013-06-02 21:11:116553 return state_.vertex_attrib_manager
6554 ->ValidateBindings(function_name,
6555 this,
6556 feature_info_.get(),
6557 state_.current_program.get(),
6558 max_vertex_accessed,
[email protected]ac6904d62014-07-30 12:00:106559 instanced,
[email protected]7cd76fd2013-06-02 21:11:116560 primcount);
[email protected]b1122982010-05-17 23:04:246561}
6562
[email protected]c13e1da62011-09-09 21:48:306563bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:436564 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:306565 DCHECK(simulated);
6566 *simulated = false;
6567
[email protected]876f6fee2010-08-02 23:10:326568 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:306569 return true;
[email protected]876f6fee2010-08-02 23:10:326570
[email protected]ac77603c72013-03-08 13:52:066571 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:356572 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:246573 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:246574 bool attrib_0_used =
6575 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:066576 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:306577 return true;
[email protected]b1122982010-05-17 23:04:246578 }
6579
[email protected]b1122982010-05-17 23:04:246580 // Make a buffer with a single repeated vec4 value enough to
6581 // simulate the constant value that is supposed to be here.
6582 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:306583 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:476584 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:306585
6586 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:476587 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306588 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516589 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306590 return false;
6591 }
6592
[email protected]ab09b612013-03-11 22:11:516593 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016594 "Attribute 0 is disabled. This has signficant performance penalty");
6595
[email protected]ab09b612013-03-11 22:11:516596 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:306597 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
6598
[email protected]8f0b86c2f2012-04-10 05:48:286599 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
6600 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:496601 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306602 GLenum error = glGetError();
6603 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516604 LOCAL_SET_GL_ERROR(
6605 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306606 return false;
6607 }
[email protected]fc753442011-02-04 19:49:496608 }
[email protected]af6380962012-11-29 23:24:136609
6610 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:286611 if (new_buffer ||
6612 (attrib_0_used &&
6613 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:136614 (value.v[0] != attrib_0_value_.v[0] ||
6615 value.v[1] != attrib_0_value_.v[1] ||
6616 value.v[2] != attrib_0_value_.v[2] ||
6617 value.v[3] != attrib_0_value_.v[3])))) {
6618 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:496619 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
6620 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:136621 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:246622 attrib_0_size_ = size_needed;
6623 }
6624
6625 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
6626
[email protected]ac77603c72013-03-08 13:52:066627 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:426628 glVertexAttribDivisorANGLE(0, 0);
6629
[email protected]c13e1da62011-09-09 21:48:306630 *simulated = true;
[email protected]b1122982010-05-17 23:04:246631 return true;
[email protected]b1122982010-05-17 23:04:246632}
6633
[email protected]3fc38e22014-05-30 00:13:236634void GLES2DecoderImpl::RestoreStateForAttrib(
6635 GLuint attrib_index, bool restore_array_binding) {
[email protected]ac77603c72013-03-08 13:52:066636 const VertexAttrib* attrib =
6637 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
[email protected]3fc38e22014-05-30 00:13:236638 if (restore_array_binding) {
6639 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
6640 Buffer* buffer = attrib->buffer();
6641 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
6642 glVertexAttribPointer(
6643 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
6644 attrib->gl_stride(), ptr);
6645 }
[email protected]ac77603c72013-03-08 13:52:066646 if (attrib->divisor())
6647 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:246648 glBindBuffer(
[email protected]3fc38e22014-05-30 00:13:236649 GL_ARRAY_BUFFER, state_.bound_array_buffer.get() ?
6650 state_.bound_array_buffer->service_id() : 0);
[email protected]43410e92012-04-20 17:06:286651
[email protected]265f8992012-07-20 01:03:146652 // Never touch vertex attribute 0's state (in particular, never
6653 // disable it) when running on desktop GL because it will never be
6654 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:066655 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:146656 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:066657 if (attrib->enabled()) {
6658 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146659 } else {
[email protected]ac77603c72013-03-08 13:52:066660 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146661 }
[email protected]43410e92012-04-20 17:06:286662 }
[email protected]b1122982010-05-17 23:04:246663}
[email protected]07f54fcc2009-12-22 02:46:306664
[email protected]8fbedc02010-11-18 18:43:406665bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:436666 const char* function_name,
[email protected]c6aef902012-02-14 03:31:426667 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:406668 DCHECK(simulated);
6669 *simulated = false;
6670 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
6671 return true;
6672
[email protected]e259eb412012-10-13 05:47:246673 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:406674 return true;
6675 }
6676
[email protected]ab09b612013-03-11 22:11:516677 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016678 "GL_FIXED attributes have a signficant performance penalty");
6679
[email protected]8fbedc02010-11-18 18:43:406680 // NOTE: we could be smart and try to check if a buffer is used
6681 // twice in 2 different attribs, find the overlapping parts and therefore
6682 // duplicate the minimum amount of data but this whole code path is not meant
6683 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
6684 // tests so we just add to the buffer attrib used.
6685
[email protected]c13e1da62011-09-09 21:48:306686 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:066687 const VertexAttribManager::VertexAttribList& enabled_attribs =
6688 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
6689 for (VertexAttribManager::VertexAttribList::const_iterator it =
6690 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6691 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356692 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066693 state_.current_program->GetAttribInfoByLocation(attrib->index());
6694 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
6695 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:426696 GLuint num_vertices = max_accessed + 1;
6697 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516698 LOCAL_SET_GL_ERROR(
6699 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426700 return false;
6701 }
[email protected]8fbedc02010-11-18 18:43:406702 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066703 attrib->CanAccess(max_accessed) &&
6704 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:476705 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:066706 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:476707 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:516708 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436709 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406710 return false;
6711 }
6712 }
6713 }
6714
[email protected]3aad1a32012-09-07 20:54:476715 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
6716 uint32 size_needed = 0;
6717 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306718 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516719 LOCAL_SET_GL_ERROR(
6720 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406721 return false;
6722 }
6723
[email protected]ab09b612013-03-11 22:11:516724 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:406725
6726 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:306727 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:406728 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306729 GLenum error = glGetError();
6730 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516731 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436732 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:306733 return false;
6734 }
[email protected]8fbedc02010-11-18 18:43:406735 }
6736
6737 // Copy the elements and convert to float
6738 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:066739 for (VertexAttribManager::VertexAttribList::const_iterator it =
6740 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6741 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356742 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066743 state_.current_program->GetAttribInfoByLocation(attrib->index());
6744 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:426745 max_vertex_accessed);
6746 GLuint num_vertices = max_accessed + 1;
6747 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516748 LOCAL_SET_GL_ERROR(
6749 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426750 return false;
6751 }
[email protected]8fbedc02010-11-18 18:43:406752 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066753 attrib->CanAccess(max_accessed) &&
6754 attrib->type() == GL_FIXED) {
penghuang5a3210b2014-10-29 18:24:366755 int num_elements = attrib->size() * num_vertices;
6756 const int src_size = num_elements * sizeof(int32);
6757 const int dst_size = num_elements * sizeof(float);
6758 scoped_ptr<float[]> data(new float[num_elements]);
[email protected]8fbedc02010-11-18 18:43:406759 const int32* src = reinterpret_cast<const int32 *>(
penghuang5a3210b2014-10-29 18:24:366760 attrib->buffer()->GetRange(attrib->offset(), src_size));
[email protected]8fbedc02010-11-18 18:43:406761 const int32* end = src + num_elements;
6762 float* dst = data.get();
6763 while (src != end) {
6764 *dst++ = static_cast<float>(*src++) / 65536.0f;
6765 }
penghuang5a3210b2014-10-29 18:24:366766 glBufferSubData(GL_ARRAY_BUFFER, offset, dst_size, data.get());
[email protected]8fbedc02010-11-18 18:43:406767 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066768 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:406769 reinterpret_cast<GLvoid*>(offset));
penghuang5a3210b2014-10-29 18:24:366770 offset += dst_size;
[email protected]8fbedc02010-11-18 18:43:406771 }
6772 }
6773 *simulated = true;
6774 return true;
6775}
6776
6777void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
6778 // There's no need to call glVertexAttribPointer because we shadow all the
6779 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:246780 glBindBuffer(
6781 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:116782 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
6783 : 0);
[email protected]8fbedc02010-11-18 18:43:406784}
6785
[email protected]ad84a3a2012-06-08 21:42:436786error::Error GLES2DecoderImpl::DoDrawArrays(
6787 const char* function_name,
6788 bool instanced,
6789 GLenum mode,
6790 GLint first,
6791 GLsizei count,
6792 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226793 error::Error error = WillAccessBoundFramebufferForDraw();
6794 if (error != error::kNoError)
6795 return error;
[email protected]38d139d2011-07-14 00:38:436796 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516797 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:436798 return error::kNoError;
6799 }
6800 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516801 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:436802 return error::kNoError;
6803 }
[email protected]c6aef902012-02-14 03:31:426804 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516805 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426806 return error::kNoError;
6807 }
[email protected]ad84a3a2012-06-08 21:42:436808 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:436809 return error::kNoError;
6810 }
6811 // We have to check this here because the prototype for glDrawArrays
6812 // is GLint not GLsizei.
6813 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:516814 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:436815 return error::kNoError;
6816 }
6817
[email protected]ac6904d62014-07-30 12:00:106818 if (count == 0 || primcount == 0) {
[email protected]ab09b612013-03-11 22:11:516819 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:436820 return error::kNoError;
6821 }
6822
6823 GLuint max_vertex_accessed = first + count - 1;
[email protected]ac6904d62014-07-30 12:00:106824 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206825 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516826 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206827 return error::kNoError;
6828 }
[email protected]c13e1da62011-09-09 21:48:306829 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436830 if (!SimulateAttrib0(
6831 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306832 return error::kNoError;
6833 }
[email protected]38d139d2011-07-14 00:38:436834 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436835 if (SimulateFixedAttribs(
6836 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6837 primcount)) {
[email protected]e56131d22013-07-28 16:14:116838 bool textures_set = !PrepareTexturesForRender();
[email protected]38d139d2011-07-14 00:38:436839 ApplyDirtyState();
[email protected]00c2cf92014-03-14 00:08:376840 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:426841 if (!instanced) {
6842 glDrawArrays(mode, first, count);
6843 } else {
6844 glDrawArraysInstancedANGLE(mode, first, count, primcount);
6845 }
[email protected]38d139d2011-07-14 00:38:436846 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546847 RestoreStateForTextures();
[email protected]38d139d2011-07-14 00:38:436848 }
6849 if (simulated_fixed_attribs) {
6850 RestoreStateForSimulatedFixedAttribs();
6851 }
6852 }
6853 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:236854 // We don't have to restore attrib 0 generic data at the end of this
6855 // function even if it is simulated. This is because we will simulate
6856 // it in each draw call, and attrib 0 generic data queries use cached
6857 // values instead of passing down to the underlying driver.
6858 RestoreStateForAttrib(0, false);
[email protected]38d139d2011-07-14 00:38:436859 }
[email protected]38d139d2011-07-14 00:38:436860 }
6861 return error::kNoError;
6862}
6863
vmiuracd108592014-09-08 14:36:346864error::Error GLES2DecoderImpl::HandleDrawArrays(uint32 immediate_data_size,
6865 const void* cmd_data) {
6866 const cmds::DrawArrays& c = *static_cast<const cmds::DrawArrays*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:436867 return DoDrawArrays("glDrawArrays",
6868 false,
[email protected]c6aef902012-02-14 03:31:426869 static_cast<GLenum>(c.mode),
6870 static_cast<GLint>(c.first),
6871 static_cast<GLsizei>(c.count),
[email protected]ac6904d62014-07-30 12:00:106872 1);
[email protected]c6aef902012-02-14 03:31:426873}
6874
6875error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
vmiuracd108592014-09-08 14:36:346876 uint32 immediate_data_size,
6877 const void* cmd_data) {
6878 const gles2::cmds::DrawArraysInstancedANGLE& c =
6879 *static_cast<const gles2::cmds::DrawArraysInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:156880 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516881 LOCAL_SET_GL_ERROR(
6882 GL_INVALID_OPERATION,
6883 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426884 return error::kNoError;
6885 }
[email protected]ad84a3a2012-06-08 21:42:436886 return DoDrawArrays("glDrawArraysIntancedANGLE",
6887 true,
[email protected]c6aef902012-02-14 03:31:426888 static_cast<GLenum>(c.mode),
6889 static_cast<GLint>(c.first),
6890 static_cast<GLsizei>(c.count),
6891 static_cast<GLsizei>(c.primcount));
6892}
6893
[email protected]ad84a3a2012-06-08 21:42:436894error::Error GLES2DecoderImpl::DoDrawElements(
6895 const char* function_name,
6896 bool instanced,
6897 GLenum mode,
6898 GLsizei count,
6899 GLenum type,
6900 int32 offset,
6901 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226902 error::Error error = WillAccessBoundFramebufferForDraw();
6903 if (error != error::kNoError)
6904 return error;
[email protected]e259eb412012-10-13 05:47:246905 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:516906 LOCAL_SET_GL_ERROR(
6907 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296908 return error::kNoError;
6909 }
6910
[email protected]8eee29c2010-04-29 03:38:296911 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516912 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296913 return error::kNoError;
6914 }
6915 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516916 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296917 return error::kNoError;
6918 }
[email protected]9438b012010-06-15 22:55:056919 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516920 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296921 return error::kNoError;
6922 }
[email protected]9438b012010-06-15 22:55:056923 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516924 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296925 return error::kNoError;
6926 }
[email protected]c6aef902012-02-14 03:31:426927 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516928 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426929 return error::kNoError;
6930 }
[email protected]8eee29c2010-04-29 03:38:296931
[email protected]ad84a3a2012-06-08 21:42:436932 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276933 return error::kNoError;
6934 }
6935
[email protected]ac6904d62014-07-30 12:00:106936 if (count == 0 || primcount == 0) {
[email protected]6c788fb72010-08-26 02:16:316937 return error::kNoError;
6938 }
6939
[email protected]8eee29c2010-04-29 03:38:296940 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:086941 Buffer* element_array_buffer =
6942 state_.vertex_attrib_manager->element_array_buffer();
6943
6944 if (!element_array_buffer->GetMaxValueForRange(
6945 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:516946 LOCAL_SET_GL_ERROR(
6947 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296948 return error::kNoError;
6949 }
6950
[email protected]ac6904d62014-07-30 12:00:106951 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206952 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516953 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206954 return error::kNoError;
6955 }
[email protected]c13e1da62011-09-09 21:48:306956 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436957 if (!SimulateAttrib0(
6958 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306959 return error::kNoError;
6960 }
[email protected]8fbedc02010-11-18 18:43:406961 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436962 if (SimulateFixedAttribs(
6963 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6964 primcount)) {
[email protected]e56131d22013-07-28 16:14:116965 bool textures_set = !PrepareTexturesForRender();
[email protected]297ca1c2011-06-20 23:08:466966 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:086967 // TODO(gman): Refactor to hide these details in BufferManager or
6968 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:406969 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:086970 bool used_client_side_array = false;
6971 if (element_array_buffer->IsClientSideArray()) {
6972 used_client_side_array = true;
6973 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6974 indices = element_array_buffer->GetRange(offset, 0);
6975 }
6976
[email protected]00c2cf92014-03-14 00:08:376977 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:426978 if (!instanced) {
6979 glDrawElements(mode, count, type, indices);
6980 } else {
6981 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6982 }
[email protected]17cfbe0e2013-03-07 01:26:086983
6984 if (used_client_side_array) {
6985 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
6986 element_array_buffer->service_id());
6987 }
6988
[email protected]8fbedc02010-11-18 18:43:406989 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546990 RestoreStateForTextures();
[email protected]8fbedc02010-11-18 18:43:406991 }
6992 if (simulated_fixed_attribs) {
6993 RestoreStateForSimulatedFixedAttribs();
6994 }
[email protected]ba3176a2009-12-16 18:19:466995 }
[email protected]b1122982010-05-17 23:04:246996 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:236997 // We don't have to restore attrib 0 generic data at the end of this
6998 // function even if it is simulated. This is because we will simulate
6999 // it in each draw call, and attrib 0 generic data queries use cached
7000 // values instead of passing down to the underlying driver.
7001 RestoreStateForAttrib(0, false);
[email protected]b1122982010-05-17 23:04:247002 }
[email protected]96449d2c2009-11-25 00:01:327003 }
[email protected]f7a64ee2010-02-01 22:24:147004 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327005}
7006
vmiuracd108592014-09-08 14:36:347007error::Error GLES2DecoderImpl::HandleDrawElements(uint32 immediate_data_size,
7008 const void* cmd_data) {
7009 const gles2::cmds::DrawElements& c =
7010 *static_cast<const gles2::cmds::DrawElements*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:437011 return DoDrawElements("glDrawElements",
7012 false,
[email protected]c6aef902012-02-14 03:31:427013 static_cast<GLenum>(c.mode),
7014 static_cast<GLsizei>(c.count),
7015 static_cast<GLenum>(c.type),
7016 static_cast<int32>(c.index_offset),
[email protected]ac6904d62014-07-30 12:00:107017 1);
[email protected]c6aef902012-02-14 03:31:427018}
7019
7020error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
vmiuracd108592014-09-08 14:36:347021 uint32 immediate_data_size,
7022 const void* cmd_data) {
7023 const gles2::cmds::DrawElementsInstancedANGLE& c =
7024 *static_cast<const gles2::cmds::DrawElementsInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:157025 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517026 LOCAL_SET_GL_ERROR(
7027 GL_INVALID_OPERATION,
7028 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:427029 return error::kNoError;
7030 }
[email protected]ad84a3a2012-06-08 21:42:437031 return DoDrawElements("glDrawElementsInstancedANGLE",
7032 true,
[email protected]c6aef902012-02-14 03:31:427033 static_cast<GLenum>(c.mode),
7034 static_cast<GLsizei>(c.count),
7035 static_cast<GLenum>(c.type),
7036 static_cast<int32>(c.index_offset),
7037 static_cast<GLsizei>(c.primcount));
7038}
7039
[email protected]269200b12010-11-18 22:53:067040GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:237041 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
7042 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:077043 Buffer* buffer = GetBuffer(buffer_id);
7044 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:037045 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:517046 LOCAL_SET_GL_ERROR(
7047 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:237048 } else {
[email protected]b10492f2013-03-08 05:24:077049 if (!buffer->GetMaxValueForRange(
7050 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:037051 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:517052 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:067053 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437054 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:237055 }
7056 }
7057 return max_vertex_accessed;
7058}
7059
zmo1bb3d1d2015-01-21 20:29:437060void GLES2DecoderImpl::DoShaderSource(
7061 GLuint client_id, GLsizei count, const char** data, const GLint* length) {
7062 std::string str;
7063 for (GLsizei ii = 0; ii < count; ++ii) {
dyen7b0b4ba52015-02-04 21:38:067064 if (length && length[ii] > 0)
7065 str.append(data[ii], length[ii]);
7066 else
7067 str.append(data[ii]);
zmo1bb3d1d2015-01-21 20:29:437068 }
[email protected]df37b9932013-03-08 05:21:427069 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
7070 if (!shader) {
zmo1bb3d1d2015-01-21 20:29:437071 return;
[email protected]96449d2c2009-11-25 00:01:327072 }
[email protected]45bf5152010-02-12 00:11:317073 // Note: We don't actually call glShaderSource here. We wait until
dyen7b0b4ba52015-02-04 21:38:067074 // we actually compile the shader.
zmo576a0492014-09-13 01:12:327075 shader->set_source(str);
[email protected]558847a2010-03-24 07:02:547076}
7077
zmo38923562015-01-29 20:17:397078void GLES2DecoderImpl::DoTransformFeedbackVaryings(
7079 GLuint client_program_id, GLsizei count, const char* const* varyings,
7080 GLenum buffer_mode) {
7081 Program* program = GetProgramInfoNotShader(
7082 client_program_id, "glTransformFeedbackVaryings");
7083 if (!program) {
7084 return;
7085 }
7086 glTransformFeedbackVaryings(
7087 program->service_id(), count, varyings, buffer_mode);
7088}
7089
[email protected]ae51d192010-04-27 00:48:037090void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:387091 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:427092 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
7093 if (!shader) {
[email protected]45bf5152010-02-12 00:11:317094 return;
7095 }
dyen0ff9e4402015-02-12 22:27:437096
7097 scoped_refptr<ShaderTranslatorInterface> translator;
[email protected]b1d2dcb2010-05-17 19:24:187098 if (use_shader_translator_) {
dyen0ff9e4402015-02-12 22:27:437099 translator = shader->shader_type() == GL_VERTEX_SHADER ?
7100 vertex_translator_ : fragment_translator_;
[email protected]de17df392010-04-23 21:09:417101 }
[email protected]de17df392010-04-23 21:09:417102
dyen0ff9e4402015-02-12 22:27:437103 const Shader::TranslatedShaderSourceType source_type =
7104 feature_info_->feature_flags().angle_translated_shader_source ?
7105 Shader::kANGLE : Shader::kGL;
7106 shader->RequestCompile(translator, source_type);
vmiura8266ca72014-09-09 21:37:007107}
[email protected]45bf5152010-02-12 00:11:317108
[email protected]ddd968b82010-03-02 00:44:297109void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:427110 GLuint shader_id, GLenum pname, GLint* params) {
7111 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
7112 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:297113 return;
7114 }
dyen0ff9e4402015-02-12 22:27:437115
7116 // Compile now for statuses that require it.
7117 switch (pname) {
7118 case GL_COMPILE_STATUS:
7119 case GL_INFO_LOG_LENGTH:
7120 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
7121 shader->DoCompile();
7122 break;
7123
7124 default:
7125 break;
7126 }
7127
[email protected]8f1ccdac2010-05-19 21:01:487128 switch (pname) {
7129 case GL_SHADER_SOURCE_LENGTH:
zmo576a0492014-09-13 01:12:327130 *params = shader->source().size();
7131 if (*params)
7132 ++(*params);
[email protected]8f1ccdac2010-05-19 21:01:487133 return;
7134 case GL_COMPILE_STATUS:
zmo576a0492014-09-13 01:12:327135 *params = compile_shader_always_succeeds_ ? true : shader->valid();
[email protected]e5186162010-06-14 18:54:417136 return;
[email protected]8f1ccdac2010-05-19 21:01:487137 case GL_INFO_LOG_LENGTH:
zmo576a0492014-09-13 01:12:327138 *params = shader->log_info().size();
7139 if (*params)
7140 ++(*params);
[email protected]e5186162010-06-14 18:54:417141 return;
[email protected]d6a53e42011-10-05 00:09:367142 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
zmo576a0492014-09-13 01:12:327143 *params = shader->translated_source().size();
7144 if (*params)
7145 ++(*params);
[email protected]d6a53e42011-10-05 00:09:367146 return;
[email protected]8f1ccdac2010-05-19 21:01:487147 default:
7148 break;
[email protected]ddd968b82010-03-02 00:44:297149 }
[email protected]df37b9932013-03-08 05:21:427150 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:297151}
7152
vmiuracd108592014-09-08 14:36:347153error::Error GLES2DecoderImpl::HandleGetShaderSource(uint32 immediate_data_size,
7154 const void* cmd_data) {
7155 const gles2::cmds::GetShaderSource& c =
7156 *static_cast<const gles2::cmds::GetShaderSource*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427157 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:037158 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7159 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427160 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
zmo576a0492014-09-13 01:12:327161 if (!shader || shader->source().empty()) {
[email protected]8eee29c2010-04-29 03:38:297162 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:297163 return error::kNoError;
7164 }
zmo576a0492014-09-13 01:12:327165 bucket->SetFromString(shader->source().c_str());
[email protected]ae51d192010-04-27 00:48:037166 return error::kNoError;
7167}
7168
[email protected]d6a53e42011-10-05 00:09:367169error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
7170 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:347171 const void* cmd_data) {
7172 const gles2::cmds::GetTranslatedShaderSourceANGLE& c =
7173 *static_cast<const gles2::cmds::GetTranslatedShaderSourceANGLE*>(
7174 cmd_data);
[email protected]df37b9932013-03-08 05:21:427175 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:367176 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7177 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427178 Shader* shader = GetShaderInfoNotProgram(
[email protected]caa13ed2014-02-17 11:29:207179 shader_id, "glGetTranslatedShaderSourceANGLE");
[email protected]df37b9932013-03-08 05:21:427180 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:367181 bucket->SetSize(0);
7182 return error::kNoError;
7183 }
7184
dyen0ff9e4402015-02-12 22:27:437185 // Make sure translator has been utilized in compile.
7186 shader->DoCompile();
7187
zmo576a0492014-09-13 01:12:327188 bucket->SetFromString(shader->translated_source().c_str());
[email protected]d6a53e42011-10-05 00:09:367189 return error::kNoError;
7190}
7191
[email protected]ae51d192010-04-27 00:48:037192error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
vmiuracd108592014-09-08 14:36:347193 uint32 immediate_data_size,
7194 const void* cmd_data) {
7195 const gles2::cmds::GetProgramInfoLog& c =
7196 *static_cast<const gles2::cmds::GetProgramInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427197 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:587198 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7199 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427200 Program* program = GetProgramInfoNotShader(
7201 program_id, "glGetProgramInfoLog");
7202 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:467203 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:037204 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:317205 }
[email protected]df37b9932013-03-08 05:21:427206 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:037207 return error::kNoError;
7208}
7209
7210error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
vmiuracd108592014-09-08 14:36:347211 uint32 immediate_data_size,
7212 const void* cmd_data) {
7213 const gles2::cmds::GetShaderInfoLog& c =
7214 *static_cast<const gles2::cmds::GetShaderInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427215 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:587216 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7217 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427218 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
zmo576a0492014-09-13 01:12:327219 if (!shader) {
[email protected]9a14ae612011-08-08 17:51:467220 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:037221 return error::kNoError;
7222 }
dyen0ff9e4402015-02-12 22:27:437223
7224 // Shader must be compiled in order to get the info log.
7225 shader->DoCompile();
7226
zmo576a0492014-09-13 01:12:327227 bucket->SetFromString(shader->log_info().c_str());
[email protected]ae51d192010-04-27 00:48:037228 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327229}
7230
[email protected]d058bca2012-11-26 10:27:267231bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
7232 return state_.GetEnabled(cap);
7233}
7234
[email protected]1958e0e2010-04-22 05:17:157235bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:217236 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107237 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157238}
7239
7240bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:357241 const Framebuffer* framebuffer =
7242 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107243 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157244}
7245
7246bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:367247 // IsProgram is true for programs as soon as they are created, until they are
7248 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:357249 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:107250 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157251}
7252
7253bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:357254 const Renderbuffer* renderbuffer =
7255 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107256 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157257}
7258
7259bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:367260 // IsShader is true for shaders as soon as they are created, until they
7261 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:357262 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:107263 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157264}
7265
7266bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:497267 const TextureRef* texture_ref = GetTexture(client_id);
7268 return texture_ref && texture_ref->texture()->IsValid();
[email protected]ae51d192010-04-27 00:48:037269}
7270
7271void GLES2DecoderImpl::DoAttachShader(
7272 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:427273 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587274 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:427275 if (!program) {
[email protected]ae51d192010-04-27 00:48:037276 return;
[email protected]1958e0e2010-04-22 05:17:157277 }
[email protected]df37b9932013-03-08 05:21:427278 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
7279 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037280 return;
7281 }
[email protected]df37b9932013-03-08 05:21:427282 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517283 LOCAL_SET_GL_ERROR(
7284 GL_INVALID_OPERATION,
7285 "glAttachShader",
7286 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:317287 return;
7288 }
[email protected]df37b9932013-03-08 05:21:427289 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037290}
7291
7292void GLES2DecoderImpl::DoDetachShader(
7293 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:427294 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587295 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:427296 if (!program) {
[email protected]ae51d192010-04-27 00:48:037297 return;
7298 }
[email protected]df37b9932013-03-08 05:21:427299 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
7300 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037301 return;
7302 }
[email protected]df37b9932013-03-08 05:21:427303 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517304 LOCAL_SET_GL_ERROR(
7305 GL_INVALID_OPERATION,
7306 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:227307 return;
7308 }
[email protected]df37b9932013-03-08 05:21:427309 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037310}
7311
7312void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:427313 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587314 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:427315 if (!program) {
[email protected]ae51d192010-04-27 00:48:037316 return;
7317 }
[email protected]df37b9932013-03-08 05:21:427318 program->Validate();
[email protected]1958e0e2010-04-22 05:17:157319}
7320
[email protected]ac77603c72013-03-08 13:52:067321void GLES2DecoderImpl::GetVertexAttribHelper(
7322 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:247323 switch (pname) {
7324 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:067325 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:247326 if (buffer && !buffer->IsDeleted()) {
7327 GLuint client_id;
7328 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
7329 *params = client_id;
7330 }
7331 break;
7332 }
7333 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:067334 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:247335 break;
7336 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:067337 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:247338 break;
7339 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:067340 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:247341 break;
7342 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:067343 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:247344 break;
7345 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:067346 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:247347 break;
[email protected]c6aef902012-02-14 03:31:427348 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:067349 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:427350 break;
[email protected]ac77603c72013-03-08 13:52:067351 default:
7352 NOTREACHED();
7353 break;
7354 }
7355}
7356
[email protected]4c6f5462014-03-05 00:26:567357void GLES2DecoderImpl::DoGetTexParameterfv(
7358 GLenum target, GLenum pname, GLfloat* params) {
7359 InitTextureMaxAnisotropyIfNeeded(target, pname);
7360 glGetTexParameterfv(target, pname, params);
7361}
7362
7363void GLES2DecoderImpl::DoGetTexParameteriv(
7364 GLenum target, GLenum pname, GLint* params) {
7365 InitTextureMaxAnisotropyIfNeeded(target, pname);
7366 glGetTexParameteriv(target, pname, params);
7367}
7368
7369void GLES2DecoderImpl::InitTextureMaxAnisotropyIfNeeded(
7370 GLenum target, GLenum pname) {
7371 if (!workarounds().init_texture_max_anisotropy)
7372 return;
7373 if (pname != GL_TEXTURE_MAX_ANISOTROPY_EXT ||
7374 !validators_->texture_parameter.IsValid(pname)) {
7375 return;
7376 }
7377
7378 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
7379 &state_, target);
7380 if (!texture_ref) {
7381 LOCAL_SET_GL_ERROR(
7382 GL_INVALID_OPERATION,
7383 "glGetTexParamter{fi}v", "unknown texture for target");
7384 return;
7385 }
7386 Texture* texture = texture_ref->texture();
7387 texture->InitTextureMaxAnisotropyIfNeeded(target);
7388}
7389
[email protected]ac77603c72013-03-08 13:52:067390void GLES2DecoderImpl::DoGetVertexAttribfv(
7391 GLuint index, GLenum pname, GLfloat* params) {
7392 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7393 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517394 LOCAL_SET_GL_ERROR(
7395 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067396 return;
7397 }
7398 switch (pname) {
7399 case GL_CURRENT_VERTEX_ATTRIB: {
7400 const Vec4& value = state_.attrib_values[index];
7401 params[0] = value.v[0];
7402 params[1] = value.v[1];
7403 params[2] = value.v[2];
7404 params[3] = value.v[3];
7405 break;
7406 }
7407 default: {
7408 GLint value = 0;
7409 GetVertexAttribHelper(attrib, pname, &value);
7410 *params = static_cast<GLfloat>(value);
7411 break;
7412 }
7413 }
7414}
7415
7416void GLES2DecoderImpl::DoGetVertexAttribiv(
7417 GLuint index, GLenum pname, GLint* params) {
7418 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7419 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517420 LOCAL_SET_GL_ERROR(
7421 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067422 return;
7423 }
7424 switch (pname) {
[email protected]af6380962012-11-29 23:24:137425 case GL_CURRENT_VERTEX_ATTRIB: {
7426 const Vec4& value = state_.attrib_values[index];
7427 params[0] = static_cast<GLint>(value.v[0]);
7428 params[1] = static_cast<GLint>(value.v[1]);
7429 params[2] = static_cast<GLint>(value.v[2]);
7430 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:247431 break;
[email protected]af6380962012-11-29 23:24:137432 }
[email protected]b1122982010-05-17 23:04:247433 default:
[email protected]ac77603c72013-03-08 13:52:067434 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:247435 break;
7436 }
7437}
7438
[email protected]af6380962012-11-29 23:24:137439bool GLES2DecoderImpl::SetVertexAttribValue(
7440 const char* function_name, GLuint index, const GLfloat* value) {
7441 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:517442 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:137443 return false;
[email protected]b1122982010-05-17 23:04:247444 }
[email protected]af6380962012-11-29 23:24:137445 Vec4& v = state_.attrib_values[index];
7446 v.v[0] = value[0];
7447 v.v[1] = value[1];
7448 v.v[2] = value[2];
7449 v.v[3] = value[3];
7450 return true;
7451}
7452
7453void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
7454 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
7455 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
7456 glVertexAttrib1f(index, v0);
7457 }
[email protected]b1122982010-05-17 23:04:247458}
7459
7460void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:137461 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
7462 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
7463 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:247464 }
[email protected]b1122982010-05-17 23:04:247465}
7466
7467void GLES2DecoderImpl::DoVertexAttrib3f(
7468 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:137469 GLfloat v[4] = { v0, v1, v2, 1.0f, };
7470 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
7471 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:247472 }
[email protected]b1122982010-05-17 23:04:247473}
7474
7475void GLES2DecoderImpl::DoVertexAttrib4f(
7476 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:137477 GLfloat v[4] = { v0, v1, v2, v3, };
7478 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
7479 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:247480 }
[email protected]b1122982010-05-17 23:04:247481}
7482
7483void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137484 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
7485 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
7486 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:247487 }
[email protected]b1122982010-05-17 23:04:247488}
7489
7490void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137491 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
7492 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
7493 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:247494 }
[email protected]b1122982010-05-17 23:04:247495}
7496
7497void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137498 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
7499 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
7500 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:247501 }
[email protected]b1122982010-05-17 23:04:247502}
7503
7504void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137505 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
7506 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:247507 }
[email protected]b1122982010-05-17 23:04:247508}
7509
zmo0c4b7cf2014-11-26 00:52:117510error::Error GLES2DecoderImpl::HandleVertexAttribIPointer(
7511 uint32 immediate_data_size,
7512 const void* cmd_data) {
7513 // TODO(zmo): Unsafe ES3 API, missing states update.
7514 if (!unsafe_es3_apis_enabled())
7515 return error::kUnknownCommand;
7516 const gles2::cmds::VertexAttribIPointer& c =
7517 *static_cast<const gles2::cmds::VertexAttribIPointer*>(cmd_data);
7518 GLuint indx = c.indx;
7519 GLint size = c.size;
7520 GLenum type = c.type;
7521 GLsizei stride = c.stride;
7522 GLsizei offset = c.offset;
7523 const void* ptr = reinterpret_cast<const void*>(offset);
7524 glVertexAttribIPointer(indx, size, type, stride, ptr);
7525 return error::kNoError;
7526}
7527
[email protected]f7a64ee2010-02-01 22:24:147528error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
vmiuracd108592014-09-08 14:36:347529 uint32 immediate_data_size,
7530 const void* cmd_data) {
7531 const gles2::cmds::VertexAttribPointer& c =
7532 *static_cast<const gles2::cmds::VertexAttribPointer*>(cmd_data);
[email protected]944b62f32012-09-27 02:20:467533
[email protected]7cd76fd2013-06-02 21:11:117534 if (!state_.bound_array_buffer.get() ||
7535 state_.bound_array_buffer->IsDeleted()) {
7536 if (state_.vertex_attrib_manager.get() ==
[email protected]81f20a622014-04-18 01:54:527537 state_.default_vertex_attrib_manager.get()) {
[email protected]ab09b612013-03-11 22:11:517538 LOCAL_SET_GL_ERROR(
7539 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:467540 return error::kNoError;
7541 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:517542 LOCAL_SET_GL_ERROR(
7543 GL_INVALID_VALUE,
7544 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:467545 return error::kNoError;
7546 }
[email protected]96449d2c2009-11-25 00:01:327547 }
[email protected]8eee29c2010-04-29 03:38:297548
7549 GLuint indx = c.indx;
7550 GLint size = c.size;
7551 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:327552 GLboolean normalized = static_cast<GLboolean>(c.normalized);
[email protected]8eee29c2010-04-29 03:38:297553 GLsizei stride = c.stride;
7554 GLsizei offset = c.offset;
7555 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:057556 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517557 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:297558 return error::kNoError;
7559 }
[email protected]9438b012010-06-15 22:55:057560 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:517561 LOCAL_SET_GL_ERROR(
7562 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:297563 return error::kNoError;
7564 }
7565 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517566 LOCAL_SET_GL_ERROR(
7567 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:297568 return error::kNoError;
7569 }
7570 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:517571 LOCAL_SET_GL_ERROR(
7572 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:297573 return error::kNoError;
7574 }
7575 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:517576 LOCAL_SET_GL_ERROR(
7577 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:297578 return error::kNoError;
7579 }
7580 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:517581 LOCAL_SET_GL_ERROR(
7582 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:297583 return error::kNoError;
7584 }
7585 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:317586 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]a07a23602014-08-05 11:36:127587 // component_size must be a power of two to use & as optimized modulo.
7588 DCHECK(GLES2Util::IsPOT(component_size));
7589 if (offset & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517590 LOCAL_SET_GL_ERROR(
7591 GL_INVALID_OPERATION,
7592 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:317593 return error::kNoError;
7594 }
[email protected]a07a23602014-08-05 11:36:127595 if (stride & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517596 LOCAL_SET_GL_ERROR(
7597 GL_INVALID_OPERATION,
7598 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:297599 return error::kNoError;
7600 }
[email protected]7cd76fd2013-06-02 21:11:117601 state_.vertex_attrib_manager
7602 ->SetAttribInfo(indx,
7603 state_.bound_array_buffer.get(),
7604 size,
7605 type,
7606 normalized,
7607 stride,
7608 stride != 0 ? stride : component_size * size,
7609 offset);
[email protected]8fbedc02010-11-18 18:43:407610 if (type != GL_FIXED) {
7611 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
7612 }
[email protected]f7a64ee2010-02-01 22:24:147613 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327614}
7615
[email protected]43410e92012-04-20 17:06:287616void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
7617 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:247618 state_.viewport_x = x;
7619 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:027620 state_.viewport_width = std::min(width, viewport_max_width_);
7621 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:287622 glViewport(x, y, width, height);
7623}
7624
[email protected]c6aef902012-02-14 03:31:427625error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
vmiuracd108592014-09-08 14:36:347626 uint32 immediate_data_size,
7627 const void* cmd_data) {
7628 const gles2::cmds::VertexAttribDivisorANGLE& c =
7629 *static_cast<const gles2::cmds::VertexAttribDivisorANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:157630 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517631 LOCAL_SET_GL_ERROR(
7632 GL_INVALID_OPERATION,
7633 "glVertexAttribDivisorANGLE", "function not available");
[email protected]cedee332014-05-23 07:07:537634 return error::kNoError;
[email protected]c6aef902012-02-14 03:31:427635 }
7636 GLuint index = c.index;
7637 GLuint divisor = c.divisor;
7638 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517639 LOCAL_SET_GL_ERROR(
7640 GL_INVALID_VALUE,
7641 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:427642 return error::kNoError;
7643 }
7644
[email protected]e259eb412012-10-13 05:47:247645 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:427646 index,
7647 divisor);
7648 glVertexAttribDivisorANGLE(index, divisor);
7649 return error::kNoError;
7650}
7651
[email protected]68586372013-12-11 01:27:597652template <typename pixel_data_type>
7653static void WriteAlphaData(
7654 void *pixels, uint32 row_count, uint32 channel_count,
7655 uint32 alpha_channel_index, uint32 unpadded_row_size,
7656 uint32 padded_row_size, pixel_data_type alpha_value) {
7657 DCHECK_GT(channel_count, 0U);
7658 DCHECK_EQ(unpadded_row_size % sizeof(pixel_data_type), 0U);
7659 uint32 unpadded_row_size_in_elements =
7660 unpadded_row_size / sizeof(pixel_data_type);
7661 DCHECK_EQ(padded_row_size % sizeof(pixel_data_type), 0U);
7662 uint32 padded_row_size_in_elements =
7663 padded_row_size / sizeof(pixel_data_type);
7664 pixel_data_type* dst =
7665 static_cast<pixel_data_type*>(pixels) + alpha_channel_index;
7666 for (uint32 yy = 0; yy < row_count; ++yy) {
7667 pixel_data_type* end = dst + unpadded_row_size_in_elements;
7668 for (pixel_data_type* d = dst; d < end; d += channel_count) {
7669 *d = alpha_value;
7670 }
7671 dst += padded_row_size_in_elements;
7672 }
7673}
7674
[email protected]5a36dc132013-07-23 23:17:557675void GLES2DecoderImpl::FinishReadPixels(
7676 const cmds::ReadPixels& c,
7677 GLuint buffer) {
7678 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels");
7679 GLsizei width = c.width;
7680 GLsizei height = c.height;
7681 GLenum format = c.format;
7682 GLenum type = c.type;
7683 typedef cmds::ReadPixels::Result Result;
7684 uint32 pixels_size;
7685 Result* result = NULL;
7686 if (c.result_shm_id != 0) {
7687 result = GetSharedMemoryAs<Result*>(
7688 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7689 if (!result) {
7690 if (buffer != 0) {
7691 glDeleteBuffersARB(1, &buffer);
7692 }
7693 return;
7694 }
7695 }
7696 GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427697 width, height, 1, format, type, state_.pack_alignment, &pixels_size,
[email protected]5a36dc132013-07-23 23:17:557698 NULL, NULL);
7699 void* pixels = GetSharedMemoryAs<void*>(
7700 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
7701 if (!pixels) {
7702 if (buffer != 0) {
7703 glDeleteBuffersARB(1, &buffer);
7704 }
7705 return;
7706 }
7707
7708 if (buffer != 0) {
7709 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
[email protected]e585f9e22013-08-27 02:50:337710 void* data;
7711 if (features().map_buffer_range) {
7712 data = glMapBufferRange(
7713 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT);
7714 } else {
7715 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
7716 }
miub70d78592014-11-15 03:53:477717 if (!data) {
7718 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glMapBuffer",
7719 "Unable to map memory for readback.");
7720 return;
7721 }
[email protected]5a36dc132013-07-23 23:17:557722 memcpy(pixels, data, pixels_size);
7723 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't
7724 // have to restore the state.
7725 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
7726 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7727 glDeleteBuffersARB(1, &buffer);
7728 }
7729
7730 if (result != NULL) {
7731 *result = true;
7732 }
7733
7734 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7735 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7736 if ((channels_exist & 0x0008) == 0 &&
7737 workarounds().clear_alpha_in_readpixels) {
7738 // Set the alpha to 255 because some drivers are buggy in this regard.
7739 uint32 temp_size;
7740
7741 uint32 unpadded_row_size;
7742 uint32 padded_row_size;
7743 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427744 width, 2, 1, format, type, state_.pack_alignment, &temp_size,
[email protected]5a36dc132013-07-23 23:17:557745 &unpadded_row_size, &padded_row_size)) {
7746 return;
7747 }
[email protected]68586372013-12-11 01:27:597748
7749 uint32 channel_count = 0;
7750 uint32 alpha_channel = 0;
[email protected]5a36dc132013-07-23 23:17:557751 switch (format) {
7752 case GL_RGBA:
7753 case GL_BGRA_EXT:
[email protected]68586372013-12-11 01:27:597754 channel_count = 4;
7755 alpha_channel = 3;
[email protected]5a36dc132013-07-23 23:17:557756 break;
[email protected]68586372013-12-11 01:27:597757 case GL_ALPHA:
7758 channel_count = 1;
7759 alpha_channel = 0;
7760 break;
7761 }
7762
7763 if (channel_count > 0) {
7764 switch (type) {
7765 case GL_UNSIGNED_BYTE:
7766 WriteAlphaData<uint8>(
7767 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7768 padded_row_size, 0xFF);
7769 break;
7770 case GL_FLOAT:
7771 WriteAlphaData<float>(
7772 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7773 padded_row_size, 1.0f);
7774 break;
7775 case GL_HALF_FLOAT:
7776 WriteAlphaData<uint16>(
7777 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7778 padded_row_size, 0x3C00);
7779 break;
[email protected]5a36dc132013-07-23 23:17:557780 }
[email protected]5a36dc132013-07-23 23:17:557781 }
7782 }
7783}
7784
vmiuracd108592014-09-08 14:36:347785error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size,
7786 const void* cmd_data) {
7787 const gles2::cmds::ReadPixels& c =
7788 *static_cast<const gles2::cmds::ReadPixels*>(cmd_data);
[email protected]c959a09a2014-03-27 11:44:217789 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleReadPixels");
[email protected]c76fe672013-12-13 23:30:227790 error::Error fbo_error = WillAccessBoundFramebufferForRead();
7791 if (fbo_error != error::kNoError)
7792 return fbo_error;
[email protected]612d2f82009-12-08 20:49:317793 GLint x = c.x;
7794 GLint y = c.y;
7795 GLsizei width = c.width;
7796 GLsizei height = c.height;
7797 GLenum format = c.format;
7798 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:327799 GLboolean async = static_cast<GLboolean>(c.async);
[email protected]57f223832010-03-19 01:57:567800 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:517801 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:567802 return error::kNoError;
7803 }
[email protected]ed9f9cd2013-02-27 21:12:357804 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:187805 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347806 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427807 width, height, 1, format, type, state_.pack_alignment, &pixels_size,
[email protected]e259eb412012-10-13 05:47:247808 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187809 return error::kOutOfBounds;
7810 }
[email protected]612d2f82009-12-08 20:49:317811 void* pixels = GetSharedMemoryAs<void*>(
7812 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:107813 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147814 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467815 }
[email protected]de43f082013-04-02 01:16:107816 Result* result = NULL;
7817 if (c.result_shm_id != 0) {
7818 result = GetSharedMemoryAs<Result*>(
7819 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7820 if (!result) {
7821 return error::kOutOfBounds;
7822 }
7823 }
[email protected]a51788e2010-02-24 21:54:257824
[email protected]9438b012010-06-15 22:55:057825 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517826 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:297827 return error::kNoError;
7828 }
[email protected]68586372013-12-11 01:27:597829 if (!validators_->read_pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517830 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:127831 return error::kNoError;
7832 }
[email protected]68586372013-12-11 01:27:597833 if ((format != GL_RGBA && format != GL_BGRA_EXT && format != GL_RGB &&
7834 format != GL_ALPHA) || type != GL_UNSIGNED_BYTE) {
7835 // format and type are acceptable enums but not guaranteed to be supported
7836 // for this framebuffer. Have to ask gl if they are valid.
7837 GLint preferred_format = 0;
7838 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &preferred_format);
7839 GLint preferred_type = 0;
7840 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &preferred_type);
7841 if (format != static_cast<GLenum>(preferred_format) ||
7842 type != static_cast<GLenum>(preferred_type)) {
7843 LOCAL_SET_GL_ERROR(
7844 GL_INVALID_OPERATION, "glReadPixels", "format and type incompatible "
7845 "with the current read framebuffer");
7846 return error::kNoError;
7847 }
7848 }
[email protected]57f223832010-03-19 01:57:567849 if (width == 0 || height == 0) {
7850 return error::kNoError;
7851 }
7852
[email protected]57f223832010-03-19 01:57:567853 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:307854 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:567855
[email protected]3aad1a32012-09-07 20:54:477856 int32 max_x;
7857 int32 max_y;
7858 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:517859 LOCAL_SET_GL_ERROR(
7860 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:147861 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:317862 }
[email protected]57f223832010-03-19 01:57:567863
[email protected]2ea5950d2014-07-09 18:20:347864 if (!CheckBoundReadFramebufferColorAttachment("glReadPixels")) {
7865 return error::kNoError;
7866 }
7867
[email protected]0d6bfdc2011-11-02 01:32:207868 if (!CheckBoundFramebuffersValid("glReadPixels")) {
7869 return error::kNoError;
7870 }
7871
[email protected]caa13ed2014-02-17 11:29:207872 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixels");
[email protected]a0b78dc2011-11-11 10:43:107873
7874 ScopedResolvedFrameBufferBinder binder(this, false, true);
7875
[email protected]d37231fa2010-04-09 21:16:027876 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:567877 // The user requested an out of range area. Get the results 1 line
7878 // at a time.
7879 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:347880 uint32 unpadded_row_size;
7881 uint32 padded_row_size;
7882 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427883 width, 2, 1, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:347884 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:517885 LOCAL_SET_GL_ERROR(
7886 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567887 return error::kNoError;
7888 }
7889
7890 GLint dest_x_offset = std::max(-x, 0);
7891 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:347892 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427893 dest_x_offset, 1, 1, format, type, state_.pack_alignment,
7894 &dest_row_offset, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:517895 LOCAL_SET_GL_ERROR(
7896 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567897 return error::kNoError;
7898 }
7899
7900 // Copy each row into the larger dest rect.
7901 int8* dst = static_cast<int8*>(pixels);
7902 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:027903 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:567904 GLint read_width = read_end_x - read_x;
7905 for (GLint yy = 0; yy < height; ++yy) {
7906 GLint ry = y + yy;
7907
7908 // Clear the row.
7909 memset(dst, 0, unpadded_row_size);
7910
7911 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:027912 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:567913 glReadPixels(
7914 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
7915 }
7916 dst += padded_row_size;
7917 }
7918 } else {
[email protected]5a36dc132013-07-23 23:17:557919 if (async && features().use_async_readpixels) {
miu50cef602014-11-11 01:35:417920 GLuint buffer = 0;
[email protected]5a36dc132013-07-23 23:17:557921 glGenBuffersARB(1, &buffer);
7922 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
miub70d78592014-11-15 03:53:477923 // For ANGLE client version 2, GL_STREAM_READ is not available.
zmo68fcdc62014-12-05 21:51:497924 const GLenum usage_hint = feature_info_->gl_version_info().is_angle ?
7925 GL_STATIC_DRAW : GL_STREAM_READ;
miub70d78592014-11-15 03:53:477926 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, usage_hint);
[email protected]5a36dc132013-07-23 23:17:557927 GLenum error = glGetError();
7928 if (error == GL_NO_ERROR) {
7929 glReadPixels(x, y, width, height, format, type, 0);
7930 pending_readpixel_fences_.push(linked_ptr<FenceCallback>(
7931 new FenceCallback()));
7932 WaitForReadPixels(base::Bind(
7933 &GLES2DecoderImpl::FinishReadPixels,
7934 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr
7935 <GLES2DecoderImpl>(this),
7936 c, buffer));
7937 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7938 return error::kNoError;
[email protected]77bfe7442014-03-01 02:42:597939 } else {
7940 // On error, unbind pack buffer and fall through to sync readpixels
7941 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
miu50cef602014-11-11 01:35:417942 glDeleteBuffersARB(1, &buffer);
[email protected]5a36dc132013-07-23 23:17:557943 }
7944 }
[email protected]57f223832010-03-19 01:57:567945 glReadPixels(x, y, width, height, format, type, pixels);
7946 }
[email protected]ab09b612013-03-11 22:11:517947 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:257948 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:107949 if (result != NULL) {
7950 *result = true;
7951 }
[email protected]5a36dc132013-07-23 23:17:557952 FinishReadPixels(c, 0);
[email protected]a51788e2010-02-24 21:54:257953 }
[email protected]4848b9f82011-03-10 18:37:567954
[email protected]f7a64ee2010-02-01 22:24:147955 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327956}
7957
vmiuracd108592014-09-08 14:36:347958error::Error GLES2DecoderImpl::HandlePixelStorei(uint32 immediate_data_size,
7959 const void* cmd_data) {
7960 const gles2::cmds::PixelStorei& c =
7961 *static_cast<const gles2::cmds::PixelStorei*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:197962 GLenum pname = c.pname;
7963 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:057964 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:517965 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:127966 return error::kNoError;
7967 }
[email protected]222471d2011-11-30 18:06:397968 switch (pname) {
7969 case GL_PACK_ALIGNMENT:
7970 case GL_UNPACK_ALIGNMENT:
7971 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:517972 LOCAL_SET_GL_ERROR(
[email protected]caa13ed2014-02-17 11:29:207973 GL_INVALID_VALUE, "glPixelStorei", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:397974 return error::kNoError;
7975 }
[email protected]164d6d52012-05-05 00:55:037976 break;
[email protected]0a1e9ad2012-05-04 21:13:037977 case GL_UNPACK_FLIP_Y_CHROMIUM:
7978 unpack_flip_y_ = (param != 0);
7979 return error::kNoError;
7980 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
7981 unpack_premultiply_alpha_ = (param != 0);
7982 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:177983 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
7984 unpack_unpremultiply_alpha_ = (param != 0);
7985 return error::kNoError;
[email protected]222471d2011-11-30 18:06:397986 default:
7987 break;
[email protected]b9849abf2009-11-25 19:13:197988 }
7989 glPixelStorei(pname, param);
7990 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:437991 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247992 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437993 break;
7994 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:427995 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:437996 break;
7997 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247998 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437999 break;
8000 default:
8001 // Validation should have prevented us from getting here.
8002 NOTREACHED();
8003 break;
[email protected]b9849abf2009-11-25 19:13:198004 }
[email protected]f7a64ee2010-02-01 22:24:148005 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198006}
8007
[email protected]1c75a3702011-11-11 14:15:288008error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
vmiuracd108592014-09-08 14:36:348009 uint32 immediate_data_size,
8010 const void* cmd_data) {
8011 const gles2::cmds::PostSubBufferCHROMIUM& c =
8012 *static_cast<const gles2::cmds::PostSubBufferCHROMIUM*>(cmd_data);
[email protected]43ed3a72012-05-30 22:55:388013 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]a36ed4832014-04-24 16:40:278014 {
8015 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
8016 }
[email protected]b381ee32014-03-22 02:43:438017 if (!supports_post_sub_buffer_) {
[email protected]ab09b612013-03-11 22:11:518018 LOCAL_SET_GL_ERROR(
8019 GL_INVALID_OPERATION,
8020 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:288021 return error::kNoError;
8022 }
[email protected]8f9b8dd2013-09-12 18:05:138023 bool is_tracing;
8024 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
8025 &is_tracing);
8026 if (is_tracing) {
8027 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
8028 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
8029 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
8030 is_offscreen ? offscreen_size_ : surface_->GetSize());
8031 }
[email protected]7794d512012-04-17 20:36:498032 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:288033 return error::kNoError;
[email protected]7794d512012-04-17 20:36:498034 } else {
8035 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:288036 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:498037 }
[email protected]1c75a3702011-11-11 14:15:288038}
8039
[email protected]957f0642014-04-09 16:50:018040error::Error GLES2DecoderImpl::HandleScheduleOverlayPlaneCHROMIUM(
8041 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:348042 const void* cmd_data) {
8043 const gles2::cmds::ScheduleOverlayPlaneCHROMIUM& c =
8044 *static_cast<const gles2::cmds::ScheduleOverlayPlaneCHROMIUM*>(cmd_data);
[email protected]d286ebbc2014-07-03 17:19:108045 TextureRef* ref = texture_manager()->GetTexture(c.overlay_texture_id);
8046 if (!ref) {
8047 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
8048 "glScheduleOverlayPlaneCHROMIUM",
8049 "unknown texture");
8050 return error::kNoError;
8051 }
8052 gfx::GLImage* image =
8053 ref->texture()->GetLevelImage(ref->texture()->target(), 0);
8054 if (!image) {
8055 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
8056 "glScheduleOverlayPlaneCHROMIUM",
8057 "unsupported texture format");
8058 return error::kNoError;
8059 }
8060 gfx::OverlayTransform transform = GetGFXOverlayTransform(c.plane_transform);
8061 if (transform == gfx::OVERLAY_TRANSFORM_INVALID) {
8062 LOCAL_SET_GL_ERROR(GL_INVALID_ENUM,
8063 "glScheduleOverlayPlaneCHROMIUM",
8064 "invalid transform enum");
8065 return error::kNoError;
8066 }
8067 if (!surface_->ScheduleOverlayPlane(
8068 c.plane_z_order,
8069 transform,
8070 image,
8071 gfx::Rect(c.bounds_x, c.bounds_y, c.bounds_width, c.bounds_height),
8072 gfx::RectF(c.uv_x, c.uv_y, c.uv_width, c.uv_height))) {
8073 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
8074 "glScheduleOverlayPlaneCHROMIUM",
8075 "failed to schedule overlay");
8076 }
[email protected]957f0642014-04-09 16:50:018077 return error::kNoError;
8078}
8079
[email protected]558847a2010-03-24 07:02:548080error::Error GLES2DecoderImpl::GetAttribLocationHelper(
8081 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
8082 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:578083 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:518084 LOCAL_SET_GL_ERROR(
8085 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:578086 return error::kNoError;
8087 }
[email protected]df37b9932013-03-08 05:21:428088 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:588089 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:428090 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:148091 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198092 }
[email protected]df37b9932013-03-08 05:21:428093 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:518094 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438095 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:258096 return error::kNoError;
8097 }
[email protected]b9849abf2009-11-25 19:13:198098 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:548099 location_shm_id, location_shm_offset, sizeof(GLint));
8100 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:148101 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198102 }
[email protected]558847a2010-03-24 07:02:548103 // Require the client to init this incase the context is lost and we are no
8104 // longer executing commands.
8105 if (*location != -1) {
8106 return error::kGenericError;
8107 }
[email protected]df37b9932013-03-08 05:21:428108 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:148109 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198110}
8111
[email protected]558847a2010-03-24 07:02:548112error::Error GLES2DecoderImpl::HandleGetAttribLocation(
vmiuracd108592014-09-08 14:36:348113 uint32 immediate_data_size,
8114 const void* cmd_data) {
8115 const gles2::cmds::GetAttribLocation& c =
8116 *static_cast<const gles2::cmds::GetAttribLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:548117 Bucket* bucket = GetBucket(c.name_bucket_id);
8118 if (!bucket) {
8119 return error::kInvalidArguments;
8120 }
8121 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:188122 if (!bucket->GetAsString(&name_str)) {
8123 return error::kInvalidArguments;
8124 }
[email protected]558847a2010-03-24 07:02:548125 return GetAttribLocationHelper(
8126 c.program, c.location_shm_id, c.location_shm_offset, name_str);
8127}
8128
8129error::Error GLES2DecoderImpl::GetUniformLocationHelper(
8130 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
8131 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:578132 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:518133 LOCAL_SET_GL_ERROR(
8134 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:578135 return error::kNoError;
8136 }
[email protected]df37b9932013-03-08 05:21:428137 Program* program = GetProgramInfoNotShader(
[email protected]caa13ed2014-02-17 11:29:208138 client_id, "glGetUniformLocation");
[email protected]df37b9932013-03-08 05:21:428139 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:148140 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198141 }
[email protected]df37b9932013-03-08 05:21:428142 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:518143 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438144 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:258145 return error::kNoError;
8146 }
[email protected]b9849abf2009-11-25 19:13:198147 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:548148 location_shm_id, location_shm_offset, sizeof(GLint));
8149 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:148150 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198151 }
[email protected]558847a2010-03-24 07:02:548152 // Require the client to init this incase the context is lost an we are no
8153 // longer executing commands.
8154 if (*location != -1) {
8155 return error::kGenericError;
8156 }
[email protected]df37b9932013-03-08 05:21:428157 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:148158 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198159}
8160
[email protected]f7a64ee2010-02-01 22:24:148161error::Error GLES2DecoderImpl::HandleGetUniformLocation(
vmiuracd108592014-09-08 14:36:348162 uint32 immediate_data_size,
8163 const void* cmd_data) {
8164 const gles2::cmds::GetUniformLocation& c =
8165 *static_cast<const gles2::cmds::GetUniformLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:548166 Bucket* bucket = GetBucket(c.name_bucket_id);
8167 if (!bucket) {
8168 return error::kInvalidArguments;
8169 }
8170 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:188171 if (!bucket->GetAsString(&name_str)) {
8172 return error::kInvalidArguments;
8173 }
[email protected]558847a2010-03-24 07:02:548174 return GetUniformLocationHelper(
8175 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:198176}
8177
zmo155435a42015-02-13 05:06:538178error::Error GLES2DecoderImpl::HandleGetUniformIndices(
8179 uint32 immediate_data_size,
8180 const void* cmd_data) {
8181 if (!unsafe_es3_apis_enabled())
8182 return error::kUnknownCommand;
8183 const gles2::cmds::GetUniformIndices& c =
8184 *static_cast<const gles2::cmds::GetUniformIndices*>(cmd_data);
8185 Bucket* bucket = GetBucket(c.names_bucket_id);
8186 if (!bucket) {
8187 return error::kInvalidArguments;
8188 }
8189 GLsizei count = 0;
8190 std::vector<char*> names;
8191 std::vector<GLint> len;
8192 if (!bucket->GetAsStrings(&count, &names, &len) || count <= 0) {
8193 return error::kInvalidArguments;
8194 }
8195 typedef cmds::GetUniformIndices::Result Result;
8196 Result* result = GetSharedMemoryAs<Result*>(
8197 c.indices_shm_id, c.indices_shm_offset,
8198 Result::ComputeSize(static_cast<size_t>(count)));
8199 GLuint* indices = result ? result->GetData() : NULL;
8200 if (indices == NULL) {
8201 return error::kOutOfBounds;
8202 }
8203 // Check that the client initialized the result.
8204 if (result->size != 0) {
8205 return error::kInvalidArguments;
8206 }
8207 Program* program = GetProgramInfoNotShader(c.program, "glGetUniformIndices");
8208 if (!program) {
8209 return error::kNoError;
8210 }
8211 GLuint service_id = program->service_id();
8212 GLint link_status = GL_FALSE;
8213 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
8214 if (link_status != GL_TRUE) {
8215 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
8216 "glGetUniformIndices", "program not linked");
8217 return error::kNoError;
8218 }
8219 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetUniformIndices");
8220 glGetUniformIndices(service_id, count, &names[0], indices);
8221 GLenum error = glGetError();
8222 if (error == GL_NO_ERROR) {
8223 result->SetNumResults(count);
8224 } else {
8225 LOCAL_SET_GL_ERROR(error, "GetUniformIndices", "");
8226 }
8227 return error::kNoError;
8228}
8229
zmo5393fb52015-01-27 01:50:488230error::Error GLES2DecoderImpl::GetFragDataLocationHelper(
8231 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
8232 const std::string& name_str) {
8233 GLint* location = GetSharedMemoryAs<GLint*>(
8234 location_shm_id, location_shm_offset, sizeof(GLint));
8235 if (!location) {
8236 return error::kOutOfBounds;
8237 }
8238 // Require the client to init this incase the context is lost and we are no
8239 // longer executing commands.
8240 if (*location != -1) {
8241 return error::kGenericError;
8242 }
8243 Program* program = GetProgramInfoNotShader(
8244 client_id, "glGetFragDataLocation");
8245 if (!program) {
8246 return error::kNoError;
8247 }
8248 *location = glGetFragDataLocation(program->service_id(), name_str.c_str());
8249 return error::kNoError;
8250}
8251
8252error::Error GLES2DecoderImpl::HandleGetFragDataLocation(
8253 uint32 immediate_data_size,
8254 const void* cmd_data) {
8255 if (!unsafe_es3_apis_enabled())
8256 return error::kUnknownCommand;
8257 const gles2::cmds::GetFragDataLocation& c =
8258 *static_cast<const gles2::cmds::GetFragDataLocation*>(cmd_data);
8259 Bucket* bucket = GetBucket(c.name_bucket_id);
8260 if (!bucket) {
8261 return error::kInvalidArguments;
8262 }
8263 std::string name_str;
8264 if (!bucket->GetAsString(&name_str)) {
8265 return error::kInvalidArguments;
8266 }
8267 return GetFragDataLocationHelper(
8268 c.program, c.location_shm_id, c.location_shm_offset, name_str);
8269}
8270
zmo4a16ff992015-02-05 22:18:418271error::Error GLES2DecoderImpl::HandleGetUniformBlockIndex(
8272 uint32 immediate_data_size, const void* cmd_data) {
8273 if (!unsafe_es3_apis_enabled())
8274 return error::kUnknownCommand;
8275 const gles2::cmds::GetUniformBlockIndex& c =
8276 *static_cast<const gles2::cmds::GetUniformBlockIndex*>(cmd_data);
8277 Bucket* bucket = GetBucket(c.name_bucket_id);
8278 if (!bucket) {
8279 return error::kInvalidArguments;
8280 }
8281 std::string name_str;
8282 if (!bucket->GetAsString(&name_str)) {
8283 return error::kInvalidArguments;
8284 }
8285 GLuint* index = GetSharedMemoryAs<GLuint*>(
8286 c.index_shm_id, c.index_shm_offset, sizeof(GLuint));
8287 if (!index) {
8288 return error::kOutOfBounds;
8289 }
8290 // Require the client to init this in case the context is lost and we are no
8291 // longer executing commands.
8292 if (*index != GL_INVALID_INDEX) {
8293 return error::kGenericError;
8294 }
8295 Program* program = GetProgramInfoNotShader(
8296 c.program, "glGetUniformBlockIndex");
8297 if (!program) {
8298 return error::kNoError;
8299 }
8300 *index = glGetUniformBlockIndex(program->service_id(), name_str.c_str());
8301 return error::kNoError;
8302}
8303
vmiuracd108592014-09-08 14:36:348304error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size,
8305 const void* cmd_data) {
8306 const gles2::cmds::GetString& c =
8307 *static_cast<const gles2::cmds::GetString*>(cmd_data);
[email protected]ddd968b82010-03-02 00:44:298308 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:058309 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:518310 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:298311 return error::kNoError;
8312 }
[email protected]959e9072013-09-20 16:58:388313 const char* str = reinterpret_cast<const char*>(glGetString(name));
[email protected]f0d74742011-10-03 16:31:048314 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:158315 switch (name) {
8316 case GL_VERSION:
8317 str = "OpenGL ES 2.0 Chromium";
8318 break;
8319 case GL_SHADING_LANGUAGE_VERSION:
8320 str = "OpenGL ES GLSL ES 1.0 Chromium";
8321 break;
[email protected]32939602012-05-09 06:25:168322 case GL_RENDERER:
[email protected]32939602012-05-09 06:25:168323 case GL_VENDOR:
[email protected]959e9072013-09-20 16:58:388324 // Return the unmasked VENDOR/RENDERER string for WebGL contexts.
8325 // They are used by WEBGL_debug_renderer_info.
8326 if (!force_webgl_glsl_validation_)
8327 str = "Chromium";
[email protected]32939602012-05-09 06:25:168328 break;
[email protected]1958e0e2010-04-22 05:17:158329 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:048330 {
[email protected]70dc60932013-06-04 03:33:498331 // For WebGL contexts, strip out the OES derivatives and
8332 // EXT frag depth extensions if they have not been enabled.
8333 if (force_webgl_glsl_validation_) {
[email protected]f0d74742011-10-03 16:31:048334 extensions = feature_info_->extensions();
[email protected]70dc60932013-06-04 03:33:498335 if (!derivatives_explicitly_enabled_) {
8336 size_t offset = extensions.find(kOESDerivativeExtension);
8337 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098338 extensions.replace(offset, arraysize(kOESDerivativeExtension),
[email protected]70dc60932013-06-04 03:33:498339 std::string());
8340 }
8341 }
8342 if (!frag_depth_explicitly_enabled_) {
8343 size_t offset = extensions.find(kEXTFragDepthExtension);
8344 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098345 extensions.replace(offset, arraysize(kEXTFragDepthExtension),
[email protected]70dc60932013-06-04 03:33:498346 std::string());
8347 }
[email protected]f0d74742011-10-03 16:31:048348 }
[email protected]aff39ac82013-06-08 04:53:138349 if (!draw_buffers_explicitly_enabled_) {
8350 size_t offset = extensions.find(kEXTDrawBuffersExtension);
8351 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098352 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension),
[email protected]aff39ac82013-06-08 04:53:138353 std::string());
8354 }
8355 }
[email protected]93c2fd82014-04-16 02:46:068356 if (!shader_texture_lod_explicitly_enabled_) {
8357 size_t offset = extensions.find(kEXTShaderTextureLodExtension);
8358 if (std::string::npos != offset) {
8359 extensions.replace(offset,
8360 arraysize(kEXTShaderTextureLodExtension),
8361 std::string());
8362 }
8363 }
[email protected]f0d74742011-10-03 16:31:048364 } else {
[email protected]6f5fac9d12012-06-26 21:02:458365 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:048366 }
[email protected]b381ee32014-03-22 02:43:438367 if (supports_post_sub_buffer_)
8368 extensions += " GL_CHROMIUM_post_sub_buffer";
[email protected]6f5fac9d12012-06-26 21:02:458369 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:048370 }
[email protected]1958e0e2010-04-22 05:17:158371 break;
8372 default:
[email protected]1958e0e2010-04-22 05:17:158373 break;
8374 }
[email protected]ddd968b82010-03-02 00:44:298375 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:158376 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:298377 return error::kNoError;
8378}
8379
vmiuracd108592014-09-08 14:36:348380error::Error GLES2DecoderImpl::HandleBufferData(uint32 immediate_data_size,
8381 const void* cmd_data) {
8382 const gles2::cmds::BufferData& c =
8383 *static_cast<const gles2::cmds::BufferData*>(cmd_data);
[email protected]0c86dbf2010-03-05 08:14:118384 GLenum target = static_cast<GLenum>(c.target);
8385 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
8386 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8387 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8388 GLenum usage = static_cast<GLenum>(c.usage);
8389 const void* data = NULL;
8390 if (data_shm_id != 0 || data_shm_offset != 0) {
8391 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
8392 if (!data) {
8393 return error::kOutOfBounds;
8394 }
8395 }
[email protected]0fbba3732013-07-17 15:40:138396 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:148397 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198398}
8399
[email protected]0c86dbf2010-03-05 08:14:118400void GLES2DecoderImpl::DoBufferSubData(
8401 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]0fbba3732013-07-17 15:40:138402 // Just delegate it. Some validation is actually done before this.
8403 buffer_manager()->ValidateAndDoBufferSubData(
8404 &state_, target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:198405}
8406
[email protected]0d6bfdc2011-11-02 01:32:208407bool GLES2DecoderImpl::ClearLevel(
8408 unsigned service_id,
8409 unsigned bind_target,
8410 unsigned target,
8411 int level,
[email protected]d8e6c9242014-02-20 16:56:258412 unsigned internal_format,
[email protected]0d6bfdc2011-11-02 01:32:208413 unsigned format,
8414 unsigned type,
8415 int width,
[email protected]4502e6492011-12-14 19:39:158416 int height,
8417 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:008418 uint32 channels = GLES2Util::GetChannelsForFormat(format);
[email protected]345ba902013-11-14 21:39:008419 if (feature_info_->feature_flags().angle_depth_texture &&
8420 (channels & GLES2Util::kDepth) != 0) {
[email protected]81375742012-06-08 00:04:008421 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
8422 // on depth formats.
8423 GLuint fb = 0;
8424 glGenFramebuffersEXT(1, &fb);
8425 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
8426
8427 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
8428 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
8429 GL_DEPTH_ATTACHMENT;
8430
8431 glFramebufferTexture2DEXT(
8432 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
8433 // ANGLE promises a depth only attachment ok.
8434 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
8435 GL_FRAMEBUFFER_COMPLETE) {
8436 return false;
8437 }
8438 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:478439 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
8440 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]81375742012-06-08 00:04:008441 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:458442 state_.SetDeviceDepthMask(GL_TRUE);
8443 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]81375742012-06-08 00:04:008444 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
8445
8446 RestoreClearState();
8447
8448 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:358449 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:008450 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
8451 GLuint fb_service_id =
8452 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
8453 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
8454 return true;
8455 }
8456
[email protected]45d15a62012-04-18 14:33:178457 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
8458
8459 uint32 size;
8460 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:348461 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428462 width, height, 1, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:178463 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:208464 return false;
8465 }
[email protected]45d15a62012-04-18 14:33:178466
[email protected]a5d3dad2012-05-26 04:34:448467 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
8468
[email protected]45d15a62012-04-18 14:33:178469 int tile_height;
8470
8471 if (size > kMaxZeroSize) {
8472 if (kMaxZeroSize < padded_row_size) {
8473 // That'd be an awfully large texture.
8474 return false;
8475 }
8476 // We should never have a large total size with a zero row size.
8477 DCHECK_GT(padded_row_size, 0U);
8478 tile_height = kMaxZeroSize / padded_row_size;
8479 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428480 width, tile_height, 1, format, type, state_.unpack_alignment, &size,
[email protected]e259eb412012-10-13 05:47:248481 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:178482 return false;
8483 }
[email protected]4502e6492011-12-14 19:39:158484 } else {
[email protected]45d15a62012-04-18 14:33:178485 tile_height = height;
8486 }
8487
8488 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:558489 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:178490 memset(zero.get(), 0, size);
8491 glBindTexture(bind_target, service_id);
8492
8493 GLint y = 0;
8494 while (y < height) {
8495 GLint h = y + tile_height > height ? height - y : tile_height;
8496 if (is_texture_immutable || h != height) {
8497 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
8498 } else {
[email protected]8f1d2aa2013-05-10 23:45:388499 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:258500 target, level, internal_format, width, h, 0, format, type,
8501 zero.get());
[email protected]45d15a62012-04-18 14:33:178502 }
8503 y += tile_height;
[email protected]4502e6492011-12-14 19:39:158504 }
[email protected]c986af502013-08-14 01:04:448505 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
8506 &state_, bind_target);
[email protected]02965c22013-03-09 02:40:078507 glBindTexture(bind_target, texture ? texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:208508 return true;
8509}
8510
[email protected]ad84a3a2012-06-08 21:42:438511namespace {
8512
8513const int kS3TCBlockWidth = 4;
8514const int kS3TCBlockHeight = 4;
8515const int kS3TCDXT1BlockSize = 8;
8516const int kS3TCDXT3AndDXT5BlockSize = 16;
8517
8518bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:518519 return (size == 1) ||
8520 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:438521}
8522
[email protected]8aec81ec2014-04-29 01:04:518523bool IsValidPVRTCSize(GLint level, GLsizei size) {
[email protected]a07a23602014-08-05 11:36:128524 return GLES2Util::IsPOT(size);
[email protected]8aec81ec2014-04-29 01:04:518525}
8526
[email protected]ad84a3a2012-06-08 21:42:438527} // anonymous namespace.
8528
8529bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
8530 const char* function_name,
8531 GLsizei width, GLsizei height, GLenum format, size_t size) {
8532 unsigned int bytes_required = 0;
8533
8534 switch (format) {
[email protected]8aec81ec2014-04-29 01:04:518535 case GL_ATC_RGB_AMD:
[email protected]ad84a3a2012-06-08 21:42:438536 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
[email protected]8aec81ec2014-04-29 01:04:518537 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8538 case GL_ETC1_RGB8_OES: {
[email protected]ad84a3a2012-06-08 21:42:438539 int num_blocks_across =
8540 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8541 int num_blocks_down =
8542 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8543 int num_blocks = num_blocks_across * num_blocks_down;
8544 bytes_required = num_blocks * kS3TCDXT1BlockSize;
8545 break;
8546 }
[email protected]8aec81ec2014-04-29 01:04:518547 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8548 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
[email protected]ad84a3a2012-06-08 21:42:438549 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8550 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8551 int num_blocks_across =
8552 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8553 int num_blocks_down =
8554 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8555 int num_blocks = num_blocks_across * num_blocks_down;
8556 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
8557 break;
8558 }
[email protected]8aec81ec2014-04-29 01:04:518559 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8560 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: {
8561 bytes_required = (std::max(width, 8) * std::max(height, 8) * 4 + 7)/8;
8562 break;
8563 }
8564 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8565 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8566 bytes_required = (std::max(width, 16) * std::max(height, 8) * 2 + 7)/8;
[email protected]2d3765b2012-10-03 00:31:078567 break;
8568 }
[email protected]ad84a3a2012-06-08 21:42:438569 default:
[email protected]ab09b612013-03-11 22:11:518570 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:438571 return false;
8572 }
8573
8574 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:518575 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438576 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
8577 return false;
8578 }
8579
8580 return true;
8581}
8582
8583bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
8584 const char* function_name,
8585 GLint level, GLsizei width, GLsizei height, GLenum format) {
8586 switch (format) {
8587 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8588 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8589 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8590 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8591 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:518592 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438593 GL_INVALID_OPERATION, function_name,
8594 "width or height invalid for level");
8595 return false;
8596 }
8597 return true;
8598 }
[email protected]8aec81ec2014-04-29 01:04:518599 case GL_ATC_RGB_AMD:
8600 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8601 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
8602 case GL_ETC1_RGB8_OES: {
[email protected]2d3765b2012-10-03 00:31:078603 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:518604 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078605 GL_INVALID_OPERATION, function_name,
8606 "width or height invalid for level");
8607 return false;
8608 }
8609 return true;
[email protected]8aec81ec2014-04-29 01:04:518610 }
8611 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8612 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8613 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8614 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8615 if (!IsValidPVRTCSize(level, width) ||
8616 !IsValidPVRTCSize(level, height)) {
8617 LOCAL_SET_GL_ERROR(
8618 GL_INVALID_OPERATION, function_name,
8619 "width or height invalid for level");
8620 return false;
8621 }
8622 return true;
8623 }
[email protected]ad84a3a2012-06-08 21:42:438624 default:
8625 return false;
8626 }
8627}
8628
8629bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
8630 const char* function_name,
8631 GLenum target, GLint level, GLint xoffset, GLint yoffset,
8632 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:358633 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:438634 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:518635 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438636 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
8637 return false;
8638 }
8639
8640 switch (format) {
8641 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8642 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8643 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8644 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8645 const int kBlockWidth = 4;
8646 const int kBlockHeight = 4;
8647 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:518648 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438649 GL_INVALID_OPERATION, function_name,
8650 "xoffset or yoffset not multiple of 4");
8651 return false;
8652 }
8653 GLsizei tex_width = 0;
8654 GLsizei tex_height = 0;
8655 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8656 width - xoffset > tex_width ||
8657 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:518658 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438659 GL_INVALID_OPERATION, function_name, "dimensions out of range");
8660 return false;
8661 }
8662 return ValidateCompressedTexDimensions(
8663 function_name, level, width, height, format);
8664 }
[email protected]8aec81ec2014-04-29 01:04:518665 case GL_ATC_RGB_AMD:
8666 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8667 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: {
8668 LOCAL_SET_GL_ERROR(
8669 GL_INVALID_OPERATION, function_name,
8670 "not supported for ATC textures");
8671 return false;
8672 }
[email protected]2d3765b2012-10-03 00:31:078673 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:518674 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078675 GL_INVALID_OPERATION, function_name,
[email protected]caa13ed2014-02-17 11:29:208676 "not supported for ECT1_RGB8_OES textures");
[email protected]2d3765b2012-10-03 00:31:078677 return false;
8678 }
[email protected]8aec81ec2014-04-29 01:04:518679 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8680 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8681 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8682 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8683 if ((xoffset != 0) || (yoffset != 0)) {
8684 LOCAL_SET_GL_ERROR(
8685 GL_INVALID_OPERATION, function_name,
8686 "xoffset and yoffset must be zero");
8687 return false;
8688 }
8689 GLsizei tex_width = 0;
8690 GLsizei tex_height = 0;
8691 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8692 width != tex_width ||
8693 height != tex_height) {
8694 LOCAL_SET_GL_ERROR(
8695 GL_INVALID_OPERATION, function_name,
8696 "dimensions must match existing texture level dimensions");
8697 return false;
8698 }
8699 return ValidateCompressedTexDimensions(
8700 function_name, level, width, height, format);
8701 }
[email protected]ad84a3a2012-06-08 21:42:438702 default:
8703 return false;
8704 }
8705}
8706
[email protected]a93bb842010-02-16 23:03:478707error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
8708 GLenum target,
8709 GLint level,
8710 GLenum internal_format,
8711 GLsizei width,
8712 GLsizei height,
8713 GLint border,
8714 GLsizei image_size,
8715 const void* data) {
[email protected]a93bb842010-02-16 23:03:478716 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:058717 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518718 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8719 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:298720 return error::kNoError;
8721 }
[email protected]9438b012010-06-15 22:55:058722 if (!validators_->compressed_texture_format.IsValid(
8723 internal_format)) {
[email protected]ab09b612013-03-11 22:11:518724 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538725 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:478726 return error::kNoError;
8727 }
[email protected]80eb6b52012-01-19 00:14:418728 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:478729 border != 0) {
[email protected]ab09b612013-03-11 22:11:518730 LOCAL_SET_GL_ERROR(
8731 GL_INVALID_VALUE,
8732 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:478733 return error::kNoError;
8734 }
[email protected]c986af502013-08-14 01:04:448735 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8736 &state_, target);
[email protected]370eaf12013-05-18 09:19:498737 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518738 LOCAL_SET_GL_ERROR(
8739 GL_INVALID_VALUE,
8740 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:478741 return error::kNoError;
8742 }
[email protected]370eaf12013-05-18 09:19:498743 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078744 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518745 LOCAL_SET_GL_ERROR(
8746 GL_INVALID_OPERATION,
8747 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:438748 return error::kNoError;
8749 }
8750
8751 if (!ValidateCompressedTexDimensions(
8752 "glCompressedTexImage2D", level, width, height, internal_format) ||
8753 !ValidateCompressedTexFuncData(
8754 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:178755 return error::kNoError;
8756 }
[email protected]968351b2011-12-20 08:26:518757
[email protected]7989c9e2013-01-23 06:39:268758 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:518759 LOCAL_SET_GL_ERROR(
8760 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:268761 return error::kNoError;
8762 }
8763
[email protected]02965c22013-03-09 02:40:078764 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448765 framebuffer_state_.clear_state_dirty = true;
[email protected]968351b2011-12-20 08:26:518766 }
8767
[email protected]40d90a22013-04-09 03:39:558768 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:478769 if (!data) {
8770 zero.reset(new int8[image_size]);
8771 memset(zero.get(), 0, image_size);
8772 data = zero.get();
8773 }
[email protected]ab09b612013-03-11 22:11:518774 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:478775 glCompressedTexImage2D(
8776 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:518777 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438778 if (error == GL_NO_ERROR) {
8779 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498780 texture_ref, target, level, internal_format,
8781 width, height, 1, border, 0, 0, true);
[email protected]cadde4a2010-07-31 17:10:438782 }
vmiura8266ca72014-09-09 21:37:008783
8784 // This may be a slow command. Exit command processing to allow for
8785 // context preemption and GPU watchdog checks.
8786 ExitCommandProcessingEarly();
[email protected]a93bb842010-02-16 23:03:478787 return error::kNoError;
8788}
8789
[email protected]f7a64ee2010-02-01 22:24:148790error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
vmiuracd108592014-09-08 14:36:348791 uint32 immediate_data_size,
8792 const void* cmd_data) {
8793 const gles2::cmds::CompressedTexImage2D& c =
8794 *static_cast<const gles2::cmds::CompressedTexImage2D*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:198795 GLenum target = static_cast<GLenum>(c.target);
8796 GLint level = static_cast<GLint>(c.level);
8797 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8798 GLsizei width = static_cast<GLsizei>(c.width);
8799 GLsizei height = static_cast<GLsizei>(c.height);
8800 GLint border = static_cast<GLint>(c.border);
8801 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
8802 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8803 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8804 const void* data = NULL;
8805 if (data_shm_id != 0 || data_shm_offset != 0) {
8806 data = GetSharedMemoryAs<const void*>(
8807 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:468808 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:148809 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198810 }
8811 }
[email protected]a93bb842010-02-16 23:03:478812 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:198813 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:198814}
8815
[email protected]b6140d02010-05-17 14:47:168816error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
vmiuracd108592014-09-08 14:36:348817 uint32 immediate_data_size,
8818 const void* cmd_data) {
8819 const gles2::cmds::CompressedTexImage2DBucket& c =
8820 *static_cast<const gles2::cmds::CompressedTexImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:168821 GLenum target = static_cast<GLenum>(c.target);
8822 GLint level = static_cast<GLint>(c.level);
8823 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8824 GLsizei width = static_cast<GLsizei>(c.width);
8825 GLsizei height = static_cast<GLsizei>(c.height);
8826 GLint border = static_cast<GLint>(c.border);
8827 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288828 if (!bucket) {
8829 return error::kInvalidArguments;
8830 }
8831 uint32 data_size = bucket->size();
8832 GLsizei imageSize = data_size;
8833 const void* data = bucket->GetData(0, data_size);
8834 if (!data) {
8835 return error::kInvalidArguments;
8836 }
[email protected]b6140d02010-05-17 14:47:168837 return DoCompressedTexImage2D(
8838 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:288839 imageSize, data);
[email protected]b6140d02010-05-17 14:47:168840}
8841
8842error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
8843 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:348844 const void* cmd_data) {
8845 const gles2::cmds::CompressedTexSubImage2DBucket& c =
8846 *static_cast<const gles2::cmds::CompressedTexSubImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:168847 GLenum target = static_cast<GLenum>(c.target);
8848 GLint level = static_cast<GLint>(c.level);
8849 GLint xoffset = static_cast<GLint>(c.xoffset);
8850 GLint yoffset = static_cast<GLint>(c.yoffset);
8851 GLsizei width = static_cast<GLsizei>(c.width);
8852 GLsizei height = static_cast<GLsizei>(c.height);
8853 GLenum format = static_cast<GLenum>(c.format);
8854 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288855 if (!bucket) {
8856 return error::kInvalidArguments;
8857 }
[email protected]b6140d02010-05-17 14:47:168858 uint32 data_size = bucket->size();
8859 GLsizei imageSize = data_size;
8860 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:288861 if (!data) {
8862 return error::kInvalidArguments;
8863 }
[email protected]9438b012010-06-15 22:55:058864 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518865 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:538866 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:168867 return error::kNoError;
8868 }
[email protected]9438b012010-06-15 22:55:058869 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518870 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8871 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:058872 return error::kNoError;
8873 }
[email protected]b6140d02010-05-17 14:47:168874 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518875 LOCAL_SET_GL_ERROR(
8876 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:168877 return error::kNoError;
8878 }
8879 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518880 LOCAL_SET_GL_ERROR(
8881 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:168882 return error::kNoError;
8883 }
8884 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:518885 LOCAL_SET_GL_ERROR(
8886 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:168887 return error::kNoError;
8888 }
[email protected]cadde4a2010-07-31 17:10:438889 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:168890 target, level, xoffset, yoffset, width, height, format, imageSize, data);
8891 return error::kNoError;
8892}
8893
vmiuracd108592014-09-08 14:36:348894error::Error GLES2DecoderImpl::HandleTexImage2D(uint32 immediate_data_size,
8895 const void* cmd_data) {
8896 const gles2::cmds::TexImage2D& c =
8897 *static_cast<const gles2::cmds::TexImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:138898 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D",
8899 "width", c.width, "height", c.height);
[email protected]c986af502013-08-14 01:04:448900 // Set as failed for now, but if it successed, this will be set to not failed.
8901 texture_state_.tex_image_2d_failed = true;
[email protected]b9849abf2009-11-25 19:13:198902 GLenum target = static_cast<GLenum>(c.target);
8903 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:448904 // TODO(kloveless): Change TexImage2D command to use unsigned integer
8905 // for internalformat.
8906 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:198907 GLsizei width = static_cast<GLsizei>(c.width);
8908 GLsizei height = static_cast<GLsizei>(c.height);
8909 GLint border = static_cast<GLint>(c.border);
8910 GLenum format = static_cast<GLenum>(c.format);
8911 GLenum type = static_cast<GLenum>(c.type);
8912 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
8913 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:188914 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:348915 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428916 width, height, 1, format, type, state_.unpack_alignment, &pixels_size,
8917 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:188918 return error::kOutOfBounds;
8919 }
[email protected]b9849abf2009-11-25 19:13:198920 const void* pixels = NULL;
8921 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
8922 pixels = GetSharedMemoryAs<const void*>(
8923 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:468924 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:148925 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198926 }
8927 }
[email protected]f598f422012-12-07 08:30:038928
[email protected]c986af502013-08-14 01:04:448929 TextureManager::DoTextImage2DArguments args = {
8930 target, level, internal_format, width, height, border, format, type,
8931 pixels, pixels_size};
8932 texture_manager()->ValidateAndDoTexImage2D(
8933 &texture_state_, &state_, &framebuffer_state_, args);
vmiura8266ca72014-09-09 21:37:008934
8935 // This may be a slow command. Exit command processing to allow for
8936 // context preemption and GPU watchdog checks.
8937 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:038938 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198939}
8940
zmobcadd6592015-01-08 20:13:428941error::Error GLES2DecoderImpl::HandleTexImage3D(uint32 immediate_data_size,
8942 const void* cmd_data) {
8943 // TODO(zmo): Unsafe ES3 API.
8944 if (!unsafe_es3_apis_enabled())
8945 return error::kUnknownCommand;
8946
8947 const gles2::cmds::TexImage3D& c =
8948 *static_cast<const gles2::cmds::TexImage3D*>(cmd_data);
8949 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage3D",
8950 "widthXheight", c.width * c.height, "depth", c.depth);
8951 GLenum target = static_cast<GLenum>(c.target);
8952 GLint level = static_cast<GLint>(c.level);
8953 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8954 GLsizei width = static_cast<GLsizei>(c.width);
8955 GLsizei height = static_cast<GLsizei>(c.height);
8956 GLsizei depth = static_cast<GLsizei>(c.depth);
8957 GLint border = static_cast<GLint>(c.border);
8958 GLenum format = static_cast<GLenum>(c.format);
8959 GLenum type = static_cast<GLenum>(c.type);
8960 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
8961 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
8962 uint32 pixels_size;
8963 if (!GLES2Util::ComputeImageDataSizes(
8964 width, height, depth, format, type, state_.unpack_alignment, &pixels_size,
8965 NULL, NULL)) {
8966 return error::kOutOfBounds;
8967 }
8968 const void* pixels = NULL;
8969 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
8970 pixels = GetSharedMemoryAs<const void*>(
8971 pixels_shm_id, pixels_shm_offset, pixels_size);
8972 if (!pixels) {
8973 return error::kOutOfBounds;
8974 }
8975 }
8976
8977 glTexImage3D(target, level, internal_format, width, height, depth, border,
8978 format, type, pixels);
8979
8980 // This may be a slow command. Exit command processing to allow for
8981 // context preemption and GPU watchdog checks.
8982 ExitCommandProcessingEarly();
8983 return error::kNoError;
8984}
8985
[email protected]cadde4a2010-07-31 17:10:438986void GLES2DecoderImpl::DoCompressedTexSubImage2D(
8987 GLenum target,
8988 GLint level,
8989 GLint xoffset,
8990 GLint yoffset,
8991 GLsizei width,
8992 GLsizei height,
8993 GLenum format,
8994 GLsizei image_size,
8995 const void * data) {
[email protected]c986af502013-08-14 01:04:448996 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8997 &state_, target);
[email protected]370eaf12013-05-18 09:19:498998 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518999 LOCAL_SET_GL_ERROR(
9000 GL_INVALID_OPERATION,
9001 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:439002 return;
9003 }
[email protected]370eaf12013-05-18 09:19:499004 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:439005 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:529006 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:079007 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:519008 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:529009 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439010 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:529011 return;
9012 }
9013 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:519014 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:529015 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439016 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:529017 return;
9018 }
[email protected]02965c22013-03-09 02:40:079019 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:529020 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:519021 LOCAL_SET_GL_ERROR(
9022 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:439023 return;
9024 }
[email protected]ad84a3a2012-06-08 21:42:439025
9026 if (!ValidateCompressedTexFuncData(
9027 "glCompressedTexSubImage2D", width, height, format, image_size) ||
9028 !ValidateCompressedTexSubDimensions(
9029 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:079030 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:439031 return;
9032 }
9033
9034
[email protected]0d6bfdc2011-11-02 01:32:209035 // Note: There is no need to deal with texture cleared tracking here
9036 // because the validation above means you can only get here if the level
9037 // is already a matching compressed format and in that case
9038 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:439039 glCompressedTexSubImage2D(
9040 target, level, xoffset, yoffset, width, height, format, image_size, data);
vmiura8266ca72014-09-09 21:37:009041
9042 // This may be a slow command. Exit command processing to allow for
9043 // context preemption and GPU watchdog checks.
9044 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:439045}
9046
[email protected]6e288612010-12-21 20:45:039047static void Clip(
9048 GLint start, GLint range, GLint sourceRange,
9049 GLint* out_start, GLint* out_range) {
9050 DCHECK(out_start);
9051 DCHECK(out_range);
9052 if (start < 0) {
9053 range += start;
9054 start = 0;
9055 }
9056 GLint end = start + range;
9057 if (end > sourceRange) {
9058 range -= end - sourceRange;
9059 }
9060 *out_start = start;
9061 *out_range = range;
9062}
9063
[email protected]cadde4a2010-07-31 17:10:439064void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:449065 GLenum target,
9066 GLint level,
9067 GLenum internal_format,
9068 GLint x,
9069 GLint y,
9070 GLsizei width,
9071 GLsizei height,
9072 GLint border) {
[email protected]09e17272012-11-30 10:30:449073 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:449074 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9075 &state_, target);
[email protected]370eaf12013-05-18 09:19:499076 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519077 LOCAL_SET_GL_ERROR(
9078 GL_INVALID_OPERATION,
9079 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:439080 return;
9081 }
[email protected]370eaf12013-05-18 09:19:499082 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079083 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:519084 LOCAL_SET_GL_ERROR(
9085 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]cedee332014-05-23 07:07:539086 return;
[email protected]97dc7cbe2011-12-06 17:26:179087 }
[email protected]80eb6b52012-01-19 00:14:419088 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:189089 border != 0) {
[email protected]ab09b612013-03-11 22:11:519090 LOCAL_SET_GL_ERROR(
9091 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:189092 return;
9093 }
[email protected]17a961192014-02-14 15:20:529094 if (!texture_manager()->ValidateFormatAndTypeCombination(
9095 state_.GetErrorState(), "glCopyTexImage2D", internal_format,
9096 GL_UNSIGNED_BYTE)) {
[email protected]81375742012-06-08 00:04:009097 return;
9098 }
[email protected]f5719fb2010-08-04 18:27:189099
[email protected]9edc6b22010-12-23 02:00:269100 // Check we have compatible formats.
9101 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
9102 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
9103 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
9104
9105 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:519106 LOCAL_SET_GL_ERROR(
9107 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:269108 return;
9109 }
9110
[email protected]81375742012-06-08 00:04:009111 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:519112 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:009113 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:269114 "glCopyTexImage2D", "can not be used with depth or stencil textures");
9115 return;
9116 }
9117
9118 uint32 estimated_size = 0;
9119 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:429120 width, height, 1, internal_format, GL_UNSIGNED_BYTE,
9121 state_.unpack_alignment, &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:519122 LOCAL_SET_GL_ERROR(
9123 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:269124 return;
9125 }
9126
9127 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519128 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:009129 return;
9130 }
9131
[email protected]2ea5950d2014-07-09 18:20:349132 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexImage2D")) {
9133 return;
9134 }
9135
zmo383512cf2014-10-14 00:11:009136 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
9137 LOCAL_SET_GL_ERROR(
9138 GL_INVALID_OPERATION,
9139 "glCopyTexImage2D", "source and destination textures are the same");
9140 return;
9141 }
9142
[email protected]a0b78dc2011-11-11 10:43:109143 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
9144 return;
9145 }
9146
[email protected]ab09b612013-03-11 22:11:519147 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:279148 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:039149 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:269150
[email protected]02965c22013-03-09 02:40:079151 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:449152 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:469153 }
9154
[email protected]9edc6b22010-12-23 02:00:269155 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:039156 GLint copyX = 0;
9157 GLint copyY = 0;
9158 GLint copyWidth = 0;
9159 GLint copyHeight = 0;
9160 Clip(x, width, size.width(), &copyX, &copyWidth);
9161 Clip(y, height, size.height(), &copyY, &copyHeight);
9162
9163 if (copyX != x ||
9164 copyY != y ||
9165 copyWidth != width ||
9166 copyHeight != height) {
9167 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:209168 if (!ClearLevel(
[email protected]02965c22013-03-09 02:40:079169 texture->service_id(), texture->target(),
[email protected]d8e6c9242014-02-20 16:56:259170 target, level, internal_format, internal_format, GL_UNSIGNED_BYTE,
9171 width, height, texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:519172 LOCAL_SET_GL_ERROR(
9173 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:039174 return;
9175 }
[email protected]6e288612010-12-21 20:45:039176 if (copyHeight > 0 && copyWidth > 0) {
9177 GLint dx = copyX - x;
9178 GLint dy = copyY - y;
9179 GLint destX = dx;
9180 GLint destY = dy;
[email protected]00c2cf92014-03-14 00:08:379181 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039182 glCopyTexSubImage2D(target, level,
9183 destX, destY, copyX, copyY,
9184 copyWidth, copyHeight);
9185 }
9186 } else {
[email protected]00c2cf92014-03-14 00:08:379187 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039188 glCopyTexImage2D(target, level, internal_format,
9189 copyX, copyY, copyWidth, copyHeight, border);
9190 }
[email protected]ab09b612013-03-11 22:11:519191 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:439192 if (error == GL_NO_ERROR) {
9193 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499194 texture_ref, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:209195 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:439196 }
vmiura8266ca72014-09-09 21:37:009197
9198 // This may be a slow command. Exit command processing to allow for
9199 // context preemption and GPU watchdog checks.
9200 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:439201}
9202
9203void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:449204 GLenum target,
9205 GLint level,
9206 GLint xoffset,
9207 GLint yoffset,
9208 GLint x,
9209 GLint y,
9210 GLsizei width,
9211 GLsizei height) {
[email protected]09e17272012-11-30 10:30:449212 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:449213 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9214 &state_, target);
[email protected]370eaf12013-05-18 09:19:499215 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519216 LOCAL_SET_GL_ERROR(
9217 GL_INVALID_OPERATION,
9218 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:439219 return;
9220 }
[email protected]370eaf12013-05-18 09:19:499221 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:439222 GLenum type = 0;
9223 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:079224 if (!texture->GetLevelType(target, level, &type, &format) ||
9225 !texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:529226 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:519227 LOCAL_SET_GL_ERROR(
9228 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:439229 return;
9230 }
[email protected]85a4ac22013-05-31 01:58:479231 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:519232 LOCAL_SET_GL_ERROR(
9233 GL_INVALID_OPERATION,
9234 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:599235 return;
9236 }
[email protected]9edc6b22010-12-23 02:00:269237
9238 // Check we have compatible formats.
9239 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
9240 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
9241 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
9242
[email protected]2d3765b2012-10-03 00:31:079243 if (!channels_needed ||
9244 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:519245 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439246 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:269247 return;
9248 }
9249
[email protected]81375742012-06-08 00:04:009250 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:519251 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:009252 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439253 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:009254 return;
9255 }
9256
[email protected]2ea5950d2014-07-09 18:20:349257 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexSubImage2D")) {
9258 return;
9259 }
9260
zmo383512cf2014-10-14 00:11:009261 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
9262 LOCAL_SET_GL_ERROR(
9263 GL_INVALID_OPERATION,
9264 "glCopyTexSubImage2D", "source and destination textures are the same");
9265 return;
9266 }
9267
[email protected]a0b78dc2011-11-11 10:43:109268 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
9269 return;
9270 }
9271
[email protected]de26b3c2011-08-03 21:54:279272 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:039273 gfx::Size size = GetBoundReadFrameBufferSize();
9274 GLint copyX = 0;
9275 GLint copyY = 0;
9276 GLint copyWidth = 0;
9277 GLint copyHeight = 0;
9278 Clip(x, width, size.width(), &copyX, &copyWidth);
9279 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:209280
dongseong.hwang351519f2015-01-21 14:33:599281 if (xoffset != 0 || yoffset != 0 || width != size.width() ||
9282 height != size.height()) {
9283 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target,
9284 level)) {
9285 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexSubImage2D",
9286 "dimensions too big");
9287 return;
9288 }
9289 } else {
9290 // Write all pixels in below.
9291 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
[email protected]0d6bfdc2011-11-02 01:32:209292 }
9293
[email protected]6e288612010-12-21 20:45:039294 if (copyX != x ||
9295 copyY != y ||
9296 copyWidth != width ||
9297 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:209298 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:039299 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:349300 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:429301 width, height, 1, format, type, state_.unpack_alignment, &pixels_size,
[email protected]e259eb412012-10-13 05:47:249302 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:519303 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439304 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:039305 return;
9306 }
[email protected]40d90a22013-04-09 03:39:559307 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:039308 memset(zero.get(), 0, pixels_size);
[email protected]00c2cf92014-03-14 00:08:379309 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039310 glTexSubImage2D(
9311 target, level, xoffset, yoffset, width, height,
9312 format, type, zero.get());
9313 }
[email protected]0d6bfdc2011-11-02 01:32:209314
[email protected]6e288612010-12-21 20:45:039315 if (copyHeight > 0 && copyWidth > 0) {
9316 GLint dx = copyX - x;
9317 GLint dy = copyY - y;
9318 GLint destX = xoffset + dx;
9319 GLint destY = yoffset + dy;
[email protected]00c2cf92014-03-14 00:08:379320 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039321 glCopyTexSubImage2D(target, level,
9322 destX, destY, copyX, copyY,
9323 copyWidth, copyHeight);
9324 }
vmiura8266ca72014-09-09 21:37:009325
9326 // This may be a slow command. Exit command processing to allow for
9327 // context preemption and GPU watchdog checks.
9328 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:439329}
9330
[email protected]f598f422012-12-07 08:30:039331bool GLES2DecoderImpl::ValidateTexSubImage2D(
9332 error::Error* error,
9333 const char* function_name,
9334 GLenum target,
9335 GLint level,
9336 GLint xoffset,
9337 GLint yoffset,
9338 GLsizei width,
9339 GLsizei height,
9340 GLenum format,
9341 GLenum type,
9342 const void * data) {
9343 (*error) = error::kNoError;
9344 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:519345 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:039346 return false;
9347 }
9348 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:519349 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:039350 return false;
9351 }
9352 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:519353 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:039354 return false;
9355 }
[email protected]c986af502013-08-14 01:04:449356 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9357 &state_, target);
[email protected]370eaf12013-05-18 09:19:499358 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519359 LOCAL_SET_GL_ERROR(
9360 GL_INVALID_OPERATION,
9361 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:039362 return false;
[email protected]cadde4a2010-07-31 17:10:439363 }
[email protected]370eaf12013-05-18 09:19:499364 Texture* texture = texture_ref->texture();
[email protected]df6cf1ad2011-01-29 01:20:529365 GLenum current_type = 0;
9366 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:079367 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:519368 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:039369 GL_INVALID_OPERATION, function_name, "level does not exist.");
9370 return false;
[email protected]df6cf1ad2011-01-29 01:20:529371 }
[email protected]17a961192014-02-14 15:20:529372 if (!texture_manager()->ValidateTextureParameters(state_.GetErrorState(),
9373 function_name, format, type, internal_format, level)) {
[email protected]f598f422012-12-07 08:30:039374 return false;
[email protected]df6cf1ad2011-01-29 01:20:529375 }
9376 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:519377 LOCAL_SET_GL_ERROR(
9378 GL_INVALID_OPERATION,
9379 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:039380 return false;
[email protected]df6cf1ad2011-01-29 01:20:529381 }
[email protected]85a4ac22013-05-31 01:58:479382 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:519383 LOCAL_SET_GL_ERROR(
9384 GL_INVALID_OPERATION,
9385 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:599386 return false;
9387 }
[email protected]02965c22013-03-09 02:40:079388 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:529389 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:519390 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:039391 return false;
[email protected]cadde4a2010-07-31 17:10:439392 }
[email protected]81375742012-06-08 00:04:009393 if ((GLES2Util::GetChannelsForFormat(format) &
9394 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:519395 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:009396 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:039397 function_name, "can not supply data for depth or stencil textures");
9398 return false;
[email protected]81375742012-06-08 00:04:009399 }
[email protected]f598f422012-12-07 08:30:039400 if (data == NULL) {
9401 (*error) = error::kOutOfBounds;
9402 return false;
9403 }
9404 return true;
9405}
[email protected]81375742012-06-08 00:04:009406
[email protected]f598f422012-12-07 08:30:039407error::Error GLES2DecoderImpl::DoTexSubImage2D(
9408 GLenum target,
9409 GLint level,
9410 GLint xoffset,
9411 GLint yoffset,
9412 GLsizei width,
9413 GLsizei height,
9414 GLenum format,
9415 GLenum type,
9416 const void * data) {
9417 error::Error error = error::kNoError;
9418 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
9419 xoffset, yoffset, width, height, format, type, data)) {
9420 return error;
9421 }
[email protected]c986af502013-08-14 01:04:449422 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9423 &state_, target);
[email protected]370eaf12013-05-18 09:19:499424 Texture* texture = texture_ref->texture();
[email protected]4502e6492011-12-14 19:39:159425 GLsizei tex_width = 0;
9426 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:079427 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:159428 DCHECK(ok);
9429 if (xoffset != 0 || yoffset != 0 ||
9430 width != tex_width || height != tex_height) {
[email protected]370eaf12013-05-18 09:19:499431 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
9432 target, level)) {
[email protected]ab09b612013-03-11 22:11:519433 LOCAL_SET_GL_ERROR(
9434 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:039435 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:309436 }
[email protected]c986af502013-08-14 01:04:449437 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:159438 glTexSubImage2D(
9439 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:039440 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:209441 }
[email protected]4502e6492011-12-14 19:39:159442
[email protected]345ba902013-11-14 21:39:009443 if (!texture_state_.texsubimage2d_faster_than_teximage2d &&
[email protected]c986af502013-08-14 01:04:449444 !texture->IsImmutable()) {
9445 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]d8e6c9242014-02-20 16:56:259446 GLenum internal_format;
9447 GLenum tex_type;
9448 texture->GetLevelType(target, level, &tex_type, &internal_format);
9449 // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need
9450 // to look it up.
[email protected]8f1d2aa2013-05-10 23:45:389451 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:259452 target, level, internal_format, width, height, 0, format, type, data);
[email protected]4502e6492011-12-14 19:39:159453 } else {
[email protected]c986af502013-08-14 01:04:449454 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:159455 glTexSubImage2D(
9456 target, level, xoffset, yoffset, width, height, format, type, data);
9457 }
[email protected]370eaf12013-05-18 09:19:499458 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
vmiura8266ca72014-09-09 21:37:009459
9460 // This may be a slow command. Exit command processing to allow for
9461 // context preemption and GPU watchdog checks.
9462 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:039463 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:439464}
9465
vmiuracd108592014-09-08 14:36:349466error::Error GLES2DecoderImpl::HandleTexSubImage2D(uint32 immediate_data_size,
9467 const void* cmd_data) {
9468 const gles2::cmds::TexSubImage2D& c =
9469 *static_cast<const gles2::cmds::TexSubImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:139470 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage2D",
9471 "width", c.width, "height", c.height);
[email protected]b493ee622011-04-13 23:52:009472 GLboolean internal = static_cast<GLboolean>(c.internal);
[email protected]c986af502013-08-14 01:04:449473 if (internal == GL_TRUE && texture_state_.tex_image_2d_failed)
[email protected]b493ee622011-04-13 23:52:009474 return error::kNoError;
9475
9476 GLenum target = static_cast<GLenum>(c.target);
9477 GLint level = static_cast<GLint>(c.level);
9478 GLint xoffset = static_cast<GLint>(c.xoffset);
9479 GLint yoffset = static_cast<GLint>(c.yoffset);
9480 GLsizei width = static_cast<GLsizei>(c.width);
9481 GLsizei height = static_cast<GLsizei>(c.height);
9482 GLenum format = static_cast<GLenum>(c.format);
9483 GLenum type = static_cast<GLenum>(c.type);
9484 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:349485 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:429486 width, height, 1, format, type, state_.unpack_alignment, &data_size,
[email protected]e259eb412012-10-13 05:47:249487 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:009488 return error::kOutOfBounds;
9489 }
9490 const void* pixels = GetSharedMemoryAs<const void*>(
9491 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:039492 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:009493 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:009494}
9495
zmobcadd6592015-01-08 20:13:429496// TODO(zmo): Remove the below stub once we add the real function binding.
9497// Currently it's missing due to a gmock limitation.
9498static void glTexSubImage3D(
9499 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
9500 GLsizei height, GLsizei width, GLsizei depth, GLenum format, GLenum type,
9501 const void* pixels) {
9502 NOTIMPLEMENTED();
9503}
9504
9505error::Error GLES2DecoderImpl::HandleTexSubImage3D(uint32 immediate_data_size,
9506 const void* cmd_data) {
9507 // TODO(zmo): Unsafe ES3 API.
9508 if (!unsafe_es3_apis_enabled())
9509 return error::kUnknownCommand;
9510
9511 const gles2::cmds::TexSubImage3D& c =
9512 *static_cast<const gles2::cmds::TexSubImage3D*>(cmd_data);
9513 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage3D",
9514 "widthXheight", c.width * c.height, "depth", c.depth);
9515 GLenum target = static_cast<GLenum>(c.target);
9516 GLint level = static_cast<GLint>(c.level);
9517 GLint xoffset = static_cast<GLint>(c.xoffset);
9518 GLint yoffset = static_cast<GLint>(c.yoffset);
9519 GLint zoffset = static_cast<GLint>(c.zoffset);
9520 GLsizei width = static_cast<GLsizei>(c.width);
9521 GLsizei height = static_cast<GLsizei>(c.height);
9522 GLsizei depth = static_cast<GLsizei>(c.depth);
9523 GLenum format = static_cast<GLenum>(c.format);
9524 GLenum type = static_cast<GLenum>(c.type);
9525 uint32 data_size;
9526 if (!GLES2Util::ComputeImageDataSizes(
9527 width, height, depth, format, type, state_.unpack_alignment, &data_size,
9528 NULL, NULL)) {
9529 return error::kOutOfBounds;
9530 }
9531 const void* pixels = GetSharedMemoryAs<const void*>(
9532 c.pixels_shm_id, c.pixels_shm_offset, data_size);
9533 glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height,
9534 depth, format, type, pixels);
9535 return error::kNoError;
9536}
9537
[email protected]f7a64ee2010-02-01 22:24:149538error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
vmiuracd108592014-09-08 14:36:349539 uint32 immediate_data_size,
9540 const void* cmd_data) {
9541 const gles2::cmds::GetVertexAttribPointerv& c =
9542 *static_cast<const gles2::cmds::GetVertexAttribPointerv*>(cmd_data);
[email protected]8bf5a3e2010-01-29 04:21:369543 GLuint index = static_cast<GLuint>(c.index);
9544 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:359545 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:259546 Result* result = GetSharedMemoryAs<Result*>(
9547 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:369548 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:149549 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:369550 }
[email protected]07d0cc82010-02-17 04:51:409551 // Check that the client initialized the result.
9552 if (result->size != 0) {
9553 return error::kInvalidArguments;
9554 }
[email protected]9438b012010-06-15 22:55:059555 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:519556 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9557 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:149558 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369559 }
[email protected]3916c97e2010-02-25 03:20:509560 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:519561 LOCAL_SET_GL_ERROR(
9562 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:149563 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369564 }
[email protected]0bfd9882010-02-05 23:02:259565 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:089566 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:359567 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:149568 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329569}
9570
[email protected]f7b85372010-02-03 01:11:379571bool GLES2DecoderImpl::GetUniformSetup(
[email protected]df37b9932013-03-08 05:21:429572 GLuint program_id, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:379573 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:129574 error::Error* error, GLint* real_location,
9575 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:109576 DCHECK(error);
9577 DCHECK(service_id);
9578 DCHECK(result_pointer);
9579 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:129580 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:379581 *error = error::kNoError;
9582 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:259583 SizedResult<GLint>* result;
9584 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9585 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
9586 if (!result) {
[email protected]f7b85372010-02-03 01:11:379587 *error = error::kOutOfBounds;
9588 return false;
9589 }
[email protected]0bfd9882010-02-05 23:02:259590 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:379591 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:259592 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:429593 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
9594 if (!program) {
[email protected]ae51d192010-04-27 00:48:039595 return false;
9596 }
[email protected]df37b9932013-03-08 05:21:429597 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:379598 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:519599 LOCAL_SET_GL_ERROR(
9600 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:379601 return false;
9602 }
[email protected]df37b9932013-03-08 05:21:429603 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:369604 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:359605 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:429606 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:129607 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:369608 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:379609 // No such location.
[email protected]ab09b612013-03-11 22:11:519610 LOCAL_SET_GL_ERROR(
9611 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:379612 return false;
9613 }
[email protected]43c2f1f2011-03-25 18:35:369614 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:509615 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:379616 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:519617 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:379618 return false;
9619 }
[email protected]0bfd9882010-02-05 23:02:259620 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9621 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
9622 if (!result) {
[email protected]f7b85372010-02-03 01:11:379623 *error = error::kOutOfBounds;
9624 return false;
9625 }
[email protected]0bfd9882010-02-05 23:02:259626 result->size = size;
[email protected]939e7362010-05-13 20:49:109627 *result_type = type;
[email protected]f7b85372010-02-03 01:11:379628 return true;
9629}
9630
vmiuracd108592014-09-08 14:36:349631error::Error GLES2DecoderImpl::HandleGetUniformiv(uint32 immediate_data_size,
9632 const void* cmd_data) {
9633 const gles2::cmds::GetUniformiv& c =
9634 *static_cast<const gles2::cmds::GetUniformiv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379635 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339636 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379637 GLuint service_id;
[email protected]939e7362010-05-13 20:49:109638 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:129639 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379640 Error error;
[email protected]0bfd9882010-02-05 23:02:259641 void* result;
[email protected]f7b85372010-02-03 01:11:379642 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:129643 program, fake_location, c.params_shm_id, c.params_shm_offset,
9644 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:259645 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:129646 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:359647 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:379648 }
9649 return error;
[email protected]96449d2c2009-11-25 00:01:329650}
9651
vmiuracd108592014-09-08 14:36:349652error::Error GLES2DecoderImpl::HandleGetUniformfv(uint32 immediate_data_size,
9653 const void* cmd_data) {
9654 const gles2::cmds::GetUniformfv& c =
9655 *static_cast<const gles2::cmds::GetUniformfv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379656 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339657 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379658 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:129659 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379660 Error error;
[email protected]ed9f9cd2013-02-27 21:12:359661 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:109662 Result* result;
9663 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:379664 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:129665 program, fake_location, c.params_shm_id, c.params_shm_offset,
9666 &error, &real_location, &service_id,
9667 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:109668 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
9669 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
9670 GLsizei num_values = result->GetNumResults();
[email protected]40d90a22013-04-09 03:39:559671 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:129672 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:109673 GLfloat* dst = result->GetData();
9674 for (GLsizei ii = 0; ii < num_values; ++ii) {
9675 dst[ii] = (temp[ii] != 0);
9676 }
9677 } else {
[email protected]1b0a6752012-02-22 03:44:129678 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:109679 }
[email protected]f7b85372010-02-03 01:11:379680 }
9681 return error;
[email protected]96449d2c2009-11-25 00:01:329682}
9683
[email protected]f7a64ee2010-02-01 22:24:149684error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
vmiuracd108592014-09-08 14:36:349685 uint32 immediate_data_size,
9686 const void* cmd_data) {
9687 const gles2::cmds::GetShaderPrecisionFormat& c =
9688 *static_cast<const gles2::cmds::GetShaderPrecisionFormat*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259689 GLenum shader_type = static_cast<GLenum>(c.shadertype);
9690 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:359691 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:259692 Result* result = GetSharedMemoryAs<Result*>(
9693 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9694 if (!result) {
9695 return error::kOutOfBounds;
9696 }
[email protected]07d0cc82010-02-17 04:51:409697 // Check that the client initialized the result.
9698 if (result->success != 0) {
9699 return error::kInvalidArguments;
9700 }
[email protected]9438b012010-06-15 22:55:059701 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:519702 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539703 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:299704 return error::kNoError;
9705 }
[email protected]9438b012010-06-15 22:55:059706 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:519707 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539708 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:299709 return error::kNoError;
9710 }
9711
9712 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:409713
[email protected]46c86752013-05-21 05:08:399714 GLint range[2] = { 0, 0 };
[email protected]d8bc3ec2013-03-07 06:28:409715 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:219716 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:409717
9718 result->min_range = range[0];
9719 result->max_range = range[1];
9720 result->precision = precision;
9721
[email protected]f7a64ee2010-02-01 22:24:149722 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329723}
9724
[email protected]f7a64ee2010-02-01 22:24:149725error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
vmiuracd108592014-09-08 14:36:349726 uint32 immediate_data_size,
9727 const void* cmd_data) {
9728 const gles2::cmds::GetAttachedShaders& c =
9729 *static_cast<const gles2::cmds::GetAttachedShaders*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259730 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:429731 GLuint program_id = static_cast<GLuint>(c.program);
9732 Program* program = GetProgramInfoNotShader(
9733 program_id, "glGetAttachedShaders");
9734 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259735 return error::kNoError;
9736 }
[email protected]ed9f9cd2013-02-27 21:12:359737 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:259738 uint32 max_count = Result::ComputeMaxResults(result_size);
9739 Result* result = GetSharedMemoryAs<Result*>(
9740 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
9741 if (!result) {
9742 return error::kOutOfBounds;
9743 }
[email protected]07d0cc82010-02-17 04:51:409744 // Check that the client initialized the result.
9745 if (result->size != 0) {
9746 return error::kInvalidArguments;
9747 }
[email protected]0bfd9882010-02-05 23:02:259748 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:039749 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:429750 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:259751 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:039752 if (!shader_manager()->GetClientId(result->GetData()[ii],
9753 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:259754 NOTREACHED();
9755 return error::kGenericError;
9756 }
9757 }
9758 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:149759 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329760}
9761
[email protected]f7a64ee2010-02-01 22:24:149762error::Error GLES2DecoderImpl::HandleGetActiveUniform(
vmiuracd108592014-09-08 14:36:349763 uint32 immediate_data_size,
9764 const void* cmd_data) {
9765 const gles2::cmds::GetActiveUniform& c =
9766 *static_cast<const gles2::cmds::GetActiveUniform*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429767 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:259768 GLuint index = c.index;
9769 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:359770 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:259771 Result* result = GetSharedMemoryAs<Result*>(
9772 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9773 if (!result) {
9774 return error::kOutOfBounds;
9775 }
[email protected]07d0cc82010-02-17 04:51:409776 // Check that the client initialized the result.
9777 if (result->success != 0) {
9778 return error::kInvalidArguments;
9779 }
[email protected]df37b9932013-03-08 05:21:429780 Program* program = GetProgramInfoNotShader(
9781 program_id, "glGetActiveUniform");
9782 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259783 return error::kNoError;
9784 }
[email protected]ed9f9cd2013-02-27 21:12:359785 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:429786 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:259787 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:519788 LOCAL_SET_GL_ERROR(
9789 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:259790 return error::kNoError;
9791 }
9792 result->success = 1; // true.
9793 result->size = uniform_info->size;
9794 result->type = uniform_info->type;
9795 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:299796 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:149797 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329798}
9799
zmoa2b555d2015-02-06 23:50:399800error::Error GLES2DecoderImpl::HandleGetActiveUniformBlockiv(
9801 uint32 immediate_data_size, const void* cmd_data) {
9802 if (!unsafe_es3_apis_enabled())
9803 return error::kUnknownCommand;
9804 const gles2::cmds::GetActiveUniformBlockiv& c =
9805 *static_cast<const gles2::cmds::GetActiveUniformBlockiv*>(cmd_data);
9806 GLuint program_id = c.program;
9807 GLuint index = static_cast<GLuint>(c.index);
9808 GLenum pname = static_cast<GLenum>(c.pname);
9809 Program* program = GetProgramInfoNotShader(
zmo8fab00c2015-02-07 02:45:059810 program_id, "glGetActiveUniformBlockiv");
zmoa2b555d2015-02-06 23:50:399811 if (!program) {
9812 return error::kNoError;
9813 }
9814 GLuint service_id = program->service_id();
9815 GLint link_status = GL_FALSE;
9816 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
9817 if (link_status != GL_TRUE) {
9818 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
9819 "glGetActiveActiveUniformBlockiv", "program not linked");
9820 return error::kNoError;
9821 }
9822 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetActiveUniformBlockiv");
9823 GLsizei num_values = 1;
9824 if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) {
9825 GLint num = 0;
9826 glGetActiveUniformBlockiv(
9827 service_id, index, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &num);
9828 GLenum error = glGetError();
9829 if (error != GL_NO_ERROR) {
9830 // Assume this will the same error if calling with pname.
9831 LOCAL_SET_GL_ERROR(error, "GetActiveUniformBlockiv", "");
9832 return error::kNoError;
9833 }
9834 num_values = static_cast<GLsizei>(num);
9835 }
9836 typedef cmds::GetActiveUniformBlockiv::Result Result;
9837 Result* result = GetSharedMemoryAs<Result*>(
9838 c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
9839 GLint* params = result ? result->GetData() : NULL;
9840 if (params == NULL) {
9841 return error::kOutOfBounds;
9842 }
9843 // Check that the client initialized the result.
9844 if (result->size != 0) {
9845 return error::kInvalidArguments;
9846 }
9847 glGetActiveUniformBlockiv(service_id, index, pname, params);
9848 GLenum error = glGetError();
9849 if (error == GL_NO_ERROR) {
9850 result->SetNumResults(num_values);
9851 } else {
9852 LOCAL_SET_GL_ERROR(error, "GetActiveUniformBlockiv", "");
9853 }
9854 return error::kNoError;
9855}
9856
zmo4a16ff992015-02-05 22:18:419857error::Error GLES2DecoderImpl::HandleGetActiveUniformBlockName(
9858 uint32 immediate_data_size, const void* cmd_data) {
9859 if (!unsafe_es3_apis_enabled())
9860 return error::kUnknownCommand;
9861 const gles2::cmds::GetActiveUniformBlockName& c =
9862 *static_cast<const gles2::cmds::GetActiveUniformBlockName*>(cmd_data);
9863 GLuint program_id = c.program;
9864 GLuint index = c.index;
9865 uint32 name_bucket_id = c.name_bucket_id;
9866 typedef cmds::GetActiveUniformBlockName::Result Result;
9867 Result* result = GetSharedMemoryAs<Result*>(
9868 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9869 if (!result) {
9870 return error::kOutOfBounds;
9871 }
9872 // Check that the client initialized the result.
9873 if (*result != 0) {
9874 return error::kInvalidArguments;
9875 }
9876 Program* program = GetProgramInfoNotShader(
9877 program_id, "glGetActiveUniformBlockName");
9878 if (!program) {
9879 return error::kNoError;
9880 }
9881 GLuint service_id = program->service_id();
9882 GLint link_status = GL_FALSE;
9883 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
9884 if (link_status != GL_TRUE) {
9885 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
9886 "glGetActiveActiveUniformBlockName", "program not linked");
9887 return error::kNoError;
9888 }
9889 GLint max_length = 0;
9890 glGetProgramiv(
9891 service_id, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &max_length);
9892 // Increase one so &buffer[0] is always valid.
9893 GLsizei buf_size = static_cast<GLsizei>(max_length) + 1;
9894 std::vector<char> buffer(buf_size);
9895 GLsizei length = 0;
9896 glGetActiveUniformBlockName(
9897 service_id, index, buf_size, &length, &buffer[0]);
9898 if (length == 0) {
9899 *result = 0;
9900 return error::kNoError;
9901 }
9902 *result = 1;
9903 Bucket* bucket = CreateBucket(name_bucket_id);
9904 DCHECK_GT(buf_size, length);
9905 DCHECK_EQ(0, buffer[length]);
9906 bucket->SetFromString(&buffer[0]);
9907 return error::kNoError;
9908}
9909
zmoc7e7e13f2015-02-17 22:07:079910error::Error GLES2DecoderImpl::HandleGetActiveUniformsiv(
9911 uint32 immediate_data_size, const void* cmd_data) {
9912 if (!unsafe_es3_apis_enabled())
9913 return error::kUnknownCommand;
9914 const gles2::cmds::GetActiveUniformsiv& c =
9915 *static_cast<const gles2::cmds::GetActiveUniformsiv*>(cmd_data);
9916 GLuint program_id = c.program;
9917 GLenum pname = static_cast<GLenum>(c.pname);
9918 Bucket* bucket = GetBucket(c.indices_bucket_id);
9919 if (!bucket) {
9920 return error::kInvalidArguments;
9921 }
9922 GLsizei count = static_cast<GLsizei>(bucket->size() / sizeof(GLuint));
9923 const GLuint* indices = bucket->GetDataAs<const GLuint*>(0, bucket->size());
9924 typedef cmds::GetActiveUniformsiv::Result Result;
9925 Result* result = GetSharedMemoryAs<Result*>(
9926 c.params_shm_id, c.params_shm_offset, Result::ComputeSize(count));
9927 GLint* params = result ? result->GetData() : NULL;
9928 if (params == NULL) {
9929 return error::kOutOfBounds;
9930 }
9931 // Check that the client initialized the result.
9932 if (result->size != 0) {
9933 return error::kInvalidArguments;
9934 }
9935 Program* program = GetProgramInfoNotShader(
9936 program_id, "glGetActiveUniformsiv");
9937 if (!program) {
9938 return error::kNoError;
9939 }
9940 GLuint service_id = program->service_id();
9941 GLint link_status = GL_FALSE;
9942 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
9943 if (link_status != GL_TRUE) {
9944 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
9945 "glGetActiveUniformsiv", "program not linked");
9946 return error::kNoError;
9947 }
9948 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetActiveUniformsiv");
9949 glGetActiveUniformsiv(service_id, count, indices, pname, params);
9950 GLenum error = glGetError();
9951 if (error == GL_NO_ERROR) {
9952 result->SetNumResults(count);
9953 } else {
9954 LOCAL_SET_GL_ERROR(error, "GetActiveUniformsiv", "");
9955 }
9956 return error::kNoError;
9957}
9958
vmiuracd108592014-09-08 14:36:349959error::Error GLES2DecoderImpl::HandleGetActiveAttrib(uint32 immediate_data_size,
9960 const void* cmd_data) {
9961 const gles2::cmds::GetActiveAttrib& c =
9962 *static_cast<const gles2::cmds::GetActiveAttrib*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429963 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:259964 GLuint index = c.index;
9965 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:359966 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:259967 Result* result = GetSharedMemoryAs<Result*>(
9968 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9969 if (!result) {
9970 return error::kOutOfBounds;
9971 }
[email protected]07d0cc82010-02-17 04:51:409972 // Check that the client initialized the result.
9973 if (result->success != 0) {
9974 return error::kInvalidArguments;
9975 }
[email protected]df37b9932013-03-08 05:21:429976 Program* program = GetProgramInfoNotShader(
9977 program_id, "glGetActiveAttrib");
9978 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259979 return error::kNoError;
9980 }
[email protected]ed9f9cd2013-02-27 21:12:359981 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:429982 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:259983 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:519984 LOCAL_SET_GL_ERROR(
9985 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:259986 return error::kNoError;
9987 }
9988 result->success = 1; // true.
9989 result->size = attrib_info->size;
9990 result->type = attrib_info->type;
9991 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:299992 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:149993 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329994}
9995
vmiuracd108592014-09-08 14:36:349996error::Error GLES2DecoderImpl::HandleShaderBinary(uint32 immediate_data_size,
9997 const void* cmd_data) {
[email protected]b273e432010-04-12 17:23:589998#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:519999 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:5810000 return error::kNoError;
10001#else
10002 GLsizei n = static_cast<GLsizei>(c.n);
10003 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:5110004 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:5810005 return error::kNoError;
10006 }
10007 GLsizei length = static_cast<GLsizei>(c.length);
10008 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:5110009 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:5810010 return error::kNoError;
10011 }
10012 uint32 data_size;
10013 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
10014 return error::kOutOfBounds;
10015 }
10016 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
10017 c.shaders_shm_id, c.shaders_shm_offset, data_size);
10018 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
10019 const void* binary = GetSharedMemoryAs<const void*>(
10020 c.binary_shm_id, c.binary_shm_offset, length);
10021 if (shaders == NULL || binary == NULL) {
10022 return error::kOutOfBounds;
10023 }
[email protected]0782b14b2014-05-24 13:04:1610024 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]b273e432010-04-12 17:23:5810025 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:4210026 Shader* shader = GetShader(shaders[ii]);
10027 if (!shader) {
[email protected]ab09b612013-03-11 22:11:5110028 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:5810029 return error::kNoError;
10030 }
[email protected]df37b9932013-03-08 05:21:4210031 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:5810032 }
10033 // TODO(gman): call glShaderBinary
10034 return error::kNoError;
10035#endif
10036}
10037
[email protected]6d792ee12013-05-15 00:40:5610038void GLES2DecoderImpl::DoSwapBuffers() {
[email protected]64ace852011-05-19 21:49:4910039 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:0810040
[email protected]64ace852011-05-19 21:49:4910041 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:4210042 // TRACE_EVENT for gpu tests:
10043 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:4210044 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:4210045 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
10046 "width", (is_offscreen ? offscreen_size_.width() :
10047 surface_->GetSize().width()));
[email protected]6d792ee12013-05-15 00:40:5610048 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
[email protected]64ace852011-05-19 21:49:4910049 "offscreen", is_offscreen,
10050 "frame", this_frame_number);
[email protected]b2e92592014-01-10 15:47:1510051 {
[email protected]a36ed4832014-04-24 16:40:2710052 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
[email protected]b2e92592014-01-10 15:47:1510053 }
10054
dyenb547eff62015-01-17 00:14:5610055 ScopedGPUTrace scoped_gpu_trace(gpu_tracer_.get(), kTraceDecoder,
10056 "gpu_toplevel", "SwapBuffer");
10057
[email protected]8f9b8dd2013-09-12 18:05:1310058 bool is_tracing;
10059 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
10060 &is_tracing);
10061 if (is_tracing) {
10062 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
10063 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
10064 is_offscreen ? offscreen_size_ : surface_->GetSize());
10065 }
10066
[email protected]6217d392010-03-25 22:08:3510067 // If offscreen then don't actually SwapBuffers to the display. Just copy
10068 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:4910069 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:3110070 TRACE_EVENT2("gpu", "Offscreen",
10071 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:5310072 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
10073 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
10074 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
10075 // fix this.
[email protected]62e155e2012-10-23 22:43:1510076 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:5310077 offscreen_saved_frame_buffer_->Create();
10078 glFinish();
10079 }
10080
10081 // Allocate the offscreen saved color texture.
10082 DCHECK(offscreen_saved_color_format_);
10083 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:0910084 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:5310085
10086 offscreen_saved_frame_buffer_->AttachRenderTexture(
10087 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:0510088 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
10089 if (offscreen_saved_frame_buffer_->CheckStatus() !=
10090 GL_FRAMEBUFFER_COMPLETE) {
10091 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
10092 << "because offscreen saved FBO was incomplete.";
[email protected]6d792ee12013-05-15 00:40:5610093 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
10094 return;
[email protected]f0cfe752013-01-14 01:09:0510095 }
[email protected]1fb8c482011-08-31 01:01:5310096
[email protected]f0cfe752013-01-14 01:09:0510097 // Clear the offscreen color texture.
10098 // TODO(piman): Is this still necessary?
10099 {
10100 ScopedFrameBufferBinder binder(this,
10101 offscreen_saved_frame_buffer_->id());
10102 glClearColor(0, 0, 0, 0);
[email protected]454157e2014-05-03 02:49:4510103 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
10104 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f0cfe752013-01-14 01:09:0510105 glClear(GL_COLOR_BUFFER_BIT);
10106 RestoreClearState();
10107 }
[email protected]1fb8c482011-08-31 01:01:5310108 }
10109
10110 UpdateParentTextureInfo();
10111 }
10112
[email protected]f0cfe752013-01-14 01:09:0510113 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
[email protected]6d792ee12013-05-15 00:40:5610114 return;
[email protected]ab09b612013-03-11 22:11:5110115 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010116 "GLES2DecoderImpl::DoSwapBuffers", GetErrorState());
[email protected]6217d392010-03-25 22:08:3510117
[email protected]34ff8b0c2010-10-01 20:06:0210118 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:1310119 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:2710120 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]b86b14982010-10-11 18:45:4810121 } else {
[email protected]069944672012-04-25 20:52:2310122 ScopedFrameBufferBinder binder(this,
10123 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:1310124
[email protected]069944672012-04-25 20:52:2310125 if (offscreen_target_buffer_preserved_) {
10126 // Copy the target frame buffer to the saved offscreen texture.
10127 offscreen_saved_color_texture_->Copy(
10128 offscreen_saved_color_texture_->size(),
10129 offscreen_saved_color_format_);
10130 } else {
10131 // Flip the textures in the parent context via the texture manager.
10132 if (!!offscreen_saved_color_texture_info_.get())
[email protected]370eaf12013-05-18 09:19:4910133 offscreen_saved_color_texture_info_->texture()->
[email protected]069944672012-04-25 20:52:2310134 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:5610135
[email protected]069944672012-04-25 20:52:2310136 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
10137 offscreen_target_frame_buffer_->AttachRenderTexture(
10138 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:4810139 }
[email protected]069944672012-04-25 20:52:2310140
10141 // Ensure the side effects of the copy are visible to the parent
10142 // context. There is no need to do this for ANGLE because it uses a
10143 // single D3D device for all contexts.
zmo68fcdc62014-12-05 21:51:4910144 if (!feature_info_->gl_version_info().is_angle)
[email protected]069944672012-04-25 20:52:2310145 glFlush();
[email protected]0c8c9d22010-06-25 17:36:3910146 }
[email protected]6217d392010-03-25 22:08:3510147 } else {
[email protected]f62a5ab2011-05-23 20:34:1510148 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:0110149 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]6d792ee12013-05-15 00:40:5610150 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]d0498742010-09-20 20:27:0110151 }
[email protected]6217d392010-03-25 22:08:3510152 }
vmiura8266ca72014-09-09 21:37:0010153
10154 // This may be a slow command. Exit command processing to allow for
10155 // context preemption and GPU watchdog checks.
10156 ExitCommandProcessingEarly();
[email protected]6217d392010-03-25 22:08:3510157}
10158
bajones2345c1f2014-12-09 04:45:5110159void GLES2DecoderImpl::DoSwapInterval(int interval)
10160{
10161 context_->SetSwapInterval(interval);
10162}
10163
[email protected]d4239852011-08-12 04:51:2210164error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
vmiuracd108592014-09-08 14:36:3410165 uint32 immediate_data_size,
10166 const void* cmd_data) {
10167 const gles2::cmds::EnableFeatureCHROMIUM& c =
10168 *static_cast<const gles2::cmds::EnableFeatureCHROMIUM*>(cmd_data);
[email protected]b1d2dcb2010-05-17 19:24:1810169 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:2810170 if (!bucket || bucket->size() == 0) {
10171 return error::kInvalidArguments;
10172 }
[email protected]ed9f9cd2013-02-27 21:12:3510173 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:1810174 Result* result = GetSharedMemoryAs<Result*>(
10175 c.result_shm_id, c.result_shm_offset, sizeof(*result));
10176 if (!result) {
10177 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:1010178 }
[email protected]b1d2dcb2010-05-17 19:24:1810179 // Check that the client initialized the result.
10180 if (*result != 0) {
10181 return error::kInvalidArguments;
10182 }
10183 std::string feature_str;
10184 if (!bucket->GetAsString(&feature_str)) {
10185 return error::kInvalidArguments;
10186 }
10187
10188 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:2210189 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:1810190 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:2210191 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
penghuang0140c182015-01-12 23:20:1210192 buffer_manager()->set_allow_fixed_attribs(true);
[email protected]8fbedc02010-11-18 18:43:4010193 // TODO(gman): decide how to remove the need for this const_cast.
10194 // I could make validators_ non const but that seems bad as this is the only
10195 // place it is needed. I could make some special friend class of validators
10196 // just to allow this to set them. That seems silly. I could refactor this
10197 // code to use the extension mechanism or the initialization attributes to
10198 // turn this feature on. Given that the only real point of this is to make
10199 // the conformance tests pass and given that there is lots of real work that
10200 // needs to be done it seems like refactoring for one to one of those
10201 // methods is a very low priority.
10202 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:0410203 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
10204 force_webgl_glsl_validation_ = true;
10205 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:1810206 } else {
10207 return error::kNoError;
10208 }
10209
10210 *result = 1; // true.
10211 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:1010212}
10213
[email protected]c2f8c8402010-12-06 18:07:2410214error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
10215 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:3410216 const void* cmd_data) {
10217 const gles2::cmds::GetRequestableExtensionsCHROMIUM& c =
10218 *static_cast<const gles2::cmds::GetRequestableExtensionsCHROMIUM*>(
10219 cmd_data);
[email protected]c2f8c8402010-12-06 18:07:2410220 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:3510221 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]956aec52013-09-05 15:41:1910222 info->Initialize(disallowed_features_);
[email protected]c2f8c8402010-12-06 18:07:2410223 bucket->SetFromString(info->extensions().c_str());
10224 return error::kNoError;
10225}
10226
10227error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
vmiuracd108592014-09-08 14:36:3410228 uint32 immediate_data_size,
10229 const void* cmd_data) {
10230 const gles2::cmds::RequestExtensionCHROMIUM& c =
10231 *static_cast<const gles2::cmds::RequestExtensionCHROMIUM*>(cmd_data);
[email protected]c2f8c8402010-12-06 18:07:2410232 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:2810233 if (!bucket || bucket->size() == 0) {
10234 return error::kInvalidArguments;
10235 }
[email protected]c2f8c8402010-12-06 18:07:2410236 std::string feature_str;
10237 if (!bucket->GetAsString(&feature_str)) {
10238 return error::kInvalidArguments;
10239 }
10240
[email protected]4b7eba92013-01-08 02:23:5610241 bool desire_webgl_glsl_validation =
10242 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
10243 bool desire_standard_derivatives = false;
[email protected]70dc60932013-06-04 03:33:4910244 bool desire_frag_depth = false;
[email protected]aff39ac82013-06-08 04:53:1310245 bool desire_draw_buffers = false;
[email protected]93c2fd82014-04-16 02:46:0610246 bool desire_shader_texture_lod = false;
[email protected]4b7eba92013-01-08 02:23:5610247 if (force_webgl_glsl_validation_) {
10248 desire_standard_derivatives =
10249 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]70dc60932013-06-04 03:33:4910250 desire_frag_depth =
10251 feature_str.find("GL_EXT_frag_depth") != std::string::npos;
[email protected]aff39ac82013-06-08 04:53:1310252 desire_draw_buffers =
10253 feature_str.find("GL_EXT_draw_buffers") != std::string::npos;
[email protected]93c2fd82014-04-16 02:46:0610254 desire_shader_texture_lod =
10255 feature_str.find("GL_EXT_shader_texture_lod") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:0410256 }
10257
[email protected]4b7eba92013-01-08 02:23:5610258 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
[email protected]70dc60932013-06-04 03:33:4910259 desire_standard_derivatives != derivatives_explicitly_enabled_ ||
[email protected]aff39ac82013-06-08 04:53:1310260 desire_frag_depth != frag_depth_explicitly_enabled_ ||
10261 desire_draw_buffers != draw_buffers_explicitly_enabled_) {
[email protected]70dc60932013-06-04 03:33:4910262 force_webgl_glsl_validation_ |= desire_webgl_glsl_validation;
10263 derivatives_explicitly_enabled_ |= desire_standard_derivatives;
10264 frag_depth_explicitly_enabled_ |= desire_frag_depth;
[email protected]aff39ac82013-06-08 04:53:1310265 draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
[email protected]93c2fd82014-04-16 02:46:0610266 shader_texture_lod_explicitly_enabled_ |= desire_shader_texture_lod;
[email protected]c2f8c8402010-12-06 18:07:2410267 InitializeShaderTranslator();
10268 }
10269
[email protected]302ce6d2011-07-07 23:28:1110270 UpdateCapabilities();
10271
[email protected]c2f8c8402010-12-06 18:07:2410272 return error::kNoError;
10273}
10274
[email protected]2318d342011-07-11 22:27:4210275error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
vmiuracd108592014-09-08 14:36:3410276 uint32 immediate_data_size,
10277 const void* cmd_data) {
10278 const gles2::cmds::GetProgramInfoCHROMIUM& c =
10279 *static_cast<const gles2::cmds::GetProgramInfoCHROMIUM*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:4210280 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:4210281 uint32 bucket_id = c.bucket_id;
10282 Bucket* bucket = CreateBucket(bucket_id);
10283 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:4210284 Program* program = NULL;
10285 program = GetProgram(program_id);
10286 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:4610287 return error::kNoError;
[email protected]2318d342011-07-11 22:27:4210288 }
[email protected]df37b9932013-03-08 05:21:4210289 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:4210290 return error::kNoError;
10291}
10292
zmo4a16ff992015-02-05 22:18:4110293error::Error GLES2DecoderImpl::HandleGetUniformBlocksCHROMIUM(
10294 uint32 immediate_data_size, const void* cmd_data) {
10295 if (!unsafe_es3_apis_enabled())
10296 return error::kUnknownCommand;
10297 const gles2::cmds::GetUniformBlocksCHROMIUM& c =
10298 *static_cast<const gles2::cmds::GetUniformBlocksCHROMIUM*>(cmd_data);
10299 GLuint program_id = static_cast<GLuint>(c.program);
10300 uint32 bucket_id = c.bucket_id;
10301 Bucket* bucket = CreateBucket(bucket_id);
10302 bucket->SetSize(sizeof(UniformBlocksHeader)); // in case we fail.
10303 Program* program = NULL;
10304 program = GetProgram(program_id);
10305 if (!program || !program->IsValid()) {
10306 return error::kNoError;
10307 }
10308 program->GetUniformBlocks(bucket);
10309 return error::kNoError;
10310}
10311
zmoc7e7e13f2015-02-17 22:07:0710312error::Error GLES2DecoderImpl::HandleGetUniformsES3CHROMIUM(
10313 uint32 immediate_data_size, const void* cmd_data) {
10314 if (!unsafe_es3_apis_enabled())
10315 return error::kUnknownCommand;
10316 const gles2::cmds::GetUniformsES3CHROMIUM& c =
10317 *static_cast<const gles2::cmds::GetUniformsES3CHROMIUM*>(cmd_data);
10318 GLuint program_id = static_cast<GLuint>(c.program);
10319 uint32 bucket_id = c.bucket_id;
10320 Bucket* bucket = CreateBucket(bucket_id);
10321 bucket->SetSize(sizeof(UniformsES3Header)); // in case we fail.
10322 Program* program = NULL;
10323 program = GetProgram(program_id);
10324 if (!program || !program->IsValid()) {
10325 return error::kNoError;
10326 }
10327 program->GetUniformsES3(bucket);
10328 return error::kNoError;
10329}
10330
zmo10842492015-02-12 00:44:1610331error::Error GLES2DecoderImpl::HandleGetTransformFeedbackVarying(
10332 uint32 immediate_data_size,
10333 const void* cmd_data) {
10334 if (!unsafe_es3_apis_enabled())
10335 return error::kUnknownCommand;
10336 const gles2::cmds::GetTransformFeedbackVarying& c =
10337 *static_cast<const gles2::cmds::GetTransformFeedbackVarying*>(cmd_data);
10338 GLuint program_id = c.program;
10339 GLuint index = c.index;
10340 uint32 name_bucket_id = c.name_bucket_id;
10341 typedef cmds::GetTransformFeedbackVarying::Result Result;
10342 Result* result = GetSharedMemoryAs<Result*>(
10343 c.result_shm_id, c.result_shm_offset, sizeof(*result));
10344 if (!result) {
10345 return error::kOutOfBounds;
10346 }
10347 // Check that the client initialized the result.
10348 if (result->success != 0) {
10349 return error::kInvalidArguments;
10350 }
10351 Program* program = GetProgramInfoNotShader(
10352 program_id, "glGetTransformFeedbackVarying");
10353 if (!program) {
10354 return error::kNoError;
10355 }
10356 GLuint service_id = program->service_id();
10357 GLint link_status = GL_FALSE;
10358 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
10359 if (link_status != GL_TRUE) {
10360 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10361 "glGetTransformFeedbackVarying", "program not linked");
10362 return error::kNoError;
10363 }
10364 GLint max_length = 0;
10365 glGetProgramiv(
10366 service_id, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &max_length);
10367 max_length = std::max(1, max_length);
10368 std::vector<char> buffer(max_length);
10369 GLsizei length = 0;
10370 GLsizei size = 0;
10371 GLenum type = 0;
10372 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetTransformFeedbackVarying");
10373 glGetTransformFeedbackVarying(
10374 service_id, index, max_length, &length, &size, &type, &buffer[0]);
10375 GLenum error = glGetError();
10376 if (error != GL_NO_ERROR) {
10377 LOCAL_SET_GL_ERROR(error, "glGetTransformFeedbackVarying", "");
10378 return error::kNoError;
10379 }
10380 result->success = 1; // true.
10381 result->size = static_cast<int32_t>(size);
10382 result->type = static_cast<uint32_t>(type);
10383 Bucket* bucket = CreateBucket(name_bucket_id);
10384 DCHECK(length >= 0 && length < max_length);
10385 buffer[length] = '\0'; // Just to be safe.
10386 bucket->SetFromString(&buffer[0]);
10387 return error::kNoError;
10388}
10389
10390error::Error GLES2DecoderImpl::HandleGetTransformFeedbackVaryingsCHROMIUM(
10391 uint32 immediate_data_size, const void* cmd_data) {
10392 if (!unsafe_es3_apis_enabled())
10393 return error::kUnknownCommand;
10394 const gles2::cmds::GetTransformFeedbackVaryingsCHROMIUM& c =
10395 *static_cast<const gles2::cmds::GetTransformFeedbackVaryingsCHROMIUM*>(
10396 cmd_data);
10397 GLuint program_id = static_cast<GLuint>(c.program);
10398 uint32 bucket_id = c.bucket_id;
10399 Bucket* bucket = CreateBucket(bucket_id);
10400 bucket->SetSize(sizeof(TransformFeedbackVaryingsHeader)); // in case we fail.
10401 Program* program = NULL;
10402 program = GetProgram(program_id);
10403 if (!program || !program->IsValid()) {
10404 return error::kNoError;
10405 }
10406 program->GetTransformFeedbackVaryings(bucket);
10407 return error::kNoError;
10408}
10409
[email protected]38d139d2011-07-14 00:38:4310410error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
10411 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:4310412 case GL_NO_ERROR:
10413 // TODO(kbr): improve the precision of the error code in this case.
10414 // Consider delegating to context for error code if MakeCurrent fails.
10415 return error::kUnknown;
10416 case GL_GUILTY_CONTEXT_RESET_ARB:
10417 return error::kGuilty;
10418 case GL_INNOCENT_CONTEXT_RESET_ARB:
10419 return error::kInnocent;
10420 case GL_UNKNOWN_CONTEXT_RESET_ARB:
10421 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:4310422 }
10423
10424 NOTREACHED();
10425 return error::kUnknown;
10426}
10427
jbauman7a059312014-10-16 19:30:5410428void GLES2DecoderImpl::MaybeExitOnContextLost() {
10429 // Some D3D drivers cannot recover from device lost in the GPU process
10430 // sandbox. Allow a new GPU process to launch.
10431 if (workarounds().exit_on_context_lost) {
10432 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
10433 << " a D3D device in the Chrome GPU process sandbox.";
10434#if defined(OS_WIN)
10435 base::win::SetShouldCrashOnProcessDetach(false);
10436#endif
10437 exit(0);
10438 }
10439}
10440
[email protected]38d139d2011-07-14 00:38:4310441bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:0910442 if (reset_status_ != GL_NO_ERROR) {
jbauman7a059312014-10-16 19:30:5410443 MaybeExitOnContextLost();
[email protected]c4485aad62012-12-17 10:19:0910444 return true;
10445 }
dongseong.hwange1cb2aa2015-02-11 09:33:3310446 if (IsRobustnessSupported()) {
10447 GLenum status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:4310448 if (status != GL_NO_ERROR) {
10449 // The graphics card was reset. Signal a lost context to the application.
10450 reset_status_ = status;
[email protected]93a7d98f2013-07-11 00:04:2210451 reset_by_robustness_extension_ = true;
[email protected]38d139d2011-07-14 00:38:4310452 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:0910453 << " context lost via ARB/EXT_robustness. Reset status = "
10454 << GLES2Util::GetStringEnum(status);
jbauman7a059312014-10-16 19:30:5410455 MaybeExitOnContextLost();
[email protected]38d139d2011-07-14 00:38:4310456 return true;
10457 }
10458 }
10459 return false;
10460}
10461
[email protected]93a7d98f2013-07-11 00:04:2210462bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() {
10463 return WasContextLost() && reset_by_robustness_extension_;
10464}
10465
[email protected]c4485aad62012-12-17 10:19:0910466void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
10467 // Only loses the context once.
10468 if (reset_status_ != GL_NO_ERROR) {
10469 return;
10470 }
10471
oetuaho37cc50e2014-10-31 11:19:2010472 if (workarounds().use_virtualized_gl_contexts) {
10473 // If the context is virtual, the real context being guilty does not ensure
10474 // that the virtual context is guilty.
10475 if (reset_status == GL_GUILTY_CONTEXT_RESET_ARB) {
10476 reset_status = GL_UNKNOWN_CONTEXT_RESET_ARB;
10477 }
10478 } else if (reset_status == GL_UNKNOWN_CONTEXT_RESET_ARB &&
dongseong.hwange1cb2aa2015-02-11 09:33:3310479 IsRobustnessSupported()) {
oetuaho37cc50e2014-10-31 11:19:2010480 // If the reason for the call was a GL error, we can try to determine the
10481 // reset status more accurately.
10482 GLenum driver_status = glGetGraphicsResetStatusARB();
10483 if (driver_status == GL_GUILTY_CONTEXT_RESET_ARB ||
10484 driver_status == GL_INNOCENT_CONTEXT_RESET_ARB) {
10485 reset_status = driver_status;
10486 }
10487 }
10488
[email protected]c4485aad62012-12-17 10:19:0910489 // Marks this context as lost.
10490 reset_status_ = reset_status;
10491 current_decoder_error_ = error::kLostContext;
[email protected]c4485aad62012-12-17 10:19:0910492}
10493
[email protected]b096d032013-03-08 03:08:0110494error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:3410495 uint32 immediate_data_size,
10496 const void* cmd_data) {
[email protected]b096d032013-03-08 03:08:0110497 return error::kUnknownCommand;
10498}
10499
[email protected]840a7e462013-02-27 01:29:5110500error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:3410501 uint32 immediate_data_size,
10502 const void* cmd_data) {
10503 const gles2::cmds::WaitSyncPointCHROMIUM& c =
10504 *static_cast<const gles2::cmds::WaitSyncPointCHROMIUM*>(cmd_data);
sievers173a20d2014-10-22 18:19:3210505 uint32 sync_point = c.sync_point;
[email protected]840a7e462013-02-27 01:29:5110506 if (wait_sync_point_callback_.is_null())
10507 return error::kNoError;
10508
sievers173a20d2014-10-22 18:19:3210509 return wait_sync_point_callback_.Run(sync_point) ?
[email protected]840a7e462013-02-27 01:29:5110510 error::kNoError : error::kDeferCommandUntilLater;
10511}
10512
[email protected]5dfc457b2013-12-13 11:13:0710513error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM(
vmiuracd108592014-09-08 14:36:3410514 uint32 immediate_data_size,
10515 const void* cmd_data) {
[email protected]5dfc457b2013-12-13 11:13:0710516 if (surface_->DeferDraws())
10517 return error::kDeferCommandUntilLater;
10518 if (!surface_->SetBackbufferAllocation(false))
10519 return error::kLostContext;
10520 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
10521 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
10522 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
10523 return error::kNoError;
10524}
10525
[email protected]882ba1e22012-03-08 19:02:5310526bool GLES2DecoderImpl::GenQueriesEXTHelper(
10527 GLsizei n, const GLuint* client_ids) {
10528 for (GLsizei ii = 0; ii < n; ++ii) {
10529 if (query_manager_->GetQuery(client_ids[ii])) {
10530 return false;
10531 }
10532 }
[email protected]4eea7e62014-04-22 21:14:4310533 query_manager_->GenQueries(n, client_ids);
[email protected]882ba1e22012-03-08 19:02:5310534 return true;
10535}
10536
10537void GLES2DecoderImpl::DeleteQueriesEXTHelper(
10538 GLsizei n, const GLuint* client_ids) {
10539 for (GLsizei ii = 0; ii < n; ++ii) {
10540 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
10541 if (query && !query->IsDeleted()) {
[email protected]8ebd46c2014-01-08 12:06:1310542 ContextState::QueryMap::iterator it =
10543 state_.current_queries.find(query->target());
10544 if (it != state_.current_queries.end())
10545 state_.current_queries.erase(it);
10546
[email protected]c45f1972012-03-14 07:27:3610547 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:5310548 }
[email protected]4eea7e62014-04-22 21:14:4310549 query_manager_->RemoveQuery(client_ids[ii]);
[email protected]882ba1e22012-03-08 19:02:5310550 }
10551}
10552
revemancc241eb2014-11-11 03:30:3710553bool GLES2DecoderImpl::ProcessPendingQueries(bool did_finish) {
[email protected]22e3f552012-03-13 01:54:1910554 if (query_manager_.get() == NULL) {
10555 return false;
10556 }
revemancc241eb2014-11-11 03:30:3710557 if (!query_manager_->ProcessPendingQueries(did_finish)) {
[email protected]22e3f552012-03-13 01:54:1910558 current_decoder_error_ = error::kOutOfBounds;
10559 }
10560 return query_manager_->HavePendingQueries();
10561}
10562
[email protected]5a36dc132013-07-23 23:17:5510563// Note that if there are no pending readpixels right now,
10564// this function will call the callback immediately.
10565void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) {
10566 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) {
10567 pending_readpixel_fences_.back()->callbacks.push_back(callback);
10568 } else {
10569 callback.Run();
10570 }
10571}
10572
10573void GLES2DecoderImpl::ProcessPendingReadPixels() {
10574 while (!pending_readpixel_fences_.empty() &&
10575 pending_readpixel_fences_.front()->fence->HasCompleted()) {
10576 std::vector<base::Closure> callbacks =
10577 pending_readpixel_fences_.front()->callbacks;
10578 pending_readpixel_fences_.pop();
10579 for (size_t i = 0; i < callbacks.size(); i++) {
10580 callbacks[i].Run();
10581 }
10582 }
10583}
10584
[email protected]2b1767cf2013-03-16 09:25:0510585bool GLES2DecoderImpl::HasMoreIdleWork() {
[email protected]5a36dc132013-07-23 23:17:5510586 return !pending_readpixel_fences_.empty() ||
10587 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:0510588}
10589
10590void GLES2DecoderImpl::PerformIdleWork() {
[email protected]5a36dc132013-07-23 23:17:5510591 ProcessPendingReadPixels();
[email protected]b68b100752013-06-05 08:34:4810592 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
[email protected]2b1767cf2013-03-16 09:25:0510593 return;
[email protected]b68b100752013-06-05 08:34:4810594 async_pixel_transfer_manager_->ProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:0510595 ProcessFinishedAsyncTransfers();
10596}
10597
vmiuracd108592014-09-08 14:36:3410598error::Error GLES2DecoderImpl::HandleBeginQueryEXT(uint32 immediate_data_size,
10599 const void* cmd_data) {
10600 const gles2::cmds::BeginQueryEXT& c =
10601 *static_cast<const gles2::cmds::BeginQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:5310602 GLenum target = static_cast<GLenum>(c.target);
10603 GLuint client_id = static_cast<GLuint>(c.id);
10604 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
10605 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
10606
[email protected]c45f1972012-03-14 07:27:3610607 switch (target) {
10608 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:5510609 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]5537605d2013-08-27 05:22:3110610 case GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM:
10611 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:0010612 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:3610613 break;
[email protected]6a25ae422014-04-17 23:48:2710614 case GL_COMMANDS_COMPLETED_CHROMIUM:
10615 if (!features().chromium_sync_query) {
10616 LOCAL_SET_GL_ERROR(
10617 GL_INVALID_OPERATION, "glBeginQueryEXT",
10618 "not enabled for commands completed queries");
10619 return error::kNoError;
10620 }
10621 break;
[email protected]c45f1972012-03-14 07:27:3610622 default:
[email protected]62e155e2012-10-23 22:43:1510623 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:5110624 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:0010625 GL_INVALID_OPERATION, "glBeginQueryEXT",
10626 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:3610627 return error::kNoError;
10628 }
10629 break;
[email protected]882ba1e22012-03-08 19:02:5310630 }
10631
[email protected]8ebd46c2014-01-08 12:06:1310632 if (state_.current_queries.find(target) != state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:5110633 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310634 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:5310635 return error::kNoError;
10636 }
10637
10638 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:5110639 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:5310640 return error::kNoError;
10641 }
10642
10643 QueryManager::Query* query = query_manager_->GetQuery(client_id);
10644 if (!query) {
[email protected]4eea7e62014-04-22 21:14:4310645 if (!query_manager_->IsValidQuery(client_id)) {
10646 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10647 "glBeginQueryEXT",
10648 "id not made by glGenQueriesEXT");
10649 return error::kNoError;
10650 }
[email protected]c45f1972012-03-14 07:27:3610651 query = query_manager_->CreateQuery(
10652 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:5310653 }
10654
[email protected]c45f1972012-03-14 07:27:3610655 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:5110656 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310657 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:5310658 return error::kNoError;
10659 } else if (query->shm_id() != sync_shm_id ||
10660 query->shm_offset() != sync_shm_offset) {
10661 DLOG(ERROR) << "Shared memory used by query not the same as before";
10662 return error::kInvalidArguments;
10663 }
10664
[email protected]c45f1972012-03-14 07:27:3610665 if (!query_manager_->BeginQuery(query)) {
10666 return error::kOutOfBounds;
10667 }
[email protected]882ba1e22012-03-08 19:02:5310668
[email protected]8ebd46c2014-01-08 12:06:1310669 state_.current_queries[target] = query;
[email protected]882ba1e22012-03-08 19:02:5310670 return error::kNoError;
10671}
10672
vmiuracd108592014-09-08 14:36:3410673error::Error GLES2DecoderImpl::HandleEndQueryEXT(uint32 immediate_data_size,
10674 const void* cmd_data) {
10675 const gles2::cmds::EndQueryEXT& c =
10676 *static_cast<const gles2::cmds::EndQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:5310677 GLenum target = static_cast<GLenum>(c.target);
10678 uint32 submit_count = static_cast<GLuint>(c.submit_count);
[email protected]8ebd46c2014-01-08 12:06:1310679 ContextState::QueryMap::iterator it = state_.current_queries.find(target);
[email protected]882ba1e22012-03-08 19:02:5310680
[email protected]8ebd46c2014-01-08 12:06:1310681 if (it == state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:5110682 LOCAL_SET_GL_ERROR(
10683 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:5310684 return error::kNoError;
10685 }
[email protected]882ba1e22012-03-08 19:02:5310686
[email protected]8ebd46c2014-01-08 12:06:1310687 QueryManager::Query* query = it->second.get();
10688 if (!query_manager_->EndQuery(query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:3610689 return error::kOutOfBounds;
10690 }
10691
[email protected]fe8d73c2013-02-16 22:37:3210692 query_manager_->ProcessPendingTransferQueries();
10693
[email protected]8ebd46c2014-01-08 12:06:1310694 state_.current_queries.erase(it);
[email protected]882ba1e22012-03-08 19:02:5310695 return error::kNoError;
10696}
10697
[email protected]944b62f32012-09-27 02:20:4610698bool GLES2DecoderImpl::GenVertexArraysOESHelper(
10699 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:4610700 for (GLsizei ii = 0; ii < n; ++ii) {
10701 if (GetVertexAttribManager(client_ids[ii])) {
10702 return false;
10703 }
10704 }
[email protected]ab4fd7282012-10-12 16:25:5710705
[email protected]62e155e2012-10-23 22:43:1510706 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:5710707 // Emulated VAO
10708 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:4810709 CreateVertexAttribManager(client_ids[ii], 0, true);
[email protected]ab4fd7282012-10-12 16:25:5710710 }
10711 } else {
[email protected]40d90a22013-04-09 03:39:5510712 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:5710713
10714 glGenVertexArraysOES(n, service_ids.get());
10715 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:4810716 CreateVertexAttribManager(client_ids[ii], service_ids[ii], true);
[email protected]ab4fd7282012-10-12 16:25:5710717 }
[email protected]944b62f32012-09-27 02:20:4610718 }
[email protected]ab4fd7282012-10-12 16:25:5710719
[email protected]944b62f32012-09-27 02:20:4610720 return true;
10721}
10722
10723void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
10724 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:4610725 for (GLsizei ii = 0; ii < n; ++ii) {
10726 VertexAttribManager* vao =
10727 GetVertexAttribManager(client_ids[ii]);
10728 if (vao && !vao->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:1110729 if (state_.vertex_attrib_manager.get() == vao) {
[email protected]242c9822014-04-15 21:36:1110730 DoBindVertexArrayOES(0);
[email protected]944b62f32012-09-27 02:20:4610731 }
10732 RemoveVertexAttribManager(client_ids[ii]);
10733 }
10734 }
10735}
10736
10737void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:4610738 VertexAttribManager* vao = NULL;
[email protected]944b62f32012-09-27 02:20:4610739 if (client_id != 0) {
10740 vao = GetVertexAttribManager(client_id);
10741 if (!vao) {
10742 // Unlike most Bind* methods, the spec explicitly states that VertexArray
10743 // only allows names that have been previously generated. As such, we do
10744 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:5110745 LOCAL_SET_GL_ERROR(
10746 GL_INVALID_OPERATION,
10747 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:4610748 current_decoder_error_ = error::kNoError;
10749 return;
[email protected]944b62f32012-09-27 02:20:4610750 }
[email protected]944b62f32012-09-27 02:20:4610751 } else {
[email protected]81f20a622014-04-18 01:54:5210752 vao = state_.default_vertex_attrib_manager.get();
[email protected]944b62f32012-09-27 02:20:4610753 }
10754
[email protected]ab4fd7282012-10-12 16:25:5710755 // Only set the VAO state if it's changed
[email protected]7cd76fd2013-06-02 21:11:1110756 if (state_.vertex_attrib_manager.get() != vao) {
[email protected]e259eb412012-10-13 05:47:2410757 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:1510758 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:5710759 EmulateVertexArrayState();
10760 } else {
[email protected]da364812014-05-09 21:39:4810761 GLuint service_id = vao->service_id();
[email protected]ab4fd7282012-10-12 16:25:5710762 glBindVertexArrayOES(service_id);
10763 }
10764 }
10765}
10766
10767// Used when OES_vertex_array_object isn't natively supported
10768void GLES2DecoderImpl::EmulateVertexArrayState() {
10769 // Setup the Vertex attribute state
10770 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
[email protected]3fc38e22014-05-30 00:13:2310771 RestoreStateForAttrib(vv, true);
[email protected]ab4fd7282012-10-12 16:25:5710772 }
10773
10774 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:2110775 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:2410776 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:5710777 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
10778 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:4610779}
10780
10781bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:4610782 const VertexAttribManager* vao =
10783 GetVertexAttribManager(client_id);
10784 return vao && vao->IsValid() && !vao->IsDeleted();
10785}
10786
[email protected]e51bdf32011-11-23 22:21:4610787#if defined(OS_MACOSX)
10788void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
10789 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
10790 texture_id);
10791 if (it != texture_to_io_surface_map_.end()) {
10792 // Found a previous IOSurface bound to this texture; release it.
[email protected]c3a6b4a2014-06-04 09:25:5310793 IOSurfaceRef surface = it->second;
[email protected]e51bdf32011-11-23 22:21:4610794 CFRelease(surface);
10795 texture_to_io_surface_map_.erase(it);
10796 }
10797}
10798#endif
10799
10800void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
10801 GLenum target, GLsizei width, GLsizei height,
10802 GLuint io_surface_id, GLuint plane) {
10803#if defined(OS_MACOSX)
10804 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:5110805 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310806 GL_INVALID_OPERATION,
10807 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:4610808 return;
10809 }
10810
[email protected]e51bdf32011-11-23 22:21:4610811 if (target != GL_TEXTURE_RECTANGLE_ARB) {
10812 // This might be supported in the future, and if we could require
10813 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
10814 // could delete a lot of code. For now, perform strict validation so we
10815 // know what's going on.
[email protected]ab09b612013-03-11 22:11:5110816 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4610817 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310818 "glTexImageIOSurface2DCHROMIUM",
10819 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:4610820 return;
10821 }
10822
[email protected]09d50362012-10-18 20:54:3710823 // Default target might be conceptually valid, but disallow it to avoid
10824 // accidents.
[email protected]c986af502013-08-14 01:04:4410825 TextureRef* texture_ref =
10826 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910827 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110828 LOCAL_SET_GL_ERROR(
10829 GL_INVALID_OPERATION,
10830 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:4610831 return;
10832 }
[email protected]e51bdf32011-11-23 22:21:4610833
10834 // Look up the new IOSurface. Note that because of asynchrony
10835 // between processes this might fail; during live resizing the
10836 // plugin process might allocate and release an IOSurface before
10837 // this process gets a chance to look it up. Hold on to any old
10838 // IOSurface in this case.
[email protected]c3a6b4a2014-06-04 09:25:5310839 IOSurfaceRef surface = IOSurfaceLookup(io_surface_id);
[email protected]e51bdf32011-11-23 22:21:4610840 if (!surface) {
[email protected]ab09b612013-03-11 22:11:5110841 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310842 GL_INVALID_OPERATION,
10843 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:4610844 return;
10845 }
10846
10847 // Release any IOSurface previously bound to this texture.
[email protected]370eaf12013-05-18 09:19:4910848 ReleaseIOSurfaceForTexture(texture_ref->service_id());
[email protected]e51bdf32011-11-23 22:21:4610849
10850 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
10851 texture_to_io_surface_map_.insert(
[email protected]370eaf12013-05-18 09:19:4910852 std::make_pair(texture_ref->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:4610853
10854 CGLContextObj context =
10855 static_cast<CGLContextObj>(context_->GetHandle());
10856
[email protected]c3a6b4a2014-06-04 09:25:5310857 CGLError err = CGLTexImageIOSurface2D(
[email protected]e51bdf32011-11-23 22:21:4610858 context,
10859 target,
10860 GL_RGBA,
10861 width,
10862 height,
10863 GL_BGRA,
10864 GL_UNSIGNED_INT_8_8_8_8_REV,
10865 surface,
10866 plane);
10867
10868 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:5110869 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4610870 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310871 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:4610872 return;
10873 }
10874
10875 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910876 texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:4610877 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
10878
10879#else
[email protected]ab09b612013-03-11 22:11:5110880 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310881 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:4610882#endif
10883}
10884
[email protected]97dc7cbe2011-12-06 17:26:1710885static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
10886 switch (internalformat) {
10887 case GL_RGB565:
10888 return GL_RGB;
10889 case GL_RGBA4:
10890 return GL_RGBA;
10891 case GL_RGB5_A1:
10892 return GL_RGBA;
10893 case GL_RGB8_OES:
10894 return GL_RGB;
10895 case GL_RGBA8_OES:
10896 return GL_RGBA;
10897 case GL_LUMINANCE8_ALPHA8_EXT:
10898 return GL_LUMINANCE_ALPHA;
10899 case GL_LUMINANCE8_EXT:
10900 return GL_LUMINANCE;
10901 case GL_ALPHA8_EXT:
10902 return GL_ALPHA;
10903 case GL_RGBA32F_EXT:
10904 return GL_RGBA;
10905 case GL_RGB32F_EXT:
10906 return GL_RGB;
10907 case GL_ALPHA32F_EXT:
10908 return GL_ALPHA;
10909 case GL_LUMINANCE32F_EXT:
10910 return GL_LUMINANCE;
10911 case GL_LUMINANCE_ALPHA32F_EXT:
10912 return GL_LUMINANCE_ALPHA;
10913 case GL_RGBA16F_EXT:
10914 return GL_RGBA;
10915 case GL_RGB16F_EXT:
10916 return GL_RGB;
10917 case GL_ALPHA16F_EXT:
10918 return GL_ALPHA;
10919 case GL_LUMINANCE16F_EXT:
10920 return GL_LUMINANCE;
10921 case GL_LUMINANCE_ALPHA16F_EXT:
10922 return GL_LUMINANCE_ALPHA;
10923 case GL_BGRA8_EXT:
10924 return GL_BGRA_EXT;
bajones2a2ea232014-10-13 21:38:5910925 case GL_SRGB8_ALPHA8_EXT:
10926 return GL_SRGB_ALPHA_EXT;
[email protected]97dc7cbe2011-12-06 17:26:1710927 default:
10928 return GL_NONE;
10929 }
10930}
10931
[email protected]43410e92012-04-20 17:06:2810932void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:0310933 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
[email protected]a4a6bdd12013-04-19 20:46:5410934 GLenum internal_format, GLenum dest_type) {
[email protected]1e24dc7f2014-04-14 02:40:0810935 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM");
10936
[email protected]370eaf12013-05-18 09:19:4910937 TextureRef* dest_texture_ref = GetTexture(dest_id);
10938 TextureRef* source_texture_ref = GetTexture(source_id);
[email protected]43410e92012-04-20 17:06:2810939
[email protected]370eaf12013-05-18 09:19:4910940 if (!source_texture_ref || !dest_texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110941 LOCAL_SET_GL_ERROR(
10942 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:2810943 return;
10944 }
10945
10946 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110947 LOCAL_SET_GL_ERROR(
10948 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:2810949 return;
10950 }
10951
[email protected]370eaf12013-05-18 09:19:4910952 Texture* source_texture = source_texture_ref->texture();
10953 Texture* dest_texture = dest_texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0710954 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:2510955 (source_texture->target() != GL_TEXTURE_2D &&
[email protected]041d463f2014-04-30 05:38:3410956 source_texture->target() != GL_TEXTURE_RECTANGLE_ARB &&
10957 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
[email protected]3ecc1052013-09-26 08:59:0010958 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
10959 "glCopyTextureCHROMIUM",
10960 "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:0310961 return;
10962 }
10963
[email protected]43410e92012-04-20 17:06:2810964 int source_width, source_height, dest_width, dest_height;
[email protected]43410e92012-04-20 17:06:2810965
[email protected]3e0dfd72014-02-21 06:28:4110966 gfx::GLImage* image =
10967 source_texture->GetLevelImage(source_texture->target(), 0);
10968 if (image) {
[email protected]7bffe9e12014-01-27 23:02:5510969 gfx::Size size = image->GetSize();
[email protected]377976552013-05-14 23:32:5610970 source_width = size.width();
10971 source_height = size.height();
10972 if (source_width <= 0 || source_height <= 0) {
10973 LOCAL_SET_GL_ERROR(
10974 GL_INVALID_VALUE,
[email protected]7bffe9e12014-01-27 23:02:5510975 "glCopyTextureChromium", "invalid image size");
[email protected]377976552013-05-14 23:32:5610976 return;
10977 }
[email protected]3ecc1052013-09-26 08:59:0010978 } else {
10979 if (!source_texture->GetLevelSize(
10980 source_texture->target(), 0, &source_width, &source_height)) {
10981 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
10982 "glCopyTextureChromium",
10983 "source texture has no level 0");
10984 return;
10985 }
10986
10987 // Check that this type of texture is allowed.
10988 if (!texture_manager()->ValidForTarget(
10989 source_texture->target(), level, source_width, source_height, 1)) {
10990 LOCAL_SET_GL_ERROR(
10991 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions");
10992 return;
10993 }
[email protected]377976552013-05-14 23:32:5610994 }
10995
[email protected]04b5b37d2014-02-07 02:11:5110996 // Clear the source texture if necessary.
10997 if (!texture_manager()->ClearTextureLevel(
10998 this, source_texture_ref, source_texture->target(), 0)) {
10999 LOCAL_SET_GL_ERROR(
11000 GL_OUT_OF_MEMORY, "glCopyTextureCHROMIUM", "dimensions too big");
11001 return;
11002 }
11003
[email protected]a6e3d282014-08-22 22:20:4411004 GLenum source_type = 0;
11005 GLenum source_internal_format = 0;
11006 source_texture->GetLevelType(
11007 source_texture->target(), 0, &source_type, &source_internal_format);
11008
11009 // The destination format should be GL_RGB, or GL_RGBA. GL_ALPHA,
11010 // GL_LUMINANCE, and GL_LUMINANCE_ALPHA are not supported because they are not
11011 // renderable on some platforms.
reveman6b0fbe42014-09-04 00:55:0311012 bool valid_dest_format = internal_format == GL_RGB ||
11013 internal_format == GL_RGBA ||
11014 internal_format == GL_BGRA_EXT;
[email protected]a6e3d282014-08-22 22:20:4411015 bool valid_source_format = source_internal_format == GL_ALPHA ||
11016 source_internal_format == GL_RGB ||
11017 source_internal_format == GL_RGBA ||
11018 source_internal_format == GL_LUMINANCE ||
11019 source_internal_format == GL_LUMINANCE_ALPHA ||
11020 source_internal_format == GL_BGRA_EXT;
11021 if (!valid_source_format || !valid_dest_format) {
11022 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11023 "glCopyTextureCHROMIUM",
11024 "invalid internal format");
11025 return;
11026 }
11027
[email protected]cf6b8f62012-05-25 21:43:3711028 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
11029 // needed because it takes 10s of milliseconds to initialize.
11030 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:5111031 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:3711032 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:2711033 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:3711034 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:5111035 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:3711036 return;
11037 }
11038
[email protected]efc87712014-07-09 00:22:4711039 GLenum dest_type_previous = dest_type;
11040 GLenum dest_internal_format = internal_format;
[email protected]02965c22013-03-09 02:40:0711041 bool dest_level_defined = dest_texture->GetLevelSize(
11042 GL_TEXTURE_2D, level, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:2811043
[email protected]0a1e9ad2012-05-04 21:13:0311044 if (dest_level_defined) {
[email protected]a4a6bdd12013-04-19 20:46:5411045 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous,
[email protected]02965c22013-03-09 02:40:0711046 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:0311047 }
11048
11049 // Resize the destination texture to the dimensions of the source texture.
11050 if (!dest_level_defined || dest_width != source_width ||
11051 dest_height != source_height ||
[email protected]a4a6bdd12013-04-19 20:46:5411052 dest_internal_format != internal_format ||
11053 dest_type_previous != dest_type) {
[email protected]43410e92012-04-20 17:06:2811054 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:5111055 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:0711056 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
[email protected]8f1d2aa2013-05-10 23:45:3811057 glTexImage2D(
[email protected]43410e92012-04-20 17:06:2811058 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:0311059 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:5111060 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:0311061 if (error != GL_NO_ERROR) {
[email protected]2b10c02d2014-01-29 16:43:0211062 RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D);
[email protected]43410e92012-04-20 17:06:2811063 return;
[email protected]0a1e9ad2012-05-04 21:13:0311064 }
[email protected]43410e92012-04-20 17:06:2811065
11066 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4911067 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:0311068 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:2511069 } else {
[email protected]02965c22013-03-09 02:40:0711070 texture_manager()->SetLevelCleared(
[email protected]370eaf12013-05-18 09:19:4911071 dest_texture_ref, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:2811072 }
11073
[email protected]00c2cf92014-03-14 00:08:3711074 ScopedModifyPixels modify(dest_texture_ref);
[email protected]91c94eb2013-10-22 10:32:5411075
revemance8fbe82014-09-05 02:19:5211076 // Try using GLImage::CopyTexImage when possible.
11077 bool unpack_premultiply_alpha_change =
11078 unpack_premultiply_alpha_ ^ unpack_unpremultiply_alpha_;
11079 if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change && !level) {
11080 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
11081 if (image->CopyTexImage(GL_TEXTURE_2D))
11082 return;
11083 }
11084
11085 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
11086
[email protected]5394a4102013-04-18 05:41:3711087 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
11088 // before presenting.
11089 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
11090 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
11091 // instead of using default matrix crbug.com/226218.
11092 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
11093 0.0f, 1.0f, 0.0f, 0.0f,
11094 0.0f, 0.0f, 1.0f, 0.0f,
11095 0.0f, 0.0f, 0.0f, 1.0f};
11096 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
11097 this,
11098 source_texture->target(),
[email protected]5394a4102013-04-18 05:41:3711099 source_texture->service_id(),
[email protected]90f7d30d2014-08-13 02:51:5711100 dest_texture->service_id(),
11101 level,
11102 source_width,
11103 source_height,
[email protected]5394a4102013-04-18 05:41:3711104 unpack_flip_y_,
11105 unpack_premultiply_alpha_,
11106 unpack_unpremultiply_alpha_,
11107 default_matrix);
11108 } else {
[email protected]90f7d30d2014-08-13 02:51:5711109 copy_texture_CHROMIUM_->DoCopyTexture(this,
11110 source_texture->target(),
11111 source_texture->service_id(),
11112 source_internal_format,
11113 dest_texture->service_id(),
11114 level,
11115 internal_format,
11116 source_width,
11117 source_height,
11118 unpack_flip_y_,
11119 unpack_premultiply_alpha_,
11120 unpack_unpremultiply_alpha_);
[email protected]5394a4102013-04-18 05:41:3711121 }
[email protected]91c94eb2013-10-22 10:32:5411122
11123 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
[email protected]43410e92012-04-20 17:06:2811124}
11125
[email protected]97dc7cbe2011-12-06 17:26:1711126static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
11127 switch (internalformat) {
11128 case GL_RGB565:
11129 return GL_UNSIGNED_SHORT_5_6_5;
11130 case GL_RGBA4:
11131 return GL_UNSIGNED_SHORT_4_4_4_4;
11132 case GL_RGB5_A1:
11133 return GL_UNSIGNED_SHORT_5_5_5_1;
11134 case GL_RGB8_OES:
11135 return GL_UNSIGNED_BYTE;
11136 case GL_RGBA8_OES:
11137 return GL_UNSIGNED_BYTE;
11138 case GL_LUMINANCE8_ALPHA8_EXT:
11139 return GL_UNSIGNED_BYTE;
11140 case GL_LUMINANCE8_EXT:
11141 return GL_UNSIGNED_BYTE;
11142 case GL_ALPHA8_EXT:
11143 return GL_UNSIGNED_BYTE;
11144 case GL_RGBA32F_EXT:
11145 return GL_FLOAT;
11146 case GL_RGB32F_EXT:
11147 return GL_FLOAT;
11148 case GL_ALPHA32F_EXT:
11149 return GL_FLOAT;
11150 case GL_LUMINANCE32F_EXT:
11151 return GL_FLOAT;
11152 case GL_LUMINANCE_ALPHA32F_EXT:
11153 return GL_FLOAT;
11154 case GL_RGBA16F_EXT:
11155 return GL_HALF_FLOAT_OES;
11156 case GL_RGB16F_EXT:
11157 return GL_HALF_FLOAT_OES;
11158 case GL_ALPHA16F_EXT:
11159 return GL_HALF_FLOAT_OES;
11160 case GL_LUMINANCE16F_EXT:
11161 return GL_HALF_FLOAT_OES;
11162 case GL_LUMINANCE_ALPHA16F_EXT:
11163 return GL_HALF_FLOAT_OES;
11164 case GL_BGRA8_EXT:
11165 return GL_UNSIGNED_BYTE;
11166 default:
11167 return GL_NONE;
11168 }
11169}
11170
11171void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:4411172 GLenum target,
11173 GLint levels,
11174 GLenum internal_format,
11175 GLsizei width,
11176 GLsizei height) {
[email protected]67f929422014-05-17 15:33:1311177 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT",
11178 "width", width, "height", height);
[email protected]80eb6b52012-01-19 00:14:4111179 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]3ecc1052013-09-26 08:59:0011180 TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:5111181 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4311182 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:1711183 return;
11184 }
[email protected]c986af502013-08-14 01:04:4411185 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11186 &state_, target);
[email protected]370eaf12013-05-18 09:19:4911187 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111188 LOCAL_SET_GL_ERROR(
11189 GL_INVALID_OPERATION,
11190 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:1711191 return;
11192 }
[email protected]370eaf12013-05-18 09:19:4911193 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0711194 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:4411195 framebuffer_state_.clear_state_dirty = true;
[email protected]97dc7cbe2011-12-06 17:26:1711196 }
[email protected]02965c22013-03-09 02:40:0711197 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:5111198 LOCAL_SET_GL_ERROR(
11199 GL_INVALID_OPERATION,
11200 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:1711201 return;
11202 }
[email protected]7989c9e2013-01-23 06:39:2611203
11204 GLenum format = ExtractFormatFromStorageFormat(internal_format);
11205 GLenum type = ExtractTypeFromStorageFormat(internal_format);
11206
11207 {
11208 GLsizei level_width = width;
11209 GLsizei level_height = height;
11210 uint32 estimated_size = 0;
11211 for (int ii = 0; ii < levels; ++ii) {
11212 uint32 level_size = 0;
11213 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4211214 level_width, level_height, 1, format, type, state_.unpack_alignment,
[email protected]7989c9e2013-01-23 06:39:2611215 &estimated_size, NULL, NULL) ||
11216 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5111217 LOCAL_SET_GL_ERROR(
11218 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:2611219 return;
11220 }
11221 level_width = std::max(1, level_width >> 1);
11222 level_height = std::max(1, level_height >> 1);
11223 }
11224 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5111225 LOCAL_SET_GL_ERROR(
11226 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2611227 return;
11228 }
11229 }
11230
[email protected]ab09b612013-03-11 22:11:5111231 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]8f1d2aa2013-05-10 23:45:3811232 glTexStorage2DEXT(target, levels, internal_format, width, height);
[email protected]ab09b612013-03-11 22:11:5111233 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:1711234 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:1511235 GLsizei level_width = width;
11236 GLsizei level_height = height;
11237 for (int ii = 0; ii < levels; ++ii) {
11238 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4911239 texture_ref, target, ii, format,
11240 level_width, level_height, 1, 0, format, type, false);
[email protected]4502e6492011-12-14 19:39:1511241 level_width = std::max(1, level_width >> 1);
11242 level_height = std::max(1, level_height >> 1);
11243 }
[email protected]02965c22013-03-09 02:40:0711244 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:1711245 }
[email protected]97dc7cbe2011-12-06 17:26:1711246}
[email protected]e51bdf32011-11-23 22:21:4611247
[email protected]78b514b2012-05-01 21:50:5911248error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
vmiuracd108592014-09-08 14:36:3411249 uint32 immediate_data_size,
11250 const void* cmd_data) {
[email protected]baed42c2013-10-01 05:06:3511251 return error::kUnknownCommand;
[email protected]78b514b2012-05-01 21:50:5911252}
11253
11254void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3711255 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0211256 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3211257 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3711258 "mailbox[0]", static_cast<unsigned char>(data[0]));
11259
[email protected]43f253da2014-06-10 17:51:2211260 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11261 &state_, target);
11262 ProduceTextureRef("glProduceTextureCHROMIUM", texture_ref, target, data);
11263}
11264
11265void GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM(GLuint client_id,
11266 GLenum target, const GLbyte* data) {
11267 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM",
11268 "context", logger_.GetLogPrefix(),
11269 "mailbox[0]", static_cast<unsigned char>(data[0]));
11270
11271 ProduceTextureRef("glProduceTextureDirectCHROMIUM", GetTexture(client_id),
11272 target, data);
11273}
11274
11275void GLES2DecoderImpl::ProduceTextureRef(std::string func_name,
11276 TextureRef* texture_ref, GLenum target, const GLbyte* data) {
[email protected]64ba52f2014-02-15 14:22:3711277 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
[email protected]43f253da2014-06-10 17:51:2211278 DLOG_IF(ERROR, !mailbox.Verify()) << func_name << " was passed a "
[email protected]64ba52f2014-02-15 14:22:3711279 "mailbox that was not generated by "
11280 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0211281
[email protected]370eaf12013-05-18 09:19:4911282 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111283 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2211284 GL_INVALID_OPERATION, func_name.c_str(), "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5911285 return;
11286 }
11287
[email protected]62e65f02013-05-29 22:28:1011288 Texture* produced = texture_manager()->Produce(texture_ref);
11289 if (!produced) {
[email protected]ab09b612013-03-11 22:11:5111290 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2211291 GL_INVALID_OPERATION, func_name.c_str(), "invalid texture");
11292 return;
11293 }
11294
11295 if (produced->target() != target) {
11296 LOCAL_SET_GL_ERROR(
11297 GL_INVALID_OPERATION, func_name.c_str(), "invalid target");
[email protected]78b514b2012-05-01 21:50:5911298 return;
11299 }
11300
sievers8b373ec52014-10-24 23:04:0611301 group_->mailbox_manager()->ProduceTexture(mailbox, produced);
[email protected]78b514b2012-05-01 21:50:5911302}
11303
11304void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3711305 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0211306 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3211307 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3711308 "mailbox[0]", static_cast<unsigned char>(data[0]));
11309 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
11310 DLOG_IF(ERROR, !mailbox.Verify()) << "ConsumeTextureCHROMIUM was passed a "
11311 "mailbox that was not generated by "
11312 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0211313
[email protected]62e65f02013-05-29 22:28:1011314 scoped_refptr<TextureRef> texture_ref =
[email protected]c986af502013-08-14 01:04:4411315 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]7cd76fd2013-06-02 21:11:1111316 if (!texture_ref.get()) {
11317 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11318 "glConsumeTextureCHROMIUM",
11319 "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5911320 return;
11321 }
[email protected]62e65f02013-05-29 22:28:1011322 GLuint client_id = texture_ref->client_id();
11323 if (!client_id) {
11324 LOCAL_SET_GL_ERROR(
11325 GL_INVALID_OPERATION,
11326 "glConsumeTextureCHROMIUM", "unknown texture for target");
11327 return;
11328 }
sievers8b373ec52014-10-24 23:04:0611329 Texture* texture = group_->mailbox_manager()->ConsumeTexture(mailbox);
[email protected]62e65f02013-05-29 22:28:1011330 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5111331 LOCAL_SET_GL_ERROR(
11332 GL_INVALID_OPERATION,
11333 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:5911334 return;
11335 }
[email protected]62e65f02013-05-29 22:28:1011336 if (texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:5111337 LOCAL_SET_GL_ERROR(
11338 GL_INVALID_OPERATION,
[email protected]62e65f02013-05-29 22:28:1011339 "glConsumeTextureCHROMIUM", "invalid target");
[email protected]78b514b2012-05-01 21:50:5911340 return;
11341 }
[email protected]62e65f02013-05-29 22:28:1011342
11343 DeleteTexturesHelper(1, &client_id);
11344 texture_ref = texture_manager()->Consume(client_id, texture);
11345 glBindTexture(target, texture_ref->service_id());
11346
11347 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
11348 unit.bind_target = target;
11349 switch (target) {
11350 case GL_TEXTURE_2D:
11351 unit.bound_texture_2d = texture_ref;
11352 break;
11353 case GL_TEXTURE_CUBE_MAP:
11354 unit.bound_texture_cube_map = texture_ref;
11355 break;
11356 case GL_TEXTURE_EXTERNAL_OES:
11357 unit.bound_texture_external_oes = texture_ref;
11358 break;
11359 case GL_TEXTURE_RECTANGLE_ARB:
11360 unit.bound_texture_rectangle_arb = texture_ref;
11361 break;
11362 default:
11363 NOTREACHED(); // Validation should prevent us getting here.
11364 break;
11365 }
[email protected]78b514b2012-05-01 21:50:5911366}
11367
[email protected]43f253da2014-06-10 17:51:2211368error::Error GLES2DecoderImpl::HandleCreateAndConsumeTextureCHROMIUMImmediate(
11369 uint32_t immediate_data_size,
vmiuracd108592014-09-08 14:36:3411370 const void* cmd_data) {
11371 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate& c =
11372 *static_cast<
11373 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate*>(
11374 cmd_data);
[email protected]43f253da2014-06-10 17:51:2211375 GLenum target = static_cast<GLenum>(c.target);
11376 uint32_t data_size;
11377 if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
11378 return error::kOutOfBounds;
11379 }
11380 if (data_size > immediate_data_size) {
11381 return error::kOutOfBounds;
11382 }
11383 const GLbyte* mailbox =
11384 GetImmediateDataAs<const GLbyte*>(c, data_size, immediate_data_size);
11385 if (!validators_->texture_bind_target.IsValid(target)) {
11386 LOCAL_SET_GL_ERROR_INVALID_ENUM(
11387 "glCreateAndConsumeTextureCHROMIUM", target, "target");
11388 return error::kNoError;
11389 }
11390 if (mailbox == NULL) {
11391 return error::kOutOfBounds;
11392 }
11393 uint32_t client_id = c.client_id;
11394 DoCreateAndConsumeTextureCHROMIUM(target, mailbox, client_id);
11395 return error::kNoError;
11396}
11397
11398void GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM(GLenum target,
11399 const GLbyte* data, GLuint client_id) {
11400 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM",
11401 "context", logger_.GetLogPrefix(),
11402 "mailbox[0]", static_cast<unsigned char>(data[0]));
11403 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
11404 DLOG_IF(ERROR, !mailbox.Verify()) << "CreateAndConsumeTextureCHROMIUM was "
11405 "passed a mailbox that was not "
11406 "generated by GenMailboxCHROMIUM.";
11407
11408 TextureRef* texture_ref = GetTexture(client_id);
11409 if (texture_ref) {
11410 LOCAL_SET_GL_ERROR(
11411 GL_INVALID_OPERATION,
11412 "glCreateAndConsumeTextureCHROMIUM", "client id already in use");
11413 return;
11414 }
sievers8b373ec52014-10-24 23:04:0611415 Texture* texture = group_->mailbox_manager()->ConsumeTexture(mailbox);
[email protected]43f253da2014-06-10 17:51:2211416 if (!texture) {
11417 LOCAL_SET_GL_ERROR(
11418 GL_INVALID_OPERATION,
11419 "glCreateAndConsumeTextureCHROMIUM", "invalid mailbox name");
11420 return;
11421 }
11422 if (texture->target() != target) {
11423 LOCAL_SET_GL_ERROR(
11424 GL_INVALID_OPERATION,
11425 "glCreateAndConsumeTextureCHROMIUM", "invalid target");
11426 return;
11427 }
11428
[email protected]43f253da2014-06-10 17:51:2211429 texture_ref = texture_manager()->Consume(client_id, texture);
11430}
11431
orglofchcad5a6742014-11-07 19:51:1211432bool GLES2DecoderImpl::DoIsValuebufferCHROMIUM(GLuint client_id) {
11433 const Valuebuffer* valuebuffer = GetValuebuffer(client_id);
11434 return valuebuffer && valuebuffer->IsValid();
11435}
11436
11437void GLES2DecoderImpl::DoBindValueBufferCHROMIUM(GLenum target,
11438 GLuint client_id) {
11439 Valuebuffer* valuebuffer = NULL;
11440 if (client_id != 0) {
11441 valuebuffer = GetValuebuffer(client_id);
11442 if (!valuebuffer) {
11443 if (!group_->bind_generates_resource()) {
11444 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBindValuebufferCHROMIUM",
11445 "id not generated by glBindValuebufferCHROMIUM");
11446 return;
11447 }
11448
11449 // It's a new id so make a valuebuffer for it.
11450 CreateValuebuffer(client_id);
11451 valuebuffer = GetValuebuffer(client_id);
11452 }
11453 valuebuffer->MarkAsValid();
11454 }
11455 state_.bound_valuebuffer = valuebuffer;
11456}
11457
11458void GLES2DecoderImpl::DoSubscribeValueCHROMIUM(GLenum target,
11459 GLenum subscription) {
11460 if (!CheckCurrentValuebuffer("glSubscribeValueCHROMIUM")) {
11461 return;
11462 }
11463 state_.bound_valuebuffer.get()->AddSubscription(subscription);
11464}
11465
11466void GLES2DecoderImpl::DoPopulateSubscribedValuesCHROMIUM(GLenum target) {
11467 if (!CheckCurrentValuebuffer("glPopulateSubscribedValuesCHROMIUM")) {
11468 return;
11469 }
11470 valuebuffer_manager()->UpdateValuebufferState(state_.bound_valuebuffer.get());
11471}
11472
11473void GLES2DecoderImpl::DoUniformValueBufferCHROMIUM(GLint location,
11474 GLenum target,
11475 GLenum subscription) {
11476 if (!CheckCurrentValuebufferForSubscription(
11477 subscription, "glPopulateSubscribedValuesCHROMIUM")) {
11478 return;
11479 }
11480 if (!CheckSubscriptionTarget(location, subscription,
11481 "glPopulateSubscribedValuesCHROMIUM")) {
11482 return;
11483 }
11484 const ValueState* state =
11485 state_.bound_valuebuffer.get()->GetState(subscription);
11486 if (state) {
11487 switch (subscription) {
11488 case GL_MOUSE_POSITION_CHROMIUM:
11489 DoUniform2iv(location, 1, state->int_value);
11490 break;
11491 default:
11492 NOTREACHED() << "Unhandled uniform subscription target "
11493 << subscription;
11494 break;
11495 }
11496 }
11497}
11498
[email protected]d2a0e1a2012-08-12 02:25:0111499void GLES2DecoderImpl::DoInsertEventMarkerEXT(
11500 GLsizei length, const GLchar* marker) {
11501 if (!marker) {
11502 marker = "";
11503 }
11504 debug_marker_manager_.SetMarker(
11505 length ? std::string(marker, length) : std::string(marker));
11506}
11507
11508void GLES2DecoderImpl::DoPushGroupMarkerEXT(
11509 GLsizei length, const GLchar* marker) {
11510 if (!marker) {
11511 marker = "";
11512 }
[email protected]cac16542014-01-15 17:53:5111513 std::string name = length ? std::string(marker, length) : std::string(marker);
11514 debug_marker_manager_.PushGroup(name);
dyen4bb43282015-01-08 01:09:5611515 gpu_tracer_->Begin(TRACE_DISABLED_BY_DEFAULT("gpu_group_marker"), name,
11516 kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0111517}
11518
11519void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
11520 debug_marker_manager_.PopGroup();
dyen4bb43282015-01-08 01:09:5611521 gpu_tracer_->End(kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0111522}
11523
[email protected]09d50362012-10-18 20:54:3711524void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
11525 GLenum target, GLint image_id) {
11526 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3711527
[email protected]bc26e8d2014-01-29 00:40:3011528 if (target == GL_TEXTURE_CUBE_MAP) {
11529 LOCAL_SET_GL_ERROR(
11530 GL_INVALID_ENUM,
11531 "glBindTexImage2DCHROMIUM", "invalid target");
11532 return;
11533 }
11534
[email protected]09d50362012-10-18 20:54:3711535 // Default target might be conceptually valid, but disallow it to avoid
11536 // accidents.
[email protected]c986af502013-08-14 01:04:4411537 TextureRef* texture_ref =
11538 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4911539 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111540 LOCAL_SET_GL_ERROR(
11541 GL_INVALID_OPERATION,
11542 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3711543 return;
11544 }
11545
11546 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
11547 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5111548 LOCAL_SET_GL_ERROR(
11549 GL_INVALID_OPERATION,
11550 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3711551 return;
11552 }
11553
[email protected]b8160812013-04-09 00:41:0411554 {
11555 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3011556 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2611557 if (!gl_image->BindTexImage(target)) {
[email protected]b8160812013-04-09 00:41:0411558 LOCAL_SET_GL_ERROR(
11559 GL_INVALID_OPERATION,
11560 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
11561 return;
11562 }
[email protected]09d50362012-10-18 20:54:3711563 }
11564
11565 gfx::Size size = gl_image->GetSize();
11566 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4911567 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:3711568 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]370eaf12013-05-18 09:19:4911569 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:3711570}
11571
11572void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
11573 GLenum target, GLint image_id) {
11574 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3711575
11576 // Default target might be conceptually valid, but disallow it to avoid
11577 // accidents.
[email protected]c986af502013-08-14 01:04:4411578 TextureRef* texture_ref =
11579 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4911580 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111581 LOCAL_SET_GL_ERROR(
11582 GL_INVALID_OPERATION,
11583 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3711584 return;
11585 }
11586
11587 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
11588 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5111589 LOCAL_SET_GL_ERROR(
11590 GL_INVALID_OPERATION,
11591 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3711592 return;
11593 }
11594
11595 // Do nothing when image is not currently bound.
[email protected]370eaf12013-05-18 09:19:4911596 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3711597 return;
11598
[email protected]b8160812013-04-09 00:41:0411599 {
11600 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3011601 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2611602 gl_image->ReleaseTexImage(target);
[email protected]b8160812013-04-09 00:41:0411603 }
[email protected]09d50362012-10-18 20:54:3711604
11605 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4911606 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:3711607 GL_RGBA, GL_UNSIGNED_BYTE, false);
11608}
[email protected]d2a0e1a2012-08-12 02:25:0111609
[email protected]94307712012-11-16 23:26:1111610error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
vmiuracd108592014-09-08 14:36:3411611 uint32 immediate_data_size,
11612 const void* cmd_data) {
11613 const gles2::cmds::TraceBeginCHROMIUM& c =
11614 *static_cast<const gles2::cmds::TraceBeginCHROMIUM*>(cmd_data);
dyencb86f2f2014-12-09 18:35:4111615 Bucket* category_bucket = GetBucket(c.category_bucket_id);
11616 Bucket* name_bucket = GetBucket(c.name_bucket_id);
11617 if (!category_bucket || category_bucket->size() == 0 ||
11618 !name_bucket || name_bucket->size() == 0) {
[email protected]94307712012-11-16 23:26:1111619 return error::kInvalidArguments;
11620 }
dyencb86f2f2014-12-09 18:35:4111621
11622 std::string category_name;
11623 std::string trace_name;
11624 if (!category_bucket->GetAsString(&category_name) ||
11625 !name_bucket->GetAsString(&trace_name)) {
[email protected]94307712012-11-16 23:26:1111626 return error::kInvalidArguments;
11627 }
dyencb86f2f2014-12-09 18:35:4111628
dyencb86f2f2014-12-09 18:35:4111629 if (!gpu_tracer_->Begin(category_name, trace_name, kTraceCHROMIUM)) {
[email protected]ab09b612013-03-11 22:11:5111630 LOCAL_SET_GL_ERROR(
11631 GL_INVALID_OPERATION,
11632 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1411633 return error::kNoError;
11634 }
[email protected]94307712012-11-16 23:26:1111635 return error::kNoError;
11636}
11637
11638void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
dyen4bb43282015-01-08 01:09:5611639 if (!gpu_tracer_->End(kTraceCHROMIUM)) {
11640 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11641 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1111642 return;
11643 }
[email protected]94307712012-11-16 23:26:1111644}
11645
[email protected]2f143d482013-03-14 18:04:4911646void GLES2DecoderImpl::DoDrawBuffersEXT(
11647 GLsizei count, const GLenum* bufs) {
11648 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
11649 LOCAL_SET_GL_ERROR(
11650 GL_INVALID_VALUE,
11651 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
11652 return;
11653 }
11654
11655 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
11656 if (framebuffer) {
11657 for (GLsizei i = 0; i < count; ++i) {
11658 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
11659 bufs[i] != GL_NONE) {
11660 LOCAL_SET_GL_ERROR(
11661 GL_INVALID_OPERATION,
11662 "glDrawBuffersEXT",
11663 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
11664 return;
11665 }
11666 }
11667 glDrawBuffersARB(count, bufs);
11668 framebuffer->SetDrawBuffers(count, bufs);
11669 } else { // backbuffer
11670 if (count > 1 ||
11671 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
11672 LOCAL_SET_GL_ERROR(
11673 GL_INVALID_OPERATION,
11674 "glDrawBuffersEXT",
11675 "more than one buffer or bufs not GL_NONE or GL_BACK");
11676 return;
11677 }
11678 GLenum mapped_buf = bufs[0];
11679 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
11680 bufs[0] == GL_BACK) {
11681 mapped_buf = GL_COLOR_ATTACHMENT0;
11682 }
11683 glDrawBuffersARB(count, &mapped_buf);
11684 group_->set_draw_buffer(bufs[0]);
11685 }
11686}
11687
[email protected]a6a09f852014-05-23 13:05:0311688void GLES2DecoderImpl::DoLoseContextCHROMIUM(GLenum current, GLenum other) {
11689 group_->LoseContexts(other);
11690 reset_status_ = current;
11691 current_decoder_error_ = error::kLostContext;
11692}
11693
kkinnunen337d59632014-08-26 10:19:5711694void GLES2DecoderImpl::DoMatrixLoadfCHROMIUM(GLenum matrix_mode,
11695 const GLfloat* matrix) {
11696 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
11697 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
11698 if (!features().chromium_path_rendering) {
11699 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11700 "glMatrixLoadfCHROMIUM",
11701 "function not available");
11702 return;
11703 }
11704
11705 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
11706 ? state_.projection_matrix
11707 : state_.modelview_matrix;
11708 memcpy(target_matrix, matrix, sizeof(GLfloat) * 16);
11709 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
11710 // since the values of the _NV and _CHROMIUM tokens match.
11711 glMatrixLoadfEXT(matrix_mode, matrix);
11712}
11713
11714void GLES2DecoderImpl::DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode) {
11715 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
11716 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
11717
11718 if (!features().chromium_path_rendering) {
11719 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11720 "glMatrixLoadIdentityCHROMIUM",
11721 "function not available");
11722 return;
11723 }
11724
11725 static GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
11726 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
11727 0.0f, 0.0f, 0.0f, 1.0f};
11728
11729 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
11730 ? state_.projection_matrix
11731 : state_.modelview_matrix;
11732 memcpy(target_matrix, kIdentityMatrix, sizeof(kIdentityMatrix));
11733 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
11734 // since the values of the _NV and _CHROMIUM tokens match.
11735 glMatrixLoadIdentityEXT(matrix_mode);
11736}
11737
[email protected]32145a92012-12-17 09:01:5911738bool GLES2DecoderImpl::ValidateAsyncTransfer(
11739 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:4711740 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:5911741 GLenum target,
11742 GLint level,
11743 const void * data) {
11744 // We only support async uploads to 2D textures for now.
11745 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5111746 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5911747 return false;
11748 }
11749 // We only support uploads to level zero for now.
11750 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5111751 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5911752 return false;
11753 }
11754 // A transfer buffer must be bound, even for asyncTexImage2D.
11755 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5111756 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5911757 return false;
11758 }
11759 // We only support one async transfer in progress.
[email protected]85a4ac22013-05-31 01:58:4711760 if (!texture_ref ||
11761 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5111762 LOCAL_SET_GL_ERROR(
11763 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5911764 function_name, "transfer already in progress");
11765 return false;
11766 }
11767 return true;
11768}
11769
[email protected]e3c4a9ab2014-03-31 09:07:0211770base::Closure GLES2DecoderImpl::AsyncUploadTokenCompletionClosure(
11771 uint32 async_upload_token,
11772 uint32 sync_data_shm_id,
11773 uint32 sync_data_shm_offset) {
11774 scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_data_shm_id);
Daniel Cheng3d7ce9f2014-08-26 00:26:2511775 if (!buffer.get() ||
11776 !buffer->GetDataAddress(sync_data_shm_offset, sizeof(AsyncUploadSync)))
[email protected]e3c4a9ab2014-03-31 09:07:0211777 return base::Closure();
11778
11779 AsyncMemoryParams mem_params(buffer,
11780 sync_data_shm_offset,
11781 sizeof(AsyncUploadSync));
11782
11783 scoped_refptr<AsyncUploadTokenCompletionObserver> observer(
11784 new AsyncUploadTokenCompletionObserver(async_upload_token));
11785
11786 return base::Bind(
11787 &AsyncPixelTransferManager::AsyncNotifyCompletion,
11788 base::Unretained(GetAsyncPixelTransferManager()),
11789 mem_params,
11790 observer);
11791}
11792
[email protected]69023942012-11-30 19:57:1611793error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411794 uint32 immediate_data_size,
11795 const void* cmd_data) {
11796 const gles2::cmds::AsyncTexImage2DCHROMIUM& c =
11797 *static_cast<const gles2::cmds::AsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1611798 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1611799 GLenum target = static_cast<GLenum>(c.target);
11800 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:4411801 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]69023942012-11-30 19:57:1611802 GLsizei width = static_cast<GLsizei>(c.width);
11803 GLsizei height = static_cast<GLsizei>(c.height);
11804 GLint border = static_cast<GLint>(c.border);
11805 GLenum format = static_cast<GLenum>(c.format);
11806 GLenum type = static_cast<GLenum>(c.type);
11807 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
11808 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
11809 uint32 pixels_size;
[email protected]e3c4a9ab2014-03-31 09:07:0211810 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
11811 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
11812 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
11813
11814 base::ScopedClosureRunner scoped_completion_callback;
11815 if (async_upload_token) {
11816 base::Closure completion_closure =
11817 AsyncUploadTokenCompletionClosure(async_upload_token,
11818 sync_data_shm_id,
11819 sync_data_shm_offset);
11820 if (completion_closure.is_null())
11821 return error::kInvalidArguments;
11822
11823 scoped_completion_callback.Reset(completion_closure);
11824 }
[email protected]32145a92012-12-17 09:01:5911825
11826 // TODO(epenner): Move this and copies of this memory validation
11827 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1611828 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4211829 width, height, 1, format, type, state_.unpack_alignment, &pixels_size,
11830 NULL, NULL)) {
[email protected]69023942012-11-30 19:57:1611831 return error::kOutOfBounds;
11832 }
11833 const void* pixels = NULL;
11834 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
11835 pixels = GetSharedMemoryAs<const void*>(
11836 pixels_shm_id, pixels_shm_offset, pixels_size);
11837 if (!pixels) {
11838 return error::kOutOfBounds;
11839 }
11840 }
11841
[email protected]c986af502013-08-14 01:04:4411842 TextureManager::DoTextImage2DArguments args = {
11843 target, level, internal_format, width, height, border, format, type,
11844 pixels, pixels_size};
11845 TextureRef* texture_ref;
[email protected]32145a92012-12-17 09:01:5911846 // All the normal glTexSubImage2D validation.
[email protected]c986af502013-08-14 01:04:4411847 if (!texture_manager()->ValidateTexImage2D(
11848 &state_, "glAsyncTexImage2DCHROMIUM", args, &texture_ref)) {
[email protected]32145a92012-12-17 09:01:5911849 return error::kNoError;
11850 }
11851
11852 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4911853 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5911854 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4711855 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5911856 return error::kNoError;
11857
11858 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0711859 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5111860 LOCAL_SET_GL_ERROR(
11861 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5911862 "glAsyncTexImage2DCHROMIUM", "already defined");
11863 return error::kNoError;
11864 }
11865
[email protected]7989c9e2013-01-23 06:39:2611866 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5111867 LOCAL_SET_GL_ERROR(
11868 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2611869 return error::kNoError;
11870 }
11871
[email protected]5b3a8e02013-03-13 05:36:4411872 // Setup the parameters.
[email protected]8f1d2aa2013-05-10 23:45:3811873 AsyncTexImage2DParams tex_params = {
11874 target, level, static_cast<GLenum>(internal_format),
11875 width, height, border, format, type};
[email protected]c8021e02014-03-27 06:10:1211876 AsyncMemoryParams mem_params(
11877 GetSharedMemoryBuffer(c.pixels_shm_id), c.pixels_shm_offset, pixels_size);
[email protected]32145a92012-12-17 09:01:5911878
[email protected]5b3a8e02013-03-13 05:36:4411879 // Set up the async state if needed, and make the texture
11880 // immutable so the async state stays valid. The level info
11881 // is set up lazily when the transfer completes.
[email protected]896425e2013-06-12 17:27:1811882 AsyncPixelTransferDelegate* delegate =
11883 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref,
11884 tex_params);
[email protected]5b3a8e02013-03-13 05:36:4411885 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5911886
[email protected]896425e2013-06-12 17:27:1811887 delegate->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4411888 tex_params,
11889 mem_params,
11890 base::Bind(&TextureManager::SetLevelInfoFromParams,
[email protected]370eaf12013-05-18 09:19:4911891 // The callback is only invoked if the transfer delegate still
11892 // exists, which implies through manager->texture_ref->state
[email protected]5b3a8e02013-03-13 05:36:4411893 // ownership that both of these pointers are valid.
11894 base::Unretained(texture_manager()),
[email protected]370eaf12013-05-18 09:19:4911895 base::Unretained(texture_ref),
[email protected]5b3a8e02013-03-13 05:36:4411896 tex_params));
[email protected]f598f422012-12-07 08:30:0311897 return error::kNoError;
[email protected]69023942012-11-30 19:57:1611898}
11899
11900error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411901 uint32 immediate_data_size,
11902 const void* cmd_data) {
11903 const gles2::cmds::AsyncTexSubImage2DCHROMIUM& c =
11904 *static_cast<const gles2::cmds::AsyncTexSubImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1611905 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1611906 GLenum target = static_cast<GLenum>(c.target);
11907 GLint level = static_cast<GLint>(c.level);
11908 GLint xoffset = static_cast<GLint>(c.xoffset);
11909 GLint yoffset = static_cast<GLint>(c.yoffset);
11910 GLsizei width = static_cast<GLsizei>(c.width);
11911 GLsizei height = static_cast<GLsizei>(c.height);
11912 GLenum format = static_cast<GLenum>(c.format);
11913 GLenum type = static_cast<GLenum>(c.type);
[email protected]e3c4a9ab2014-03-31 09:07:0211914 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
11915 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
11916 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
11917
11918 base::ScopedClosureRunner scoped_completion_callback;
11919 if (async_upload_token) {
11920 base::Closure completion_closure =
11921 AsyncUploadTokenCompletionClosure(async_upload_token,
11922 sync_data_shm_id,
11923 sync_data_shm_offset);
11924 if (completion_closure.is_null())
11925 return error::kInvalidArguments;
11926
11927 scoped_completion_callback.Reset(completion_closure);
11928 }
[email protected]32145a92012-12-17 09:01:5911929
11930 // TODO(epenner): Move this and copies of this memory validation
11931 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1611932 uint32 data_size;
11933 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4211934 width, height, 1, format, type, state_.unpack_alignment, &data_size,
[email protected]69023942012-11-30 19:57:1611935 NULL, NULL)) {
11936 return error::kOutOfBounds;
11937 }
11938 const void* pixels = GetSharedMemoryAs<const void*>(
11939 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5911940
11941 // All the normal glTexSubImage2D validation.
11942 error::Error error = error::kNoError;
11943 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
11944 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
11945 return error;
[email protected]69023942012-11-30 19:57:1611946 }
11947
[email protected]32145a92012-12-17 09:01:5911948 // Extra async validation.
[email protected]c986af502013-08-14 01:04:4411949 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11950 &state_, target);
[email protected]370eaf12013-05-18 09:19:4911951 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5911952 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4711953 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5911954 return error::kNoError;
11955
11956 // Guarantee async textures are always 'cleared' as follows:
11957 // - AsyncTexImage2D can not redefine an existing texture
11958 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
11959 // - AsyncTexSubImage2D clears synchronously if not already cleared.
11960 // - Textures become immutable after an async call.
11961 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0711962 if (!texture->SafeToRenderFrom()) {
[email protected]370eaf12013-05-18 09:19:4911963 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
11964 target, level)) {
[email protected]ab09b612013-03-11 22:11:5111965 LOCAL_SET_GL_ERROR(
11966 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2511967 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5911968 return error::kNoError;
11969 }
11970 }
11971
[email protected]5b3a8e02013-03-13 05:36:4411972 // Setup the parameters.
[email protected]2a7568a2013-05-09 23:12:0311973 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
[email protected]32145a92012-12-17 09:01:5911974 width, height, format, type};
[email protected]c8021e02014-03-27 06:10:1211975 AsyncMemoryParams mem_params(
11976 GetSharedMemoryBuffer(c.data_shm_id), c.data_shm_offset, data_size);
[email protected]896425e2013-06-12 17:27:1811977 AsyncPixelTransferDelegate* delegate =
11978 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
11979 if (!delegate) {
[email protected]5b3a8e02013-03-13 05:36:4411980 // TODO(epenner): We may want to enforce exclusive use
11981 // of async APIs in which case this should become an error,
11982 // (the texture should have been async defined).
[email protected]2a7568a2013-05-09 23:12:0311983 AsyncTexImage2DParams define_params = {target, level,
[email protected]5b3a8e02013-03-13 05:36:4411984 0, 0, 0, 0, 0, 0};
11985 texture->GetLevelSize(target, level, &define_params.width,
11986 &define_params.height);
11987 texture->GetLevelType(target, level, &define_params.type,
11988 &define_params.internal_format);
11989 // Set up the async state if needed, and make the texture
11990 // immutable so the async state stays valid.
[email protected]896425e2013-06-12 17:27:1811991 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate(
[email protected]85a4ac22013-05-31 01:58:4711992 texture_ref, define_params);
[email protected]5b3a8e02013-03-13 05:36:4411993 texture->SetImmutable(true);
11994 }
11995
[email protected]896425e2013-06-12 17:27:1811996 delegate->AsyncTexSubImage2D(tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5911997 return error::kNoError;
[email protected]69023942012-11-30 19:57:1611998}
11999
[email protected]a00c1f742013-03-05 17:02:1612000error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3412001 uint32 immediate_data_size,
12002 const void* cmd_data) {
12003 const gles2::cmds::WaitAsyncTexImage2DCHROMIUM& c =
12004 *static_cast<const gles2::cmds::WaitAsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]a00c1f742013-03-05 17:02:1612005 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
12006 GLenum target = static_cast<GLenum>(c.target);
12007
12008 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5112009 LOCAL_SET_GL_ERROR(
12010 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1612011 return error::kNoError;
12012 }
[email protected]c986af502013-08-14 01:04:4412013 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
12014 &state_, target);
[email protected]370eaf12013-05-18 09:19:4912015 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5112016 LOCAL_SET_GL_ERROR(
12017 GL_INVALID_OPERATION,
12018 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1612019 return error::kNoError;
12020 }
[email protected]896425e2013-06-12 17:27:1812021 AsyncPixelTransferDelegate* delegate =
12022 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
12023 if (!delegate) {
[email protected]370eaf12013-05-18 09:19:4912024 LOCAL_SET_GL_ERROR(
12025 GL_INVALID_OPERATION,
12026 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
12027 return error::kNoError;
12028 }
[email protected]896425e2013-06-12 17:27:1812029 delegate->WaitForTransferCompletion();
[email protected]69a8701e2013-03-07 21:31:0912030 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1612031 return error::kNoError;
12032}
12033
[email protected]e3c4a9ab2014-03-31 09:07:0212034error::Error GLES2DecoderImpl::HandleWaitAllAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3412035 uint32 immediate_data_size,
12036 const void* data) {
[email protected]e3c4a9ab2014-03-31 09:07:0212037 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
12038
12039 GetAsyncPixelTransferManager()->WaitAllAsyncTexImage2D();
12040 ProcessFinishedAsyncTransfers();
12041 return error::kNoError;
12042}
12043
zmo8fab00c2015-02-07 02:45:0512044error::Error GLES2DecoderImpl::HandleUniformBlockBinding(
12045 uint32_t immediate_data_size, const void* cmd_data) {
12046 if (!unsafe_es3_apis_enabled())
12047 return error::kUnknownCommand;
12048 const gles2::cmds::UniformBlockBinding& c =
12049 *static_cast<const gles2::cmds::UniformBlockBinding*>(cmd_data);
12050 GLuint client_id = c.program;
12051 GLuint index = static_cast<GLuint>(c.index);
12052 GLuint binding = static_cast<GLuint>(c.binding);
12053 Program* program = GetProgramInfoNotShader(
12054 client_id, "glUniformBlockBinding");
12055 if (!program) {
12056 return error::kNoError;
12057 }
12058 GLuint service_id = program->service_id();
12059 glUniformBlockBinding(service_id, index, binding);
12060 return error::kNoError;
12061}
12062
zmo3366957e2015-02-18 23:40:0712063error::Error GLES2DecoderImpl::HandleClientWaitSync(
12064 uint32_t immediate_data_size, const void* cmd_data) {
12065 if (!unsafe_es3_apis_enabled())
12066 return error::kUnknownCommand;
12067 const gles2::cmds::ClientWaitSync& c =
12068 *static_cast<const gles2::cmds::ClientWaitSync*>(cmd_data);
12069 GLuint sync = static_cast<GLuint>(c.sync);
12070 GLbitfield flags = static_cast<GLbitfield>(c.flags);
12071 GLuint64 timeout = GLES2Util::MapTwoUint32ToUint64(c.timeout_0, c.timeout_1);
12072 typedef cmds::ClientWaitSync::Result Result;
12073 Result* result_dst = GetSharedMemoryAs<Result*>(
12074 c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
12075 if (!result_dst) {
12076 return error::kOutOfBounds;
12077 }
12078 if (*result_dst != GL_WAIT_FAILED) {
12079 return error::kInvalidArguments;
12080 }
12081 GLsync service_sync = 0;
12082 if (!group_->GetSyncServiceId(sync, &service_sync)) {
12083 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "ClientWaitSync", "invalid sync");
12084 return error::kNoError;
12085 }
12086 *result_dst = glClientWaitSync(service_sync, flags, timeout);
12087 return error::kNoError;
12088}
12089
[email protected]91c94eb2013-10-22 10:32:5412090void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer(
12091 TextureRef* texture_ref) {
12092 Texture* texture = texture_ref->texture();
12093 DoDidUseTexImageIfNeeded(texture, texture->target());
12094}
12095
oetuaho37cc50e2014-10-31 11:19:2012096void GLES2DecoderImpl::OnContextLostError() {
12097 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB);
12098}
12099
[email protected]828a3932014-04-02 14:43:1312100void GLES2DecoderImpl::OnOutOfMemoryError() {
12101 if (lose_context_when_out_of_memory_) {
12102 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]828a3932014-04-02 14:43:1312103 }
12104}
12105
[email protected]96449d2c2009-11-25 00:01:3212106// Include the auto-generated part of this file. We split this because it means
12107// we can easily edit the non-auto generated parts right here in this file
12108// instead of having to edit some template or the code generator.
12109#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
12110
12111} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2512112} // namespace gpu