blob: e86a776da62499e037aab99ddb9f1df3042ef4ef [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]1078f912011-12-23 13:12:1420#include "base/debug/trace_event.h"
[email protected]b2e92592014-01-10 15:47:1521#include "base/debug/trace_event_synthetic_delay.h"
[email protected]5aa95ac2014-08-14 15:20:5622#include "base/float_util.h"
[email protected]3b63f8f42011-03-28 01:54:1523#include "base/memory/scoped_ptr.h"
[email protected]e3c4a9ab2014-03-31 09:07:0224#include "base/numerics/safe_math.h"
[email protected]f4390962013-06-11 07:29:2225#include "base/strings/string_number_conversions.h"
[email protected]6d668892013-12-04 21:37:1226#include "base/strings/string_split.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(
1166 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1167 const std::string& name_str);
1168
1169 error::Error GetUniformLocationHelper(
1170 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1171 const std::string& name_str);
1172
zmo1bb3d1d2015-01-21 20:29:431173 // Wrapper for glShaderSource.
1174 void DoShaderSource(
1175 GLuint client_id, GLsizei count, const char** data, const GLint* length);
[email protected]07f54fcc2009-12-22 02:46:301176
[email protected]0d6bfdc2011-11-02 01:32:201177 // Clear any textures used by the current program.
1178 bool ClearUnclearedTextures();
1179
[email protected]0d6bfdc2011-11-02 01:32:201180 // Clears any uncleared attachments attached to the given frame buffer.
1181 // Returns false if there was a generated GL error.
[email protected]4d8f0dd2013-03-09 14:37:061182 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
[email protected]3a2e7c7b2010-08-06 01:12:281183
[email protected]0d6bfdc2011-11-02 01:32:201184 // overridden from GLES2Decoder
dcheng1f4d1d72014-10-21 16:21:581185 bool ClearLevel(unsigned service_id,
1186 unsigned bind_target,
1187 unsigned target,
1188 int level,
1189 unsigned internal_format,
1190 unsigned format,
1191 unsigned type,
1192 int width,
1193 int height,
1194 bool is_texture_immutable) override;
[email protected]0d6bfdc2011-11-02 01:32:201195
[email protected]c007aa02010-09-02 22:22:401196 // Restore all GL state that affects clearing.
1197 void RestoreClearState();
1198
[email protected]3a2e7c7b2010-08-06 01:12:281199 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461200 // Returns: true if glEnable/glDisable should actually be called.
1201 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281202
[email protected]0d6bfdc2011-11-02 01:32:201203 // Check that the currently bound framebuffers are valid.
1204 // Generates GL error if not.
1205 bool CheckBoundFramebuffersValid(const char* func_name);
1206
[email protected]2ea5950d2014-07-09 18:20:341207 // Check that the currently bound read framebuffer has a color image
1208 // attached. Generates GL error if not.
1209 bool CheckBoundReadFramebufferColorAttachment(const char* func_name);
1210
zmo383512cf2014-10-14 00:11:001211 // Check that the currently bound read framebuffer's color image
1212 // isn't the target texture of the glCopyTex{Sub}Image2D.
1213 bool FormsTextureCopyingFeedbackLoop(TextureRef* texture, GLint level);
1214
[email protected]0d6bfdc2011-11-02 01:32:201215 // Check if a framebuffer meets our requirements.
1216 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351217 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201218 GLenum target,
1219 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271220
orglofchcad5a6742014-11-07 19:51:121221 // Check if the current valuebuffer exists and is valid. If not generates
1222 // the appropriate GL error. Returns true if the current valuebuffer is in
1223 // a usable state.
1224 bool CheckCurrentValuebuffer(const char* function_name);
1225
1226 // Check if the current valuebuffer exists and is valiud and that the
1227 // value buffer is actually subscribed to the given subscription
1228 bool CheckCurrentValuebufferForSubscription(GLenum subscription,
1229 const char* function_name);
1230
1231 // Check if the location can be used for the given subscription target. If not
1232 // generates the appropriate GL error. Returns true if the location is usable
1233 bool CheckSubscriptionTarget(GLint location,
1234 GLenum subscription,
1235 const char* function_name);
1236
[email protected]939e7362010-05-13 20:49:101237 // Checks if the current program exists and is valid. If not generates the
1238 // appropriate GL error. Returns true if the current program is in a usable
1239 // state.
1240 bool CheckCurrentProgram(const char* function_name);
1241
1242 // Checks if the current program exists and is valid and that location is not
1243 // -1. If the current program is not valid generates the appropriate GL
1244 // error. Returns true if the current program is in a usable state and
1245 // location is not -1.
1246 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1247
zmof9a81360f2014-10-17 00:06:141248 // Checks if the current program samples a texture that is also the color
1249 // image of the current bound framebuffer, i.e., the source and destination
1250 // of the draw operation are the same.
1251 bool CheckDrawingFeedbackLoops();
1252
orglofchcad5a6742014-11-07 19:51:121253 // Checks if |api_type| is valid for the given uniform
1254 // If the api type is not valid generates the appropriate GL
1255 // error. Returns true if |api_type| is valid for the uniform
1256 bool CheckUniformForApiType(const Program::UniformInfo* info,
1257 const char* function_name,
1258 Program::UniformApiType api_type);
1259
[email protected]939e7362010-05-13 20:49:101260 // Gets the type of a uniform for a location in the current program. Sets GL
1261 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361262 // program is valid and the location exists. Adjusts count so it
1263 // does not overflow the uniform.
[email protected]9b1f1b52014-03-12 10:40:131264 bool PrepForSetUniformByLocation(GLint fake_location,
1265 const char* function_name,
1266 Program::UniformApiType api_type,
1267 GLint* real_location,
1268 GLenum* type,
1269 GLsizei* count);
[email protected]939e7362010-05-13 20:49:101270
[email protected]b177ae22011-11-01 03:29:111271 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021272 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111273
[email protected]b273e432010-04-12 17:23:581274 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1275 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1276
[email protected]ac77603c72013-03-08 13:52:061277 // Helper for glGetVertexAttrib
1278 void GetVertexAttribHelper(
1279 const VertexAttrib* attrib, GLenum pname, GLint* param);
1280
[email protected]96449d2c2009-11-25 00:01:321281 // Wrapper for glCreateProgram
[email protected]ae51d192010-04-27 00:48:031282 bool CreateProgramHelper(GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321283
1284 // Wrapper for glCreateShader
[email protected]ae51d192010-04-27 00:48:031285 bool CreateShaderHelper(GLenum type, GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321286
[email protected]3916c97e2010-02-25 03:20:501287 // Wrapper for glActiveTexture
1288 void DoActiveTexture(GLenum texture_unit);
1289
[email protected]ae51d192010-04-27 00:48:031290 // Wrapper for glAttachShader
1291 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1292
[email protected]96449d2c2009-11-25 00:01:321293 // Wrapper for glBindBuffer since we need to track the current targets.
1294 void DoBindBuffer(GLenum target, GLuint buffer);
1295
[email protected]86093972010-03-11 00:13:561296 // Wrapper for glBindFramebuffer since we need to track the current targets.
1297 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1298
1299 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1300 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1301
[email protected]a93bb842010-02-16 23:03:471302 // Wrapper for glBindTexture since we need to track the current targets.
1303 void DoBindTexture(GLenum target, GLuint texture);
1304
[email protected]944b62f32012-09-27 02:20:461305 // Wrapper for glBindVertexArrayOES
1306 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571307 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461308
[email protected]49cabed2013-11-13 18:15:181309 // Wrapper for glBlitFramebufferCHROMIUM.
1310 void DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301311 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1312 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1313 GLbitfield mask, GLenum filter);
1314
[email protected]36cef8ce2010-03-16 07:34:451315 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111316 void DoBufferSubData(
1317 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1318
[email protected]36cef8ce2010-03-16 07:34:451319 // Wrapper for glCheckFramebufferStatus
1320 GLenum DoCheckFramebufferStatus(GLenum target);
1321
[email protected]3a03a8f2011-03-19 00:51:271322 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081323 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271324
[email protected]88a61bf2012-10-27 13:00:421325 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421326 void DoDepthRangef(GLclampf znear, GLclampf zfar);
[email protected]b04e24c2013-01-08 18:35:251327 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281328
[email protected]45bf5152010-02-12 00:11:311329 // Wrapper for glCompileShader.
1330 void DoCompileShader(GLuint shader);
1331
[email protected]ae51d192010-04-27 00:48:031332 // Wrapper for glDetachShader
1333 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1334
[email protected]3a2e7c7b2010-08-06 01:12:281335 // Wrapper for glDisable
1336 void DoDisable(GLenum cap);
1337
[email protected]07f54fcc2009-12-22 02:46:301338 // Wrapper for glDisableVertexAttribArray.
1339 void DoDisableVertexAttribArray(GLuint index);
1340
[email protected]60f22d32012-12-12 00:31:581341 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1342 // attachments.
1343 void DoDiscardFramebufferEXT(GLenum target,
1344 GLsizei numAttachments,
1345 const GLenum* attachments);
1346
[email protected]3a2e7c7b2010-08-06 01:12:281347 // Wrapper for glEnable
1348 void DoEnable(GLenum cap);
1349
[email protected]07f54fcc2009-12-22 02:46:301350 // Wrapper for glEnableVertexAttribArray.
1351 void DoEnableVertexAttribArray(GLuint index);
1352
[email protected]882ba1e22012-03-08 19:02:531353 // Wrapper for glFinish.
1354 void DoFinish();
1355
1356 // Wrapper for glFlush.
1357 void DoFlush();
1358
[email protected]36cef8ce2010-03-16 07:34:451359 // Wrapper for glFramebufferRenderbufffer.
1360 void DoFramebufferRenderbuffer(
1361 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1362 GLuint renderbuffer);
1363
1364 // Wrapper for glFramebufferTexture2D.
1365 void DoFramebufferTexture2D(
1366 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1367 GLint level);
1368
[email protected]7d3c36e2013-07-12 14:13:161369 // Wrapper for glFramebufferTexture2DMultisampleEXT.
1370 void DoFramebufferTexture2DMultisample(
1371 GLenum target, GLenum attachment, GLenum textarget,
1372 GLuint texture, GLint level, GLsizei samples);
1373
1374 // Common implementation for both DoFramebufferTexture2D wrappers.
1375 void DoFramebufferTexture2DCommon(const char* name,
1376 GLenum target, GLenum attachment, GLenum textarget,
1377 GLuint texture, GLint level, GLsizei samples);
1378
zmo84c08202014-11-23 15:28:401379 // Wrapper for glFramebufferTextureLayer.
1380 void DoFramebufferTextureLayer(
1381 GLenum target, GLenum attachment, GLuint texture, GLint level,
1382 GLint layer);
1383
[email protected]a93bb842010-02-16 23:03:471384 // Wrapper for glGenerateMipmap
1385 void DoGenerateMipmap(GLenum target);
1386
[email protected]7d3c36e2013-07-12 14:13:161387 // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname
1388 // to account for different pname values defined in different extension
1389 // variants.
1390 GLenum AdjustGetPname(GLenum pname);
1391
[email protected]b273e432010-04-12 17:23:581392 // Wrapper for DoGetBooleanv.
1393 void DoGetBooleanv(GLenum pname, GLboolean* params);
1394
1395 // Wrapper for DoGetFloatv.
1396 void DoGetFloatv(GLenum pname, GLfloat* params);
1397
[email protected]36cef8ce2010-03-16 07:34:451398 // Wrapper for glGetFramebufferAttachmentParameteriv.
1399 void DoGetFramebufferAttachmentParameteriv(
1400 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1401
[email protected]a0c3e972010-04-21 00:49:131402 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581403 void DoGetIntegerv(GLenum pname, GLint* params);
1404
[email protected]29a9eb52010-04-13 09:04:231405 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061406 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231407 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1408
[email protected]17cfbe0e2013-03-07 01:26:081409 // Wrapper for glGetBufferParameteriv.
1410 void DoGetBufferParameteriv(
1411 GLenum target, GLenum pname, GLint* params);
1412
[email protected]a0c3e972010-04-21 00:49:131413 // Wrapper for glGetProgramiv.
1414 void DoGetProgramiv(
1415 GLuint program_id, GLenum pname, GLint* params);
1416
[email protected]36cef8ce2010-03-16 07:34:451417 // Wrapper for glRenderbufferParameteriv.
1418 void DoGetRenderbufferParameteriv(
1419 GLenum target, GLenum pname, GLint* params);
1420
[email protected]ddd968b82010-03-02 00:44:291421 // Wrapper for glGetShaderiv
1422 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1423
[email protected]4c6f5462014-03-05 00:26:561424 // Wrappers for glGetTexParameter.
1425 void DoGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
1426 void DoGetTexParameteriv(GLenum target, GLenum pname, GLint* params);
1427 void InitTextureMaxAnisotropyIfNeeded(GLenum target, GLenum pname);
1428
[email protected]b1122982010-05-17 23:04:241429 // Wrappers for glGetVertexAttrib.
1430 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1431 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1432
[email protected]1958e0e2010-04-22 05:17:151433 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241434 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151435 bool DoIsBuffer(GLuint client_id);
1436 bool DoIsFramebuffer(GLuint client_id);
1437 bool DoIsProgram(GLuint client_id);
1438 bool DoIsRenderbuffer(GLuint client_id);
1439 bool DoIsShader(GLuint client_id);
1440 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461441 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151442
[email protected]07f54fcc2009-12-22 02:46:301443 // Wrapper for glLinkProgram
1444 void DoLinkProgram(GLuint program);
1445
[email protected]36cef8ce2010-03-16 07:34:451446 // Wrapper for glRenderbufferStorage.
1447 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031448 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451449
[email protected]49cabed2013-11-13 18:15:181450 // Handler for glRenderbufferStorageMultisampleCHROMIUM.
1451 void DoRenderbufferStorageMultisampleCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301452 GLenum target, GLsizei samples, GLenum internalformat,
1453 GLsizei width, GLsizei height);
1454
[email protected]49cabed2013-11-13 18:15:181455 // Handler for glRenderbufferStorageMultisampleEXT
1456 // (multisampled_render_to_texture).
1457 void DoRenderbufferStorageMultisampleEXT(
1458 GLenum target, GLsizei samples, GLenum internalformat,
1459 GLsizei width, GLsizei height);
1460
1461 // Common validation for multisample extensions.
1462 bool ValidateRenderbufferStorageMultisample(GLsizei samples,
1463 GLenum internalformat,
1464 GLsizei width,
1465 GLsizei height);
1466
[email protected]4a4c18b2013-09-13 22:50:101467 // Verifies that the currently bound multisample renderbuffer is valid
1468 // Very slow! Only done on platforms with driver bugs that return invalid
1469 // buffers under memory pressure
1470 bool VerifyMultisampleRenderbufferIntegrity(
1471 GLuint renderbuffer, GLenum format);
1472
[email protected]b273e432010-04-12 17:23:581473 // Wrapper for glReleaseShaderCompiler.
1474 void DoReleaseShaderCompiler() { }
1475
zmobcb3fdd62014-12-11 00:49:031476 // Wrappers for glSamplerParameter*v functions.
1477 void DoSamplerParameterfv(
1478 GLuint sampler, GLenum pname, const GLfloat* params);
1479 void DoSamplerParameteriv(GLuint sampler, GLenum pname, const GLint* params);
1480
[email protected]3916c97e2010-02-25 03:20:501481 // Wrappers for glTexParameter functions.
1482 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1483 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1484 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1485 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1486
1487 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1488 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121489 void DoUniform1i(GLint fake_location, GLint v0);
1490 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1491 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1492 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1493 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101494
1495 // Wrappers for glUniformfv because some drivers don't correctly accept
1496 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121497 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1498 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1499 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1500 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501501
[email protected]43c2f1f2011-03-25 18:35:361502 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121503 GLint fake_location, GLsizei count, GLboolean transpose,
1504 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361505 void DoUniformMatrix3fv(
[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 DoUniformMatrix4fv(
[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
[email protected]af6380962012-11-29 23:24:131512 bool SetVertexAttribValue(
1513 const char* function_name, GLuint index, const GLfloat* value);
1514
[email protected]b1122982010-05-17 23:04:241515 // Wrappers for glVertexAttrib??
1516 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1517 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1518 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1519 void DoVertexAttrib4f(
1520 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1521 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1522 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1523 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1524 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1525
[email protected]43410e92012-04-20 17:06:281526 // Wrapper for glViewport
1527 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1528
[email protected]07f54fcc2009-12-22 02:46:301529 // Wrapper for glUseProgram
1530 void DoUseProgram(GLuint program);
1531
[email protected]ae51d192010-04-27 00:48:031532 // Wrapper for glValidateProgram.
1533 void DoValidateProgram(GLuint program_client_id);
1534
[email protected]d2a0e1a2012-08-12 02:25:011535 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1536 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1537 void DoPopGroupMarkerEXT(void);
1538
[email protected]4e8a5b122010-05-08 22:00:101539 // Gets the number of values that will be returned by glGetXXX. Returns
1540 // false if pname is unknown.
1541 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1542
[email protected]07f54fcc2009-12-22 02:46:301543 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431544 bool IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:101545 const char* function_name, GLuint max_vertex_accessed, bool instanced,
1546 GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301547
[email protected]c13e1da62011-09-09 21:48:301548 // Returns true if successful, simulated will be true if attrib0 was
1549 // simulated.
[email protected]c6aef902012-02-14 03:31:421550 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431551 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]3fc38e22014-05-30 00:13:231552 void RestoreStateForAttrib(GLuint attrib, bool restore_array_binding);
[email protected]b1122982010-05-17 23:04:241553
[email protected]91c94eb2013-10-22 10:32:541554 // If an image is bound to texture, this will call Will/DidUseTexImage
1555 // if needed.
1556 void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1557 void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1558
1559 // Returns false if textures were replaced.
[email protected]e56131d22013-07-28 16:14:111560 bool PrepareTexturesForRender();
[email protected]91c94eb2013-10-22 10:32:541561 void RestoreStateForTextures();
[email protected]3916c97e2010-02-25 03:20:501562
[email protected]8fbedc02010-11-18 18:43:401563 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421564 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431565 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421566 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401567 void RestoreStateForSimulatedFixedAttribs();
1568
[email protected]c6aef902012-02-14 03:31:421569 // Handle DrawArrays and DrawElements for both instanced and non-instanced
[email protected]ac6904d62014-07-30 12:00:101570 // cases (primcount is always 1 for non-instanced).
[email protected]c6aef902012-02-14 03:31:421571 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431572 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421573 bool instanced, GLenum mode, GLint first, GLsizei count,
1574 GLsizei primcount);
1575 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431576 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421577 bool instanced, GLenum mode, GLsizei count, GLenum type,
1578 int32 offset, GLsizei primcount);
1579
[email protected]61eeb33f2011-07-26 15:30:311580 GLenum GetBindTargetForSamplerType(GLenum type) {
1581 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461582 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1583 switch (type) {
1584 case GL_SAMPLER_2D:
1585 return GL_TEXTURE_2D;
1586 case GL_SAMPLER_CUBE:
1587 return GL_TEXTURE_CUBE_MAP;
1588 case GL_SAMPLER_EXTERNAL_OES:
1589 return GL_TEXTURE_EXTERNAL_OES;
1590 case GL_SAMPLER_2D_RECT_ARB:
1591 return GL_TEXTURE_RECTANGLE_ARB;
1592 }
1593
1594 NOTREACHED();
1595 return 0;
[email protected]61eeb33f2011-07-26 15:30:311596 }
1597
[email protected]8e3e0662010-08-23 18:46:301598 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061599 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1600 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301601 switch (target) {
1602 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451603 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341604 framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301605 break;
[email protected]ebfb73c2012-08-15 02:37:451606 case GL_READ_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341607 framebuffer = framebuffer_state_.bound_read_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301608 break;
1609 default:
1610 NOTREACHED();
1611 break;
1612 }
[email protected]4d8f0dd2013-03-09 14:37:061613 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301614 }
1615
[email protected]ed9f9cd2013-02-27 21:12:351616 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201617 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271618 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201619 switch (target) {
1620 case GL_RENDERBUFFER:
[email protected]7cd76fd2013-06-02 21:11:111621 renderbuffer = state_.bound_renderbuffer.get();
[email protected]0d6bfdc2011-11-02 01:32:201622 break;
1623 default:
1624 NOTREACHED();
1625 break;
1626 }
[email protected]ee2a79c32013-03-10 03:50:271627 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201628 }
1629
[email protected]f7b85372010-02-03 01:11:371630 // Validates the program and location for a glGetUniform call and returns
1631 // a SizeResult setup to receive the result. Returns true if glGetUniform
1632 // should be called.
1633 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121634 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371635 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121636 error::Error* error, GLint* real_location, GLuint* service_id,
1637 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371638
jbauman7a059312014-10-16 19:30:541639 void MaybeExitOnContextLost();
dcheng1f4d1d72014-10-21 16:21:581640 bool WasContextLost() override;
1641 bool WasContextLostByRobustnessExtension() override;
1642 void LoseContext(uint32 reset_status) override;
[email protected]38d139d2011-07-14 00:38:431643
[email protected]e51bdf32011-11-23 22:21:461644#if defined(OS_MACOSX)
1645 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1646#endif
1647
[email protected]ad84a3a2012-06-08 21:42:431648 bool ValidateCompressedTexDimensions(
1649 const char* function_name,
1650 GLint level, GLsizei width, GLsizei height, GLenum format);
1651 bool ValidateCompressedTexFuncData(
1652 const char* function_name,
1653 GLsizei width, GLsizei height, GLenum format, size_t size);
1654 bool ValidateCompressedTexSubDimensions(
1655 const char* function_name,
1656 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1657 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351658 Texture* texture);
[email protected]ad84a3a2012-06-08 21:42:431659
[email protected]ab09b612013-03-11 22:11:511660 void RenderWarning(const char* filename, int line, const std::string& msg);
1661 void PerformanceWarning(
1662 const char* filename, int line, const std::string& msg);
[email protected]0f8afe82012-05-14 23:43:011663
[email protected]62e155e2012-10-23 22:43:151664 const FeatureInfo::FeatureFlags& features() const {
1665 return feature_info_->feature_flags();
1666 }
1667
1668 const FeatureInfo::Workarounds& workarounds() const {
1669 return feature_info_->workarounds();
1670 }
1671
[email protected]a7266a92012-06-28 02:11:081672 bool ShouldDeferDraws() {
1673 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341674 framebuffer_state_.bound_draw_framebuffer.get() == NULL &&
[email protected]a7266a92012-06-28 02:11:081675 surface_->DeferDraws();
1676 }
1677
[email protected]09e17272012-11-30 10:30:441678 bool ShouldDeferReads() {
1679 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341680 framebuffer_state_.bound_read_framebuffer.get() == NULL &&
[email protected]09e17272012-11-30 10:30:441681 surface_->DeferDraws();
1682 }
1683
[email protected]c76fe672013-12-13 23:30:221684 error::Error WillAccessBoundFramebufferForDraw() {
1685 if (ShouldDeferDraws())
1686 return error::kDeferCommandUntilLater;
1687 if (!offscreen_target_frame_buffer_.get() &&
1688 !framebuffer_state_.bound_draw_framebuffer.get() &&
1689 !surface_->SetBackbufferAllocation(true))
1690 return error::kLostContext;
1691 return error::kNoError;
1692 }
1693
1694 error::Error WillAccessBoundFramebufferForRead() {
1695 if (ShouldDeferReads())
1696 return error::kDeferCommandUntilLater;
1697 if (!offscreen_target_frame_buffer_.get() &&
1698 !framebuffer_state_.bound_read_framebuffer.get() &&
1699 !surface_->SetBackbufferAllocation(true))
1700 return error::kLostContext;
1701 return error::kNoError;
1702 }
1703
vmiura8266ca72014-09-09 21:37:001704 // Set remaining commands to process to 0 to force DoCommands to return
1705 // and allow context preemption and GPU watchdog checks in GpuScheduler().
1706 void ExitCommandProcessingEarly() { commands_to_process_ = 0; }
1707
[email protected]5a36dc132013-07-23 23:17:551708 void ProcessPendingReadPixels();
1709 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
1710
[email protected]96449d2c2009-11-25 00:01:321711 // Generate a member function prototype for each command in an automated and
1712 // typesafe way.
vmiuracd108592014-09-08 14:36:341713#define GLES2_CMD_OP(name) \
1714 Error Handle##name(uint32 immediate_data_size, const void* data);
[email protected]96449d2c2009-11-25 00:01:321715
1716 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1717
1718 #undef GLES2_CMD_OP
1719
[email protected]2f2d7042010-04-14 21:45:581720 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381721 scoped_refptr<gfx::GLSurface> surface_;
1722 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021723
[email protected]a3ded6d2010-10-19 06:44:391724 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351725 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391726
[email protected]1d82e822013-04-10 21:32:321727 DebugMarkerManager debug_marker_manager_;
1728 Logger logger_;
1729
[email protected]e259eb412012-10-13 05:47:241730 // All the state for this context.
1731 ContextState state_;
1732
[email protected]34ff8b0c2010-10-01 20:06:021733 // Current width and height of the offscreen frame buffer.
1734 gfx::Size offscreen_size_;
1735
[email protected]96449d2c2009-11-25 00:01:321736 // Util to help with GL.
1737 GLES2Util util_;
1738
[email protected]43410e92012-04-20 17:06:281739 // unpack flip y as last set by glPixelStorei
1740 bool unpack_flip_y_;
1741
[email protected]6c75c712012-06-19 15:43:171742 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281743 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171744 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281745
[email protected]b1122982010-05-17 23:04:241746 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1747 GLuint attrib_0_buffer_id_;
1748
1749 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131750 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241751
[email protected]fc753442011-02-04 19:49:491752 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1753 bool attrib_0_buffer_matches_value_;
1754
[email protected]b1122982010-05-17 23:04:241755 // The size of attrib 0.
1756 GLsizei attrib_0_size_;
1757
[email protected]8fbedc02010-11-18 18:43:401758 // The buffer used to simulate GL_FIXED attribs.
1759 GLuint fixed_attrib_buffer_id_;
1760
1761 // The size of fiixed attrib buffer.
1762 GLsizei fixed_attrib_buffer_size_;
1763
[email protected]b9363b22010-06-09 22:06:151764 // The offscreen frame buffer that the client renders to. With EGL, the
1765 // depth and stencil buffers are separate. With regular GL there is a single
1766 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1767 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351768 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1769 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1770 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1771 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1772 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021773 GLenum offscreen_target_color_format_;
1774 GLenum offscreen_target_depth_format_;
1775 GLenum offscreen_target_stencil_format_;
1776 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561777 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351778
[email protected]de26b3c2011-08-03 21:54:271779 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351780 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1781 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
[email protected]370eaf12013-05-18 09:19:491782 scoped_refptr<TextureRef>
[email protected]ed9f9cd2013-02-27 21:12:351783 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271784
1785 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351786 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1787 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051788 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351789
[email protected]882ba1e22012-03-08 19:02:531790 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531791
[email protected]944b62f32012-09-27 02:20:461792 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1793
[email protected]b63f1d62014-07-18 15:40:591794 scoped_ptr<ImageManager> image_manager_;
1795
[email protected]729c0b42013-05-26 02:05:071796 base::Callback<void(gfx::Size, float)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001797
[email protected]840a7e462013-02-27 01:29:511798 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481799
[email protected]e3932abb2013-03-13 00:01:371800 ShaderCacheCallback shader_cache_callback_;
1801
[email protected]85a4ac22013-05-31 01:58:471802 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
[email protected]b0af4f52011-09-28 22:04:421803
[email protected]32fe9aa2011-01-21 23:47:131804 // The format of the back buffer_
1805 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461806 bool back_buffer_has_depth_;
1807 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131808
achaulkcf5316f2014-09-26 19:28:421809 bool surfaceless_;
1810
[email protected]60f22d32012-12-12 00:31:581811 // Backbuffer attachments that are currently undefined.
1812 uint32 backbuffer_needs_clear_bits_;
1813
[email protected]a6a09f852014-05-23 13:05:031814 // The current decoder error communicates the decoder error through command
1815 // processing functions that do not return the error value. Should be set only
1816 // if not returning an error.
[email protected]a3a93e7b2010-08-28 00:48:561817 error::Error current_decoder_error_;
1818
[email protected]b1d2dcb2010-05-17 19:24:181819 bool use_shader_translator_;
[email protected]87fb6ab2012-06-13 22:28:041820 scoped_refptr<ShaderTranslator> vertex_translator_;
1821 scoped_refptr<ShaderTranslator> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181822
[email protected]e82fb792011-09-22 00:33:291823 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411824
[email protected]915a59a12010-09-30 21:29:111825 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051826 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351827 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051828
[email protected]65225772011-05-12 21:10:241829 int frame_number_;
1830
vmiura8266ca72014-09-09 21:37:001831 // Number of commands remaining to be processed in DoCommands().
1832 int commands_to_process_;
1833
[email protected]706b69f2012-07-27 04:59:301834 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431835 GLenum reset_status_;
[email protected]93a7d98f2013-07-11 00:04:221836 bool reset_by_robustness_extension_;
[email protected]b381ee32014-03-22 02:43:431837 bool supports_post_sub_buffer_;
[email protected]38d139d2011-07-14 00:38:431838
[email protected]f0d74742011-10-03 16:31:041839 // These flags are used to override the state of the shared feature_info_
1840 // member. Because the same FeatureInfo instance may be shared among many
1841 // contexts, the assumptions on the availablity of extensions in WebGL
1842 // contexts may be broken. These flags override the shared state to preserve
1843 // WebGL semantics.
1844 bool force_webgl_glsl_validation_;
1845 bool derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:491846 bool frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:131847 bool draw_buffers_explicitly_enabled_;
[email protected]93c2fd82014-04-16 02:46:061848 bool shader_texture_lod_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:041849
[email protected]062c38b2012-01-18 03:25:101850 bool compile_shader_always_succeeds_;
1851
[email protected]828a3932014-04-02 14:43:131852 // An optional behaviour to lose the context and group when OOM.
1853 bool lose_context_when_out_of_memory_;
1854
[email protected]cae20172012-12-07 00:06:191855 // Log extra info.
1856 bool service_logging_;
1857
[email protected]e51bdf32011-11-23 22:21:461858#if defined(OS_MACOSX)
[email protected]c3a6b4a2014-06-04 09:25:531859 typedef std::map<GLuint, IOSurfaceRef> TextureToIOSurfaceMap;
[email protected]e51bdf32011-11-23 22:21:461860 TextureToIOSurfaceMap texture_to_io_surface_map_;
1861#endif
1862
[email protected]43410e92012-04-20 17:06:281863 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
sievers2384f2b2014-11-18 02:10:351864 scoped_ptr<ClearFramebufferResourceManager> clear_framebuffer_blit_;
[email protected]43410e92012-04-20 17:06:281865
[email protected]1868a342012-11-07 15:56:021866 // Cached values of the currently assigned viewport dimensions.
1867 GLsizei viewport_max_width_;
1868 GLsizei viewport_max_height_;
1869
[email protected]63b465922012-09-06 02:04:521870 // Command buffer stats.
[email protected]63b465922012-09-06 02:04:521871 base::TimeDelta total_processing_commands_time_;
1872
[email protected]c986af502013-08-14 01:04:441873 // States related to each manager.
1874 DecoderTextureState texture_state_;
1875 DecoderFramebufferState framebuffer_state_;
1876
[email protected]fb97b662013-02-20 23:02:141877 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]8f9b8dd2013-09-12 18:05:131878 scoped_ptr<GPUStateTracer> gpu_state_tracer_;
vmiura1c2b1de2014-09-19 19:03:241879 const unsigned char* cb_command_trace_category_;
dyencb86f2f2014-12-09 18:35:411880 const unsigned char* gpu_decoder_category_;
[email protected]cac16542014-01-15 17:53:511881 int gpu_trace_level_;
1882 bool gpu_trace_commands_;
vmiura1c2b1de2014-09-19 19:03:241883 bool gpu_debug_commands_;
[email protected]94307712012-11-16 23:26:111884
[email protected]5a36dc132013-07-23 23:17:551885 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_;
1886
[email protected]4a4c18b2013-09-13 22:50:101887 // Used to validate multisample renderbuffers if needed
1888 GLuint validation_texture_;
1889 GLuint validation_fbo_multisample_;
1890 GLuint validation_fbo_;
1891
vmiuracd108592014-09-08 14:36:341892 typedef gpu::gles2::GLES2Decoder::Error (GLES2DecoderImpl::*CmdHandler)(
1893 uint32 immediate_data_size,
1894 const void* data);
1895
1896 // A struct to hold info about each command.
1897 struct CommandInfo {
1898 CmdHandler cmd_handler;
1899 uint8 arg_flags; // How to handle the arguments for this command
1900 uint8 cmd_flags; // How to handle this command
1901 uint16 arg_count; // How many arguments are expected for this command.
1902 };
1903
1904 // A table of CommandInfo for all the commands.
1905 static const CommandInfo command_info[kNumCommands - kStartPoint];
1906
[email protected]96449d2c2009-11-25 00:01:321907 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1908};
1909
vmiuracd108592014-09-08 14:36:341910const GLES2DecoderImpl::CommandInfo GLES2DecoderImpl::command_info[] = {
1911#define GLES2_CMD_OP(name) \
1912 { \
1913 &GLES2DecoderImpl::Handle##name, cmds::name::kArgFlags, \
1914 cmds::name::cmd_flags, \
1915 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, \
1916 } \
1917 , /* NOLINT */
1918 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1919#undef GLES2_CMD_OP
1920};
1921
[email protected]ab09b612013-03-11 22:11:511922ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:301923 const char* function_name, ErrorState* error_state)
[email protected]ab09b612013-03-11 22:11:511924 : function_name_(function_name),
[email protected]40621eb52013-10-08 15:40:301925 error_state_(error_state) {
1926 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351927}
1928
1929ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]40621eb52013-10-08 15:40:301930 ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351931}
1932
[email protected]2b10c02d2014-01-29 16:43:021933static void RestoreCurrentTextureBindings(ContextState* state, GLenum target) {
[email protected]ce296892013-10-24 22:04:361934 TextureUnit& info = state->texture_units[0];
1935 GLuint last_id;
[email protected]2b10c02d2014-01-29 16:43:021936 scoped_refptr<TextureRef> texture_ref;
1937 switch (target) {
1938 case GL_TEXTURE_2D:
1939 texture_ref = info.bound_texture_2d;
1940 break;
1941 case GL_TEXTURE_CUBE_MAP:
1942 texture_ref = info.bound_texture_cube_map;
1943 break;
1944 case GL_TEXTURE_EXTERNAL_OES:
1945 texture_ref = info.bound_texture_external_oes;
1946 break;
1947 case GL_TEXTURE_RECTANGLE_ARB:
1948 texture_ref = info.bound_texture_rectangle_arb;
1949 break;
1950 default:
1951 NOTREACHED();
1952 break;
1953 }
1954 if (texture_ref.get()) {
1955 last_id = texture_ref->service_id();
[email protected]ce296892013-10-24 22:04:361956 } else {
1957 last_id = 0;
1958 }
1959
[email protected]2b10c02d2014-01-29 16:43:021960 glBindTexture(target, last_id);
[email protected]ce296892013-10-24 22:04:361961 glActiveTexture(GL_TEXTURE0 + state->active_texture_unit);
1962}
1963
[email protected]2b10c02d2014-01-29 16:43:021964ScopedTextureBinder::ScopedTextureBinder(ContextState* state,
1965 GLuint id,
1966 GLenum target)
1967 : state_(state),
1968 target_(target) {
[email protected]ab09b612013-03-11 22:11:511969 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021970 "ScopedTextureBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351971
1972 // TODO(apatrick): Check if there are any other states that need to be reset
1973 // before binding a new texture.
1974 glActiveTexture(GL_TEXTURE0);
[email protected]2b10c02d2014-01-29 16:43:021975 glBindTexture(target, id);
[email protected]6217d392010-03-25 22:08:351976}
1977
[email protected]2b10c02d2014-01-29 16:43:021978ScopedTextureBinder::~ScopedTextureBinder() {
[email protected]ab09b612013-03-11 22:11:511979 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021980 "ScopedTextureBinder::dtor", state_->GetErrorState());
1981 RestoreCurrentTextureBindings(state_, target_);
[email protected]6217d392010-03-25 22:08:351982}
1983
[email protected]18e785a2013-10-09 03:29:411984ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state,
[email protected]6217d392010-03-25 22:08:351985 GLuint id)
[email protected]18e785a2013-10-09 03:29:411986 : state_(state) {
[email protected]ab09b612013-03-11 22:11:511987 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411988 "ScopedRenderBufferBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351989 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1990}
1991
1992ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511993 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411994 "ScopedRenderBufferBinder::dtor", state_->GetErrorState());
1995 state_->RestoreRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:351996}
1997
1998ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1999 GLuint id)
2000 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:512001 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302002 "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352003 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:452004 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:352005}
2006
2007ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:512008 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302009 "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]8e3e0662010-08-23 18:46:302010 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:352011}
2012
[email protected]34ff8b0c2010-10-01 20:06:022013ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:272014 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:522015 : decoder_(decoder) {
[email protected]9d3b2e12013-10-02 01:04:342016 resolve_and_bind_ = (
2017 decoder_->offscreen_target_frame_buffer_.get() &&
2018 decoder_->IsOffscreenBufferMultisampled() &&
2019 (!decoder_->framebuffer_state_.bound_read_framebuffer.get() ||
2020 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:022021 if (!resolve_and_bind_)
2022 return;
2023
[email protected]ab09b612013-03-11 22:11:512024 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302025 "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:022026 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
2027 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:272028 GLuint targetid;
2029 if (internal) {
2030 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
2031 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:352032 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:272033 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:352034 decoder_->offscreen_resolved_color_texture_.reset(
[email protected]ce296892013-10-24 22:04:362035 new BackTexture(decoder->memory_tracker(), &decoder->state_));
[email protected]de26b3c2011-08-03 21:54:272036 decoder_->offscreen_resolved_color_texture_->Create();
2037
2038 DCHECK(decoder_->offscreen_saved_color_format_);
2039 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:092040 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
2041 false);
[email protected]de26b3c2011-08-03 21:54:272042 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
2043 decoder_->offscreen_resolved_color_texture_.get());
2044 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
2045 GL_FRAMEBUFFER_COMPLETE) {
2046 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
2047 << "because offscreen resolved FBO was incomplete.";
2048 return;
2049 }
2050 }
2051 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
2052 } else {
2053 targetid = decoder_->offscreen_saved_frame_buffer_->id();
2054 }
2055 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:022056 const int width = decoder_->offscreen_size_.width();
2057 const int height = decoder_->offscreen_size_.height();
[email protected]454157e2014-05-03 02:49:452058 decoder->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f42f05b2013-11-15 21:46:182059 decoder->BlitFramebufferHelper(0,
2060 0,
2061 width,
2062 height,
2063 0,
2064 0,
2065 width,
2066 height,
2067 GL_COLOR_BUFFER_BIT,
2068 GL_NEAREST);
[email protected]de26b3c2011-08-03 21:54:272069 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:022070}
2071
2072ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
2073 if (!resolve_and_bind_)
2074 return;
2075
[email protected]ab09b612013-03-11 22:11:512076 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302077 "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:022078 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:222079 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:452080 decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]8c3e68782010-10-27 16:41:182081 }
[email protected]34ff8b0c2010-10-01 20:06:022082}
2083
[email protected]ce296892013-10-24 22:04:362084BackTexture::BackTexture(
2085 MemoryTracker* memory_tracker,
2086 ContextState* state)
2087 : memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2088 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482089 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252090 id_(0) {
[email protected]6217d392010-03-25 22:08:352091}
2092
[email protected]ed9f9cd2013-02-27 21:12:352093BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:352094 // This does not destroy the render texture because that would require that
2095 // the associated GL context was current. Just check that it was explicitly
2096 // destroyed.
2097 DCHECK_EQ(id_, 0u);
2098}
2099
[email protected]ed9f9cd2013-02-27 21:12:352100void BackTexture::Create() {
[email protected]40621eb52013-10-08 15:40:302101 ScopedGLErrorSuppressor suppressor("BackTexture::Create",
[email protected]ce296892013-10-24 22:04:362102 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352103 Destroy();
2104 glGenTextures(1, &id_);
[email protected]2b10c02d2014-01-29 16:43:022105 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]eeeb07b92014-08-16 07:46:262106 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2107 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
[email protected]3a4d0c52011-06-29 23:11:582108 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2109 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:162110
2111 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
2112 // never called on an offscreen context, no data will ever be uploaded to the
2113 // saved offscreen color texture (it is deferred until to when SwapBuffers
2114 // is called). My idea is that some nvidia drivers might have a bug where
2115 // deleting a texture that has never been populated might cause a
2116 // crash.
2117 glTexImage2D(
2118 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:482119
2120 bytes_allocated_ = 16u * 16u * 4u;
2121 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:352122}
2123
[email protected]ed9f9cd2013-02-27 21:12:352124bool BackTexture::AllocateStorage(
2125 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:352126 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302127 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage",
[email protected]ce296892013-10-24 22:04:362128 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022129 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]678a73f2012-12-19 19:22:092130 uint32 image_size = 0;
2131 GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:422132 size.width(), size.height(), 1, format, GL_UNSIGNED_BYTE, 8, &image_size,
[email protected]678a73f2012-12-19 19:22:092133 NULL, NULL);
2134
[email protected]7989c9e2013-01-23 06:39:262135 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
2136 return false;
2137 }
2138
[email protected]40d90a22013-04-09 03:39:552139 scoped_ptr<char[]> zero_data;
[email protected]678a73f2012-12-19 19:22:092140 if (zero) {
2141 zero_data.reset(new char[image_size]);
2142 memset(zero_data.get(), 0, image_size);
2143 }
[email protected]6217d392010-03-25 22:08:352144
[email protected]8f1d2aa2013-05-10 23:45:382145 glTexImage2D(GL_TEXTURE_2D,
2146 0, // mip level
2147 format,
2148 size.width(),
2149 size.height(),
2150 0, // border
2151 format,
2152 GL_UNSIGNED_BYTE,
2153 zero_data.get());
[email protected]6217d392010-03-25 22:08:352154
[email protected]d37231fa2010-04-09 21:16:022155 size_ = size;
2156
[email protected]1078f912011-12-23 13:12:142157 bool success = glGetError() == GL_NO_ERROR;
2158 if (success) {
[email protected]68e81a4a62012-12-13 01:16:482159 memory_tracker_.TrackMemFree(bytes_allocated_);
2160 bytes_allocated_ = image_size;
2161 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142162 }
2163 return success;
[email protected]6217d392010-03-25 22:08:352164}
2165
[email protected]ed9f9cd2013-02-27 21:12:352166void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:352167 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302168 ScopedGLErrorSuppressor suppressor("BackTexture::Copy",
[email protected]ce296892013-10-24 22:04:362169 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022170 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]6217d392010-03-25 22:08:352171 glCopyTexImage2D(GL_TEXTURE_2D,
2172 0, // level
[email protected]3a4d0c52011-06-29 23:11:582173 format,
[email protected]6217d392010-03-25 22:08:352174 0, 0,
2175 size.width(),
2176 size.height(),
2177 0); // border
2178}
2179
[email protected]ed9f9cd2013-02-27 21:12:352180void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:352181 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302182 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy",
[email protected]ce296892013-10-24 22:04:362183 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352184 glDeleteTextures(1, &id_);
2185 id_ = 0;
2186 }
[email protected]68e81a4a62012-12-13 01:16:482187 memory_tracker_.TrackMemFree(bytes_allocated_);
2188 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352189}
2190
[email protected]ed9f9cd2013-02-27 21:12:352191void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:052192 id_ = 0;
2193}
2194
[email protected]d5a28e452013-10-10 01:01:402195BackRenderbuffer::BackRenderbuffer(
2196 RenderbufferManager* renderbuffer_manager,
2197 MemoryTracker* memory_tracker,
2198 ContextState* state)
2199 : renderbuffer_manager_(renderbuffer_manager),
2200 memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2201 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482202 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252203 id_(0) {
[email protected]6217d392010-03-25 22:08:352204}
2205
[email protected]ed9f9cd2013-02-27 21:12:352206BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:352207 // This does not destroy the render buffer because that would require that
2208 // the associated GL context was current. Just check that it was explicitly
2209 // destroyed.
2210 DCHECK_EQ(id_, 0u);
2211}
2212
[email protected]ed9f9cd2013-02-27 21:12:352213void BackRenderbuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302214 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create",
[email protected]d5a28e452013-10-10 01:01:402215 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352216 Destroy();
2217 glGenRenderbuffersEXT(1, &id_);
2218}
2219
[email protected]f42f05b2013-11-15 21:46:182220bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info,
2221 const gfx::Size& size,
2222 GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:352223 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:512224 ScopedGLErrorSuppressor suppressor(
[email protected]d5a28e452013-10-10 01:01:402225 "BackRenderbuffer::AllocateStorage", state_->GetErrorState());
2226 ScopedRenderBufferBinder binder(state_, id_);
[email protected]7989c9e2013-01-23 06:39:262227
2228 uint32 estimated_size = 0;
[email protected]d5a28e452013-10-10 01:01:402229 if (!renderbuffer_manager_->ComputeEstimatedRenderbufferSize(
[email protected]8e102e102013-09-20 22:50:232230 size.width(), size.height(), samples, format, &estimated_size)) {
[email protected]7989c9e2013-01-23 06:39:262231 return false;
2232 }
2233
2234 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
2235 return false;
2236 }
2237
[email protected]34ff8b0c2010-10-01 20:06:022238 if (samples <= 1) {
2239 glRenderbufferStorageEXT(GL_RENDERBUFFER,
2240 format,
2241 size.width(),
2242 size.height());
2243 } else {
[email protected]f42f05b2013-11-15 21:46:182244 GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info,
2245 GL_RENDERBUFFER,
2246 samples,
2247 format,
2248 size.width(),
2249 size.height());
[email protected]34ff8b0c2010-10-01 20:06:022250 }
[email protected]1078f912011-12-23 13:12:142251 bool success = glGetError() == GL_NO_ERROR;
2252 if (success) {
[email protected]d5a28e452013-10-10 01:01:402253 // Mark the previously allocated bytes as free.
[email protected]68e81a4a62012-12-13 01:16:482254 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:262255 bytes_allocated_ = estimated_size;
[email protected]d5a28e452013-10-10 01:01:402256 // Track the newly allocated bytes.
[email protected]68e81a4a62012-12-13 01:16:482257 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142258 }
2259 return success;
[email protected]6217d392010-03-25 22:08:352260}
2261
[email protected]ed9f9cd2013-02-27 21:12:352262void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352263 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302264 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy",
[email protected]d5a28e452013-10-10 01:01:402265 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352266 glDeleteRenderbuffersEXT(1, &id_);
2267 id_ = 0;
2268 }
[email protected]68e81a4a62012-12-13 01:16:482269 memory_tracker_.TrackMemFree(bytes_allocated_);
2270 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352271}
2272
[email protected]ed9f9cd2013-02-27 21:12:352273void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052274 id_ = 0;
2275}
2276
[email protected]ed9f9cd2013-02-27 21:12:352277BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352278 : decoder_(decoder),
2279 id_(0) {
2280}
2281
[email protected]ed9f9cd2013-02-27 21:12:352282BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:352283 // This does not destroy the frame buffer because that would require that
2284 // the associated GL context was current. Just check that it was explicitly
2285 // destroyed.
2286 DCHECK_EQ(id_, 0u);
2287}
2288
[email protected]ed9f9cd2013-02-27 21:12:352289void BackFramebuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302290 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create",
2291 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352292 Destroy();
2293 glGenFramebuffersEXT(1, &id_);
2294}
2295
[email protected]ed9f9cd2013-02-27 21:12:352296void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:352297 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512298 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302299 "BackFramebuffer::AttachRenderTexture", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352300 ScopedFrameBufferBinder binder(decoder_, id_);
2301 GLuint attach_id = texture ? texture->id() : 0;
2302 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2303 GL_COLOR_ATTACHMENT0,
2304 GL_TEXTURE_2D,
2305 attach_id,
2306 0);
2307}
2308
[email protected]ed9f9cd2013-02-27 21:12:352309void BackFramebuffer::AttachRenderBuffer(GLenum target,
2310 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352311 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512312 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302313 "BackFramebuffer::AttachRenderBuffer", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352314 ScopedFrameBufferBinder binder(decoder_, id_);
2315 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2316 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152317 target,
[email protected]6217d392010-03-25 22:08:352318 GL_RENDERBUFFER,
2319 attach_id);
2320}
2321
[email protected]ed9f9cd2013-02-27 21:12:352322void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352323 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302324 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy",
2325 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352326 glDeleteFramebuffersEXT(1, &id_);
2327 id_ = 0;
2328 }
2329}
2330
[email protected]ed9f9cd2013-02-27 21:12:352331void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052332 id_ = 0;
2333}
2334
[email protected]ed9f9cd2013-02-27 21:12:352335GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352336 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302337 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus",
2338 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352339 ScopedFrameBufferBinder binder(decoder_, id_);
2340 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2341}
2342
[email protected]aa7666122011-09-02 19:45:522343GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2344 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322345}
2346
[email protected]aa7666122011-09-02 19:45:522347GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392348 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572349 group_(group),
[email protected]1d82e822013-04-10 21:32:322350 logger_(&debug_marker_manager_),
[email protected]828a3932014-04-02 14:43:132351 state_(group_->feature_info(), this, &logger_),
[email protected]43410e92012-04-20 17:06:282352 unpack_flip_y_(false),
2353 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172354 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242355 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492356 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242357 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402358 fixed_attrib_buffer_id_(0),
2359 fixed_attrib_buffer_size_(0),
[email protected]34ff8b0c2010-10-01 20:06:022360 offscreen_target_color_format_(0),
2361 offscreen_target_depth_format_(0),
2362 offscreen_target_stencil_format_(0),
2363 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562364 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052365 offscreen_saved_color_format_(0),
[email protected]32fe9aa2011-01-21 23:47:132366 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462367 back_buffer_has_depth_(false),
2368 back_buffer_has_stencil_(false),
achaulkcf5316f2014-09-26 19:28:422369 surfaceless_(false),
[email protected]60f22d32012-12-12 00:31:582370 backbuffer_needs_clear_bits_(0),
[email protected]a3a93e7b2010-08-28 00:48:562371 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052372 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112373 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002374 feature_info_(group_->feature_info()),
[email protected]38d139d2011-07-14 00:38:432375 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302376 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512377 reset_status_(GL_NO_ERROR),
[email protected]93a7d98f2013-07-11 00:04:222378 reset_by_robustness_extension_(false),
[email protected]b381ee32014-03-22 02:43:432379 supports_post_sub_buffer_(false),
[email protected]f0d74742011-10-03 16:31:042380 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102381 derivatives_explicitly_enabled_(false),
[email protected]70dc60932013-06-04 03:33:492382 frag_depth_explicitly_enabled_(false),
[email protected]aff39ac82013-06-08 04:53:132383 draw_buffers_explicitly_enabled_(false),
[email protected]93c2fd82014-04-16 02:46:062384 shader_texture_lod_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282385 compile_shader_always_succeeds_(false),
[email protected]828a3932014-04-02 14:43:132386 lose_context_when_out_of_memory_(false),
avi9ab037202014-12-22 23:49:532387 service_logging_(base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]cae20172012-12-07 00:06:192388 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022389 viewport_max_width_(0),
[email protected]4a4c18b2013-09-13 22:50:102390 viewport_max_height_(0),
[email protected]345ba902013-11-14 21:39:002391 texture_state_(group_->feature_info()
2392 ->workarounds()
2393 .texsubimage2d_faster_than_teximage2d),
vmiura1c2b1de2014-09-19 19:03:242394 cb_command_trace_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
2395 TRACE_DISABLED_BY_DEFAULT("cb_command"))),
dyencb86f2f2014-12-09 18:35:412396 gpu_decoder_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
2397 TRACE_DISABLED_BY_DEFAULT("gpu_decoder"))),
vmiura1c2b1de2014-09-19 19:03:242398 gpu_trace_level_(2),
2399 gpu_trace_commands_(false),
2400 gpu_debug_commands_(false),
[email protected]4a4c18b2013-09-13 22:50:102401 validation_texture_(0),
2402 validation_fbo_multisample_(0),
2403 validation_fbo_(0) {
[email protected]3b1ecc262011-08-03 22:49:572404 DCHECK(group);
2405
[email protected]b1122982010-05-17 23:04:242406 attrib_0_value_.v[0] = 0.0f;
2407 attrib_0_value_.v[1] = 0.0f;
2408 attrib_0_value_.v[2] = 0.0f;
2409 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152410
[email protected]c2f8c8402010-12-06 18:07:242411 // The shader translator is used for WebGL even when running on EGL
2412 // because additional restrictions are needed (like only enabling
2413 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562414 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2415 // the empty string to CompileShader and this is not a valid shader.
2416 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
avi9ab037202014-12-22 23:49:532417 base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]39ba4f02012-03-26 01:16:002418 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152419 use_shader_translator_ = false;
2420 }
[email protected]96449d2c2009-11-25 00:01:322421}
2422
[email protected]80eb6b52012-01-19 00:14:412423GLES2DecoderImpl::~GLES2DecoderImpl() {
2424}
2425
[email protected]c410da802011-03-14 19:17:412426bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382427 const scoped_refptr<gfx::GLSurface>& surface,
2428 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232429 bool offscreen,
[email protected]c410da802011-03-14 19:17:412430 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:292431 const DisallowedFeatures& disallowed_features,
[email protected]3c644d82011-06-20 19:58:242432 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322433 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382434 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302435 DCHECK(!context_.get());
2436
jbaumana7604692014-10-17 02:00:392437 surfaceless_ = surface->IsSurfaceless() && !offscreen;
achaulkcf5316f2014-09-26 19:28:422438
[email protected]55e136f2013-04-03 18:50:062439 set_initialized();
[email protected]b4af07d2014-08-20 00:11:572440 gpu_tracer_.reset(new GPUTracer(this));
[email protected]8f9b8dd2013-09-12 18:05:132441 gpu_state_tracer_ = GPUStateTracer::Create(&state_);
[email protected]fb97b662013-02-20 23:02:142442
avi9ab037202014-12-22 23:49:532443 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2444 switches::kEnableGPUDebugging)) {
[email protected]e844ae22012-01-14 03:36:262445 set_debug(true);
2446 }
2447
avi9ab037202014-12-22 23:49:532448 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2449 switches::kEnableGPUCommandLogging)) {
[email protected]39ba4f02012-03-26 01:16:002450 set_log_commands(true);
2451 }
2452
avi9ab037202014-12-22 23:49:532453 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2454 switches::kEnableUnsafeES3APIs)) {
zmo84c08202014-11-23 15:28:402455 set_unsafe_es3_apis_enabled(true);
2456 }
2457
avi9ab037202014-12-22 23:49:532458 compile_shader_always_succeeds_ =
2459 base::CommandLine::ForCurrentProcess()->HasSwitch(
2460 switches::kCompileShaderAlwaysSucceeds);
[email protected]062c38b2012-01-18 03:25:102461
[email protected]63c9b052012-05-17 18:27:382462 // Take ownership of the context and surface. The surface can be replaced with
2463 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382464 context_ = context;
[email protected]63c9b052012-05-17 18:27:382465 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182466
[email protected]65f7efe2013-11-28 03:11:472467 ContextCreationAttribHelper attrib_parser;
2468 if (!attrib_parser.Parse(attribs))
2469 return false;
2470
[email protected]828a3932014-04-02 14:43:132471 // Save the loseContextWhenOutOfMemory context creation attribute.
2472 lose_context_when_out_of_memory_ =
[email protected]845c4e32014-08-13 11:50:402473 attrib_parser.lose_context_when_out_of_memory;
[email protected]828a3932014-04-02 14:43:132474
[email protected]65f7efe2013-11-28 03:11:472475 // If the failIfMajorPerformanceCaveat context creation attribute was true
2476 // and we are using a software renderer, fail.
[email protected]845c4e32014-08-13 11:50:402477 if (attrib_parser.fail_if_major_perf_caveat &&
[email protected]65f7efe2013-11-28 03:11:472478 feature_info_->feature_flags().is_swiftshader) {
2479 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
2480 Destroy(true);
2481 return false;
2482 }
2483
[email protected]956aec52013-09-05 15:41:192484 if (!group_->Initialize(this, disallowed_features)) {
[email protected]09ddb91f2011-04-14 23:16:222485 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392486 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422487 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382488 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032489 return false;
[email protected]a3ded6d2010-10-19 06:44:392490 }
[email protected]b64c24952012-04-19 03:20:272491 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282492
[email protected]e82fb792011-09-22 00:33:292493 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502494
[email protected]af6380962012-11-29 23:24:132495 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]da364812014-05-09 21:39:482496 vertex_array_manager_.reset(new VertexArrayManager());
2497
2498 GLuint default_vertex_attrib_service_id = 0;
2499 if (features().native_vertex_array_object) {
2500 glGenVertexArraysOES(1, &default_vertex_attrib_service_id);
2501 glBindVertexArrayOES(default_vertex_attrib_service_id);
2502 }
2503
2504 state_.default_vertex_attrib_manager =
2505 CreateVertexAttribManager(0, default_vertex_attrib_service_id, false);
2506
[email protected]81f20a622014-04-18 01:54:522507 state_.default_vertex_attrib_manager->Initialize(
[email protected]94ba2e02014-03-12 10:32:002508 group_->max_vertex_attribs(),
2509 feature_info_->workarounds().init_vertex_attributes);
[email protected]944b62f32012-09-27 02:20:462510
[email protected]81f20a622014-04-18 01:54:522511 // vertex_attrib_manager is set to default_vertex_attrib_manager by this call
[email protected]ab4fd7282012-10-12 16:25:572512 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322513
[email protected]7cd76fd2013-06-02 21:11:112514 query_manager_.reset(new QueryManager(this, feature_info_.get()));
[email protected]882ba1e22012-03-08 19:02:532515
[email protected]b63f1d62014-07-18 15:40:592516 image_manager_.reset(new ImageManager);
2517
[email protected]302ce6d2011-07-07 23:28:112518 util_.set_num_compressed_texture_formats(
2519 validators_->compressed_texture_format.GetValues().size());
2520
[email protected]1071e572011-02-09 20:00:122521 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2522 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2523 // OpenGL ES 2.0 does not have this issue.
2524 glEnableVertexAttribArray(0);
2525 }
[email protected]b1122982010-05-17 23:04:242526 glGenBuffersARB(1, &attrib_0_buffer_id_);
2527 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2528 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2529 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402530 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082531
[email protected]1868a342012-11-07 15:56:022532 state_.texture_units.resize(group_->max_texture_units());
2533 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492534 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312535 // We want the last bind to be 2D.
[email protected]370eaf12013-05-18 09:19:492536 TextureRef* ref;
[email protected]62e155e2012-10-23 22:43:152537 if (features().oes_egl_image_external) {
[email protected]370eaf12013-05-18 09:19:492538 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072539 GL_TEXTURE_EXTERNAL_OES);
[email protected]370eaf12013-05-18 09:19:492540 state_.texture_units[tt].bound_texture_external_oes = ref;
[email protected]5ebf59f2014-04-08 03:51:572541 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref ? ref->service_id() : 0);
[email protected]61eeb33f2011-07-26 15:30:312542 }
[email protected]62e155e2012-10-23 22:43:152543 if (features().arb_texture_rectangle) {
[email protected]370eaf12013-05-18 09:19:492544 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072545 GL_TEXTURE_RECTANGLE_ARB);
[email protected]370eaf12013-05-18 09:19:492546 state_.texture_units[tt].bound_texture_rectangle_arb = ref;
[email protected]5ebf59f2014-04-08 03:51:572547 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref ? ref->service_id() : 0);
[email protected]e51bdf32011-11-23 22:21:462548 }
[email protected]370eaf12013-05-18 09:19:492549 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2550 state_.texture_units[tt].bound_texture_cube_map = ref;
[email protected]5ebf59f2014-04-08 03:51:572551 glBindTexture(GL_TEXTURE_CUBE_MAP, ref ? ref->service_id() : 0);
[email protected]370eaf12013-05-18 09:19:492552 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2553 state_.texture_units[tt].bound_texture_2d = ref;
[email protected]5ebf59f2014-04-08 03:51:572554 glBindTexture(GL_TEXTURE_2D, ref ? ref->service_id() : 0);
[email protected]1958e0e2010-04-22 05:17:152555 }
[email protected]00f893d2010-08-24 18:55:492556 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502557 CHECK_GL_ERROR();
2558
[email protected]069944672012-04-25 20:52:232559 if (offscreen) {
[email protected]845c4e32014-08-13 11:50:402560 if (attrib_parser.samples > 0 && attrib_parser.sample_buffers > 0 &&
[email protected]b0609652012-12-14 07:24:542561 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022562 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432563 // max_sample_count must be initialized to a sane value. If
2564 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2565 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022566 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
[email protected]845c4e32014-08-13 11:50:402567 offscreen_target_samples_ = std::min(attrib_parser.samples,
[email protected]34ff8b0c2010-10-01 20:06:022568 max_sample_count);
2569 } else {
2570 offscreen_target_samples_ = 1;
2571 }
[email protected]845c4e32014-08-13 11:50:402572 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved;
[email protected]34ff8b0c2010-10-01 20:06:022573
2574 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2575 const bool rgb8_supported =
2576 context_->HasExtension("GL_OES_rgb8_rgba8");
2577 // The only available default render buffer formats in GLES2 have very
2578 // little precision. Don't enable multisampling unless 8-bit render
2579 // buffer formats are available--instead fall back to 8-bit textures.
2580 if (rgb8_supported && offscreen_target_samples_ > 1) {
[email protected]845c4e32014-08-13 11:50:402581 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022582 GL_RGBA8 : GL_RGB8;
2583 } else {
2584 offscreen_target_samples_ = 1;
[email protected]845c4e32014-08-13 11:50:402585 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022586 GL_RGBA : GL_RGB;
2587 }
2588
2589 // ANGLE only supports packed depth/stencil formats, so use it if it is
2590 // available.
2591 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182592 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272593 VLOG(1) << "GL_OES_packed_depth_stencil "
2594 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]845c4e32014-08-13 11:50:402595 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002596 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022597 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2598 offscreen_target_stencil_format_ = 0;
2599 } else {
2600 // It may be the case that this depth/stencil combination is not
2601 // supported, but this will be checked later by CheckFramebufferStatus.
[email protected]845c4e32014-08-13 11:50:402602 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022603 GL_DEPTH_COMPONENT16 : 0;
[email protected]845c4e32014-08-13 11:50:402604 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022605 GL_STENCIL_INDEX8 : 0;
2606 }
2607 } else {
[email protected]845c4e32014-08-13 11:50:402608 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022609 GL_RGBA : GL_RGB;
2610
2611 // If depth is requested at all, use the packed depth stencil format if
2612 // it's available, as some desktop GL drivers don't support any non-packed
2613 // formats for depth attachments.
2614 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182615 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272616 VLOG(1) << "GL_EXT_packed_depth_stencil "
2617 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022618
[email protected]845c4e32014-08-13 11:50:402619 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002620 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022621 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2622 offscreen_target_stencil_format_ = 0;
2623 } else {
[email protected]845c4e32014-08-13 11:50:402624 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022625 GL_DEPTH_COMPONENT : 0;
[email protected]845c4e32014-08-13 11:50:402626 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022627 GL_STENCIL_INDEX : 0;
2628 }
2629 }
2630
[email protected]845c4e32014-08-13 11:50:402631 offscreen_saved_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]97872062010-11-03 19:07:052632 GL_RGBA : GL_RGB;
2633
[email protected]6217d392010-03-25 22:08:352634 // Create the target frame buffer. This is the one that the client renders
2635 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352636 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352637 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022638 // Due to GLES2 format limitations, either the color texture (for
2639 // non-multisampling) or the color render buffer (for multisampling) will be
2640 // attached to the offscreen frame buffer. The render buffer has more
2641 // limited formats available to it, but the texture can't do multisampling.
2642 if (IsOffscreenBufferMultisampled()) {
[email protected]d5a28e452013-10-10 01:01:402643 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(
2644 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022645 offscreen_target_color_render_buffer_->Create();
2646 } else {
[email protected]ce296892013-10-24 22:04:362647 offscreen_target_color_texture_.reset(new BackTexture(
2648 memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022649 offscreen_target_color_texture_->Create();
2650 }
[email protected]d5a28e452013-10-10 01:01:402651 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(
2652 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152653 offscreen_target_depth_render_buffer_->Create();
[email protected]d5a28e452013-10-10 01:01:402654 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(
2655 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152656 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352657
2658 // Create the saved offscreen texture. The target frame buffer is copied
2659 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352660 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022661 offscreen_saved_frame_buffer_->Create();
2662 //
[email protected]ce296892013-10-24 22:04:362663 offscreen_saved_color_texture_.reset(new BackTexture(
2664 memory_tracker(), &state_));
[email protected]6217d392010-03-25 22:08:352665 offscreen_saved_color_texture_->Create();
2666
[email protected]6217d392010-03-25 22:08:352667 // Allocate the render buffers at their initial size and check the status
2668 // of the frame buffers is okay.
[email protected]799b4b22011-08-22 17:09:592669 if (!ResizeOffscreenFrameBuffer(size)) {
[email protected]d0498742010-09-20 20:27:012670 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382671 Destroy(true);
[email protected]6217d392010-03-25 22:08:352672 return false;
2673 }
2674
[email protected]678a73f2012-12-19 19:22:092675 // Allocate the offscreen saved color texture.
2676 DCHECK(offscreen_saved_color_format_);
2677 offscreen_saved_color_texture_->AllocateStorage(
2678 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2679
2680 offscreen_saved_frame_buffer_->AttachRenderTexture(
2681 offscreen_saved_color_texture_.get());
2682 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2683 GL_FRAMEBUFFER_COMPLETE) {
2684 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2685 Destroy(true);
2686 return false;
2687 }
2688
[email protected]6217d392010-03-25 22:08:352689 // Bind to the new default frame buffer (the offscreen target frame buffer).
2690 // This should now be associated with ID zero.
2691 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
[email protected]62e65f02013-05-29 22:28:102692 } else {
2693 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
2694 // These are NOT if the back buffer has these proprorties. They are
2695 // if we want the command buffer to enforce them regardless of what
2696 // the real backbuffer is assuming the real back buffer gives us more than
2697 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2698 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2699 // can't do anything about that.
2700
achaulkcf5316f2014-09-26 19:28:422701 if (!surfaceless_) {
2702 GLint v = 0;
2703 glGetIntegerv(GL_ALPHA_BITS, &v);
2704 // This checks if the user requested RGBA and we have RGBA then RGBA. If
2705 // the user requested RGB then RGB. If the user did not specify a
2706 // preference than use whatever we were given. Same for DEPTH and STENCIL.
2707 back_buffer_color_format_ =
2708 (attrib_parser.alpha_size != 0 && v > 0) ? GL_RGBA : GL_RGB;
2709 glGetIntegerv(GL_DEPTH_BITS, &v);
2710 back_buffer_has_depth_ = attrib_parser.depth_size != 0 && v > 0;
2711 glGetIntegerv(GL_STENCIL_BITS, &v);
2712 back_buffer_has_stencil_ = attrib_parser.stencil_size != 0 && v > 0;
2713 }
[email protected]6217d392010-03-25 22:08:352714 }
2715
[email protected]76a0ee102010-04-07 21:03:042716 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2717 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2718 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372719 // mailing list archives. It also implicitly enables the desktop GL
2720 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2721 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152722 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2723 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372724 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152725 }
[email protected]de17df392010-04-23 21:09:412726
[email protected]706b69f2012-07-27 04:59:302727 has_robustness_extension_ =
2728 context->HasExtension("GL_ARB_robustness") ||
oetuaho37cc50e2014-10-31 11:19:202729 context->HasExtension("GL_KHR_robustness") ||
[email protected]706b69f2012-07-27 04:59:302730 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432731
[email protected]c2f8c8402010-12-06 18:07:242732 if (!InitializeShaderTranslator()) {
2733 return false;
[email protected]de17df392010-04-23 21:09:412734 }
[email protected]76a0ee102010-04-07 21:03:042735
[email protected]e259eb412012-10-13 05:47:242736 state_.viewport_width = size.width();
2737 state_.viewport_height = size.height();
[email protected]43410e92012-04-20 17:06:282738
[email protected]5904806b2012-05-08 18:10:222739 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282740 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022741 viewport_max_width_ = viewport_params[0];
2742 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282743
[email protected]88a61bf2012-10-27 13:00:422744 state_.scissor_width = state_.viewport_width;
2745 state_.scissor_height = state_.viewport_height;
2746
[email protected]11f3e702012-06-19 19:00:012747 // Set all the default state because some GL drivers get it wrong.
[email protected]88ba52f2014-04-09 12:39:342748 state_.InitCapabilities(NULL);
2749 state_.InitState(NULL);
[email protected]e259eb412012-10-13 05:47:242750 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]11f3e702012-06-19 19:00:012751
2752 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2753 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2754 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2755 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
orglofchcad5a6742014-11-07 19:51:122756 DoBindValueBufferCHROMIUM(GL_SUBSCRIBED_VALUES_BUFFER_CHROMIUM, 0);
[email protected]11f3e702012-06-19 19:00:012757
achaulkcf5316f2014-09-26 19:28:422758 bool call_gl_clear = !surfaceless_;
[email protected]88cfd132013-07-11 00:59:002759#if defined(OS_ANDROID)
2760 // Temporary workaround for Android WebView because this clear ignores the
2761 // clip and corrupts that external UI of the App. Not calling glClear is ok
2762 // because the system already clears the buffer before each draw. Proper
2763 // fix might be setting the scissor clip properly before initialize. See
2764 // crbug.com/259023 for details.
2765 call_gl_clear = surface_->GetHandle();
2766#endif
2767 if (call_gl_clear) {
2768 // Clear the backbuffer.
2769 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2770 }
[email protected]561cc0a62013-05-07 18:34:452771
[email protected]b381ee32014-03-22 02:43:432772 supports_post_sub_buffer_ = surface->SupportsPostSubBuffer();
2773 if (feature_info_->workarounds()
2774 .disable_post_sub_buffers_for_onscreen_surfaces &&
2775 !surface->IsOffscreen())
2776 supports_post_sub_buffer_ = false;
2777
[email protected]62e155e2012-10-23 22:43:152778 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462779 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2780 }
[email protected]dd289a5d62012-06-30 22:05:462781
[email protected]9b753992013-04-27 02:04:412782 if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2783 context_->SetUnbindFboOnMakeCurrent();
[email protected]85cb4682013-04-20 00:54:242784 }
[email protected]85cb4682013-04-20 00:54:242785
[email protected]97419c02013-04-10 02:52:382786 // Only compositor contexts are known to use only the subset of GL
2787 // that can be safely migrated between the iGPU and the dGPU. Mark
2788 // those contexts as safe to forcibly transition between the GPUs.
2789 // http://crbug.com/180876, http://crbug.com/227228
2790 if (!offscreen)
2791 context_->SetSafeToForceGpuSwitch();
2792
[email protected]85a4ac22013-05-31 01:58:472793 async_pixel_transfer_manager_.reset(
[email protected]498b5c072013-06-04 19:30:072794 AsyncPixelTransferManager::Create(context.get()));
2795 async_pixel_transfer_manager_->Initialize(texture_manager());
[email protected]32145a92012-12-17 09:01:592796
sievers2384f2b2014-11-18 02:10:352797 if (workarounds().gl_clear_broken) {
2798 DCHECK(!clear_framebuffer_blit_.get());
2799 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glClearWorkaroundInit");
2800 clear_framebuffer_blit_.reset(new ClearFramebufferResourceManager(this));
2801 if (LOCAL_PEEK_GL_ERROR("glClearWorkaroundInit") != GL_NO_ERROR)
2802 return false;
2803 }
2804
[email protected]91c94eb2013-10-22 10:32:542805 framebuffer_manager()->AddObserver(this);
2806
[email protected]246a70452010-03-05 21:53:502807 return true;
[email protected]96449d2c2009-11-25 00:01:322808}
2809
[email protected]6d668892013-12-04 21:37:122810Capabilities GLES2DecoderImpl::GetCapabilities() {
2811 DCHECK(initialized());
2812
2813 Capabilities caps;
piman1c2e0a852014-11-12 05:17:552814 caps.VisitPrecisions([](GLenum shader, GLenum type,
2815 Capabilities::ShaderPrecision* shader_precision) {
2816 GLint range[2] = {0, 0};
2817 GLint precision = 0;
2818 GetShaderPrecisionFormatImpl(shader, type, range, &precision);
2819 shader_precision->min_range = range[0];
2820 shader_precision->max_range = range[1];
2821 shader_precision->precision = precision;
2822 });
2823 DoGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
2824 &caps.max_combined_texture_image_units);
2825 DoGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &caps.max_cube_map_texture_size);
2826 DoGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS,
2827 &caps.max_fragment_uniform_vectors);
2828 DoGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &caps.max_renderbuffer_size);
2829 DoGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &caps.max_texture_image_units);
2830 DoGetIntegerv(GL_MAX_TEXTURE_SIZE, &caps.max_texture_size);
2831 DoGetIntegerv(GL_MAX_VARYING_VECTORS, &caps.max_varying_vectors);
2832 DoGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &caps.max_vertex_attribs);
2833 DoGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
2834 &caps.max_vertex_texture_image_units);
2835 DoGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS,
2836 &caps.max_vertex_uniform_vectors);
2837 DoGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS,
2838 &caps.num_compressed_texture_formats);
2839 DoGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &caps.num_shader_binary_formats);
2840 DoGetIntegerv(GL_BIND_GENERATES_RESOURCE_CHROMIUM,
2841 &caps.bind_generates_resource_chromium);
[email protected]6d668892013-12-04 21:37:122842
[email protected]6d668892013-12-04 21:37:122843 caps.egl_image_external =
2844 feature_info_->feature_flags().oes_egl_image_external;
2845 caps.texture_format_bgra8888 =
2846 feature_info_->feature_flags().ext_texture_format_bgra8888;
2847 caps.texture_format_etc1 =
2848 feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture;
aeliasd880a3d2014-08-26 00:46:202849 caps.texture_format_etc1_npot =
2850 caps.texture_format_etc1 && !workarounds().etc1_power_of_two_only;
[email protected]6d668892013-12-04 21:37:122851 caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle;
2852 caps.texture_usage = feature_info_->feature_flags().angle_texture_usage;
2853 caps.texture_storage = feature_info_->feature_flags().ext_texture_storage;
2854 caps.discard_framebuffer =
2855 feature_info_->feature_flags().ext_discard_framebuffer;
[email protected]12c99ab02014-04-22 10:12:352856 caps.sync_query = feature_info_->feature_flags().chromium_sync_query;
[email protected]6d668892013-12-04 21:37:122857
2858#if defined(OS_MACOSX)
2859 // This is unconditionally true on mac, no need to test for it at runtime.
2860 caps.iosurface = true;
2861#endif
2862
[email protected]b381ee32014-03-22 02:43:432863 caps.post_sub_buffer = supports_post_sub_buffer_;
reveman340109182014-09-30 15:36:452864 caps.image = true;
[email protected]6d668892013-12-04 21:37:122865
ed9198b422014-10-23 15:01:372866 caps.blend_equation_advanced =
2867 feature_info_->feature_flags().blend_equation_advanced;
2868 caps.blend_equation_advanced_coherent =
2869 feature_info_->feature_flags().blend_equation_advanced_coherent;
hendrikwfc25ca6192014-12-02 06:05:132870 caps.texture_rg = feature_info_->feature_flags().ext_texture_rg;
[email protected]6d668892013-12-04 21:37:122871 return caps;
2872}
2873
[email protected]302ce6d2011-07-07 23:28:112874void GLES2DecoderImpl::UpdateCapabilities() {
2875 util_.set_num_compressed_texture_formats(
2876 validators_->compressed_texture_format.GetValues().size());
2877 util_.set_num_shader_binary_formats(
2878 validators_->shader_binary_format.GetValues().size());
2879}
2880
[email protected]c2f8c8402010-12-06 18:07:242881bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442882 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2883
[email protected]c2f8c8402010-12-06 18:07:242884 if (!use_shader_translator_) {
2885 return true;
2886 }
2887 ShBuiltInResources resources;
2888 ShInitBuiltInResources(&resources);
2889 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2890 resources.MaxVertexUniformVectors =
2891 group_->max_vertex_uniform_vectors();
2892 resources.MaxVaryingVectors = group_->max_varying_vectors();
2893 resources.MaxVertexTextureImageUnits =
2894 group_->max_vertex_texture_image_units();
2895 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2896 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2897 resources.MaxFragmentUniformVectors =
2898 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:492899 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]a0b78142013-05-23 00:47:242900 resources.MaxExpressionComplexity = 256;
2901 resources.MaxCallStackDepth = 256;
[email protected]f0d74742011-10-03 16:31:042902
[email protected]46c86752013-05-21 05:08:392903 GLint range[2] = { 0, 0 };
[email protected]8dc1bf92013-03-12 03:58:212904 GLint precision = 0;
2905 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
2906 range, &precision);
[email protected]448e459e2013-06-12 17:00:412907 resources.FragmentPrecisionHigh =
2908 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
[email protected]9e98f61b2013-03-05 02:21:142909
[email protected]f0d74742011-10-03 16:31:042910 if (force_webgl_glsl_validation_) {
2911 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:492912 resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:132913 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
[email protected]cd8f1892013-09-05 00:14:442914 if (!draw_buffers_explicitly_enabled_)
2915 resources.MaxDrawBuffers = 1;
[email protected]93c2fd82014-04-16 02:46:062916 resources.EXT_shader_texture_lod = shader_texture_lod_explicitly_enabled_;
oetuaho0decd442014-10-13 08:40:462917 resources.NV_draw_buffers =
2918 draw_buffers_explicitly_enabled_ && features().nv_draw_buffers;
[email protected]f0d74742011-10-03 16:31:042919 } else {
2920 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152921 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462922 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152923 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062924 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152925 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:492926 resources.EXT_draw_buffers =
2927 features().ext_draw_buffers ? 1 : 0;
[email protected]70dc60932013-06-04 03:33:492928 resources.EXT_frag_depth =
2929 features().ext_frag_depth ? 1 : 0;
[email protected]93c2fd82014-04-16 02:46:062930 resources.EXT_shader_texture_lod =
2931 features().ext_shader_texture_lod ? 1 : 0;
oetuaho0decd442014-10-13 08:40:462932 resources.NV_draw_buffers =
2933 features().nv_draw_buffers ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:042934 }
2935
[email protected]26b61442013-03-17 16:12:012936 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC
2937 : SH_GLES2_SPEC;
[email protected]6aedcdc2013-01-24 01:25:052938 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:022939 resources.HashFunction = &CityHash64;
[email protected]6aedcdc2013-01-24 01:25:052940 else
2941 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:122942 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2943 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2944 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
[email protected]a6739bc2013-09-07 04:45:212945 int driver_bug_workarounds = 0;
2946 if (workarounds().needs_glsl_built_in_function_emulation)
2947 driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS;
[email protected]81187c62013-09-09 23:54:542948 if (workarounds().init_gl_position_in_vertex_shader)
2949 driver_bug_workarounds |= SH_INIT_GL_POSITION;
[email protected]f0c87602013-10-17 19:34:112950 if (workarounds().unfold_short_circuit_as_ternary_operation)
2951 driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT;
[email protected]b03219d2014-02-12 11:17:052952 if (workarounds().init_varyings_without_static_use)
2953 driver_bug_workarounds |= SH_INIT_VARYINGS_WITHOUT_STATIC_USE;
[email protected]f4db2b12014-03-01 03:57:062954 if (workarounds().unroll_for_loop_with_sampler_array_index)
2955 driver_bug_workarounds |= SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX;
[email protected]711e90802014-07-22 20:40:252956 if (workarounds().scalarize_vec_and_mat_constructor_args)
2957 driver_bug_workarounds |= SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS;
[email protected]fa6d3982014-08-18 18:10:272958 if (workarounds().regenerate_struct_names)
2959 driver_bug_workarounds |= SH_REGENERATE_STRUCT_NAMES;
[email protected]87fb6ab2012-06-13 22:28:042960
avi9ab037202014-12-22 23:49:532961 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2962 switches::kEmulateShaderPrecision))
oetuahoaffd85abe2014-12-11 09:47:092963 resources.WEBGL_debug_shader_precision = true;
2964
[email protected]03cef9b2014-04-03 15:58:142965 vertex_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:262966 GL_VERTEX_SHADER,
[email protected]03cef9b2014-04-03 15:58:142967 shader_spec,
2968 &resources,
[email protected]a6739bc2013-09-07 04:45:212969 implementation_type,
2970 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042971 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242972 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:382973 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242974 return false;
2975 }
[email protected]87fb6ab2012-06-13 22:28:042976
[email protected]03cef9b2014-04-03 15:58:142977 fragment_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:262978 GL_FRAGMENT_SHADER,
[email protected]03cef9b2014-04-03 15:58:142979 shader_spec,
2980 &resources,
[email protected]a6739bc2013-09-07 04:45:212981 implementation_type,
2982 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042983 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242984 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:382985 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242986 return false;
2987 }
2988 return true;
2989}
2990
[email protected]ae51d192010-04-27 00:48:032991bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:472992 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352993 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032994 return false;
2995 }
2996 }
[email protected]40d90a22013-04-09 03:39:552997 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032998 glGenBuffersARB(n, service_ids.get());
2999 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353000 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033001 }
3002 return true;
3003}
3004
3005bool GLES2DecoderImpl::GenFramebuffersHelper(
3006 GLsizei n, const GLuint* client_ids) {
3007 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353008 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033009 return false;
3010 }
3011 }
[email protected]40d90a22013-04-09 03:39:553012 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033013 glGenFramebuffersEXT(n, service_ids.get());
3014 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353015 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033016 }
3017 return true;
3018}
3019
3020bool GLES2DecoderImpl::GenRenderbuffersHelper(
3021 GLsizei n, const GLuint* client_ids) {
3022 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353023 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033024 return false;
3025 }
3026 }
[email protected]40d90a22013-04-09 03:39:553027 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033028 glGenRenderbuffersEXT(n, service_ids.get());
3029 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353030 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033031 }
3032 return true;
3033}
3034
orglofchcad5a6742014-11-07 19:51:123035bool GLES2DecoderImpl::GenValuebuffersCHROMIUMHelper(GLsizei n,
3036 const GLuint* client_ids) {
3037 for (GLsizei ii = 0; ii < n; ++ii) {
3038 if (GetValuebuffer(client_ids[ii])) {
3039 return false;
3040 }
3041 }
3042 for (GLsizei ii = 0; ii < n; ++ii) {
3043 CreateValuebuffer(client_ids[ii]);
3044 }
3045 return true;
3046}
3047
[email protected]ae51d192010-04-27 00:48:033048bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
3049 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353050 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033051 return false;
3052 }
3053 }
[email protected]40d90a22013-04-09 03:39:553054 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033055 glGenTextures(n, service_ids.get());
3056 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353057 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033058 }
3059 return true;
3060}
3061
3062void GLES2DecoderImpl::DeleteBuffersHelper(
3063 GLsizei n, const GLuint* client_ids) {
3064 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:213065 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103066 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:243067 state_.vertex_attrib_manager->Unbind(buffer);
[email protected]7cd76fd2013-06-02 21:11:113068 if (state_.bound_array_buffer.get() == buffer) {
[email protected]e259eb412012-10-13 05:47:243069 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:103070 }
[email protected]ed9f9cd2013-02-27 21:12:353071 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033072 }
[email protected]a93bb842010-02-16 23:03:473073 }
[email protected]07f54fcc2009-12-22 02:46:303074}
3075
[email protected]ae51d192010-04-27 00:48:033076void GLES2DecoderImpl::DeleteFramebuffersHelper(
3077 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453078 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153079 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:113080
[email protected]a25fa872010-03-25 02:57:583081 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353082 Framebuffer* framebuffer =
3083 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103084 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]9d3b2e12013-10-02 01:04:343085 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
3086 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]c986af502013-08-14 01:04:443087 framebuffer_state_.clear_state_dirty = true;
[email protected]ebfb73c2012-08-15 02:37:453088 GLenum target = supports_separate_framebuffer_binds ?
3089 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:113090 glBindFramebufferEXT(target, GetBackbufferServiceId());
3091 }
[email protected]9d3b2e12013-10-02 01:04:343092 if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) {
3093 framebuffer_state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:453094 GLenum target = supports_separate_framebuffer_binds ?
3095 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:113096 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:463097 }
[email protected]70d34263c2013-01-09 00:27:453098 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:353099 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033100 }
[email protected]a25fa872010-03-25 02:57:583101 }
[email protected]07f54fcc2009-12-22 02:46:303102}
3103
[email protected]ae51d192010-04-27 00:48:033104void GLES2DecoderImpl::DeleteRenderbuffersHelper(
3105 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453106 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153107 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:583108 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353109 Renderbuffer* renderbuffer =
3110 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103111 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:113112 if (state_.bound_renderbuffer.get() == renderbuffer) {
[email protected]e259eb412012-10-13 05:47:243113 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:103114 }
3115 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:453116 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:343117 if (framebuffer_state_.bound_read_framebuffer.get()) {
3118 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113119 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103120 }
[email protected]9d3b2e12013-10-02 01:04:343121 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3122 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113123 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103124 }
3125 } else {
[email protected]9d3b2e12013-10-02 01:04:343126 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3127 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113128 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103129 }
3130 }
[email protected]c986af502013-08-14 01:04:443131 framebuffer_state_.clear_state_dirty = true;
[email protected]ed9f9cd2013-02-27 21:12:353132 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033133 }
[email protected]a25fa872010-03-25 02:57:583134 }
[email protected]07f54fcc2009-12-22 02:46:303135}
3136
orglofchcad5a6742014-11-07 19:51:123137void GLES2DecoderImpl::DeleteValuebuffersCHROMIUMHelper(
3138 GLsizei n,
3139 const GLuint* client_ids) {
3140 for (GLsizei ii = 0; ii < n; ++ii) {
3141 Valuebuffer* valuebuffer = GetValuebuffer(client_ids[ii]);
3142 if (valuebuffer) {
3143 if (state_.bound_valuebuffer.get() == valuebuffer) {
3144 state_.bound_valuebuffer = NULL;
3145 }
3146 RemoveValuebuffer(client_ids[ii]);
3147 }
3148 }
3149}
3150
[email protected]ae51d192010-04-27 00:48:033151void GLES2DecoderImpl::DeleteTexturesHelper(
3152 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453153 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153154 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:473155 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]370eaf12013-05-18 09:19:493156 TextureRef* texture_ref = GetTexture(client_ids[ii]);
3157 if (texture_ref) {
3158 Texture* texture = texture_ref->texture();
[email protected]a0b78dc2011-11-11 10:43:103159 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:443160 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463161 }
[email protected]370eaf12013-05-18 09:19:493162 // Unbind texture_ref from texture_ref units.
[email protected]1868a342012-11-07 15:56:023163 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]370eaf12013-05-18 09:19:493164 state_.texture_units[jj].Unbind(texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103165 }
3166 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:453167 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:343168 if (framebuffer_state_.bound_read_framebuffer.get()) {
3169 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113170 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103171 }
[email protected]9d3b2e12013-10-02 01:04:343172 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3173 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113174 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103175 }
3176 } else {
[email protected]9d3b2e12013-10-02 01:04:343177 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3178 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113179 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103180 }
3181 }
[email protected]e51bdf32011-11-23 22:21:463182#if defined(OS_MACOSX)
[email protected]4f9958142013-07-02 03:58:073183 GLuint service_id = texture->service_id();
[email protected]e51bdf32011-11-23 22:21:463184 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
3185 ReleaseIOSurfaceForTexture(service_id);
3186 }
3187#endif
[email protected]ed9f9cd2013-02-27 21:12:353188 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033189 }
[email protected]a93bb842010-02-16 23:03:473190 }
[email protected]07f54fcc2009-12-22 02:46:303191}
3192
[email protected]43f28f832010-02-03 02:28:483193// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:323194
[email protected]eb54a562010-01-20 21:55:183195bool GLES2DecoderImpl::MakeCurrent() {
[email protected]177d1342013-12-07 04:20:343196 if (!context_.get())
[email protected]63c9b052012-05-17 18:27:383197 return false;
3198
[email protected]177d1342013-12-07 04:20:343199 if (!context_->MakeCurrent(surface_.get()) || WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:433200 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]e9f0ca82013-04-01 23:52:293201
jbauman7a059312014-10-16 19:30:543202 MaybeExitOnContextLost();
[email protected]e9f0ca82013-04-01 23:52:293203
[email protected]63c9b052012-05-17 18:27:383204 return false;
[email protected]38d139d2011-07-14 00:38:433205 }
3206
[email protected]69a8701e2013-03-07 21:31:093207 ProcessFinishedAsyncTransfers();
[email protected]69a8701e2013-03-07 21:31:093208
[email protected]9b753992013-04-27 02:04:413209 // Rebind the FBO if it was unbound by the context.
3210 if (workarounds().unbind_fbo_on_context_switch)
3211 RestoreFramebufferBindings();
3212
[email protected]c986af502013-08-14 01:04:443213 framebuffer_state_.clear_state_dirty = true;
[email protected]370eaf12013-05-18 09:19:493214
[email protected]69a8701e2013-03-07 21:31:093215 return true;
3216}
3217
3218void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]5a36dc132013-07-23 23:17:553219 ProcessPendingReadPixels();
[email protected]fe8d73c2013-02-16 22:37:323220 if (engine() && query_manager_.get())
3221 query_manager_->ProcessPendingTransferQueries();
3222
[email protected]5b3a8e02013-03-13 05:36:443223 // TODO(epenner): Is there a better place to do this?
3224 // This needs to occur before we execute any batch of commands
3225 // from the client, as the client may have recieved an async
3226 // completion while issuing those commands.
3227 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]b68b100752013-06-05 08:34:483228 async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
[email protected]eb54a562010-01-20 21:55:183229}
3230
[email protected]8e3e0662010-08-23 18:46:303231static void RebindCurrentFramebuffer(
3232 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:063233 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:243234 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:063235 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:463236
[email protected]a3783712012-01-20 22:18:243237 if (framebuffer_id == 0) {
3238 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:303239 }
[email protected]297ca1c2011-06-20 23:08:463240
[email protected]8e3e0662010-08-23 18:46:303241 glBindFramebufferEXT(target, framebuffer_id);
3242}
3243
3244void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]c986af502013-08-14 01:04:443245 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463246
[email protected]62e155e2012-10-23 22:43:153247 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:303248 RebindCurrentFramebuffer(
3249 GL_FRAMEBUFFER,
[email protected]9d3b2e12013-10-02 01:04:343250 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243251 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303252 } else {
3253 RebindCurrentFramebuffer(
3254 GL_READ_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343255 framebuffer_state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243256 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303257 RebindCurrentFramebuffer(
3258 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343259 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243260 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303261 }
[email protected]70d34263c2013-01-09 00:27:453262 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:303263}
3264
[email protected]0d6bfdc2011-11-02 01:32:203265bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:353266 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:203267 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:103268 if (!framebuffer) {
achaulkcf5316f2014-09-26 19:28:423269 if (surfaceless_)
3270 return false;
[email protected]60f22d32012-12-12 00:31:583271 if (backbuffer_needs_clear_bits_) {
3272 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
pkasting45796dc2014-10-17 04:18:323273 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1.f);
[email protected]454157e2014-05-03 02:49:453274 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]60f22d32012-12-12 00:31:583275 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473276 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3277 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]60f22d32012-12-12 00:31:583278 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:453279 state_.SetDeviceDepthMask(GL_TRUE);
3280 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]ee757922014-06-06 05:21:423281 bool reset_draw_buffer = false;
brucedawson18249152014-10-31 23:02:323282 if ((backbuffer_needs_clear_bits_ & GL_COLOR_BUFFER_BIT) != 0 &&
[email protected]ee757922014-06-06 05:21:423283 group_->draw_buffer() == GL_NONE) {
3284 reset_draw_buffer = true;
3285 GLenum buf = GL_BACK;
3286 if (GetBackbufferServiceId() != 0) // emulated backbuffer
3287 buf = GL_COLOR_ATTACHMENT0;
3288 glDrawBuffersARB(1, &buf);
3289 }
[email protected]60f22d32012-12-12 00:31:583290 glClear(backbuffer_needs_clear_bits_);
[email protected]ee757922014-06-06 05:21:423291 if (reset_draw_buffer) {
3292 GLenum buf = GL_NONE;
3293 glDrawBuffersARB(1, &buf);
3294 }
[email protected]60f22d32012-12-12 00:31:583295 backbuffer_needs_clear_bits_ = 0;
3296 RestoreClearState();
3297 }
[email protected]0d6bfdc2011-11-02 01:32:203298 return true;
3299 }
3300
[email protected]968351b2011-12-20 08:26:513301 if (framebuffer_manager()->IsComplete(framebuffer)) {
3302 return true;
3303 }
3304
[email protected]0d6bfdc2011-11-02 01:32:203305 GLenum completeness = framebuffer->IsPossiblyComplete();
3306 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513307 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433308 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:273309 return false;
3310 }
[email protected]0d6bfdc2011-11-02 01:32:203311
3312 // Are all the attachments cleared?
3313 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
3314 texture_manager()->HaveUnclearedMips()) {
3315 if (!framebuffer->IsCleared()) {
3316 // Can we clear them?
[email protected]73276522012-11-09 05:50:203317 if (framebuffer->GetStatus(texture_manager(), target) !=
3318 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513319 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433320 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3321 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:203322 return false;
3323 }
3324 ClearUnclearedAttachments(target, framebuffer);
3325 }
3326 }
3327
[email protected]968351b2011-12-20 08:26:513328 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:203329 if (framebuffer->GetStatus(texture_manager(), target) !=
3330 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513331 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433332 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3333 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:513334 return false;
3335 }
3336 framebuffer_manager()->MarkAsComplete(framebuffer);
3337 }
3338
[email protected]0d6bfdc2011-11-02 01:32:203339 // NOTE: At this point we don't know if the framebuffer is complete but
3340 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:273341 return true;
3342}
3343
[email protected]0d6bfdc2011-11-02 01:32:203344bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:153345 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:513346 bool valid = CheckFramebufferValid(
[email protected]9d3b2e12013-10-02 01:04:343347 framebuffer_state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT,
3348 func_name);
[email protected]28718a92013-04-04 12:12:513349
3350 if (valid)
3351 OnUseFramebuffer();
3352
3353 return valid;
[email protected]0d6bfdc2011-11-02 01:32:203354 }
[email protected]9d3b2e12013-10-02 01:04:343355 return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113356 GL_DRAW_FRAMEBUFFER_EXT,
3357 func_name) &&
[email protected]9d3b2e12013-10-02 01:04:343358 CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113359 GL_READ_FRAMEBUFFER_EXT,
3360 func_name);
[email protected]0d6bfdc2011-11-02 01:32:203361}
3362
[email protected]2ea5950d2014-07-09 18:20:343363bool GLES2DecoderImpl::CheckBoundReadFramebufferColorAttachment(
3364 const char* func_name) {
3365 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3366 framebuffer_state_.bound_read_framebuffer.get() :
3367 framebuffer_state_.bound_draw_framebuffer.get();
3368 if (!framebuffer)
3369 return true;
3370 if (framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL) {
3371 LOCAL_SET_GL_ERROR(
3372 GL_INVALID_OPERATION, func_name, "no color image attached");
3373 return false;
3374 }
3375 return true;
3376}
3377
zmo383512cf2014-10-14 00:11:003378bool GLES2DecoderImpl::FormsTextureCopyingFeedbackLoop(
3379 TextureRef* texture, GLint level) {
3380 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3381 framebuffer_state_.bound_read_framebuffer.get() :
3382 framebuffer_state_.bound_draw_framebuffer.get();
3383 if (!framebuffer)
3384 return false;
3385 const Framebuffer::Attachment* attachment = framebuffer->GetAttachment(
3386 GL_COLOR_ATTACHMENT0);
3387 if (!attachment)
3388 return false;
3389 return attachment->FormsFeedbackLoop(texture, level);
3390}
3391
[email protected]8e3e0662010-08-23 18:46:303392gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:353393 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453394 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203395 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:353396 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:203397 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:263398 if (attachment) {
3399 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:503400 }
[email protected]9edc6b22010-12-23 02:00:263401 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:023402 } else if (offscreen_target_frame_buffer_.get()) {
3403 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:353404 } else {
[email protected]f62a5ab2011-05-23 20:34:153405 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:023406 }
[email protected]246a70452010-03-05 21:53:503407}
3408
[email protected]68586372013-12-11 01:27:593409GLenum GLES2DecoderImpl::GetBoundReadFrameBufferTextureType() {
3410 Framebuffer* framebuffer =
3411 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
3412 if (framebuffer != NULL) {
3413 return framebuffer->GetColorAttachmentTextureType();
3414 } else {
3415 return GL_UNSIGNED_BYTE;
3416 }
3417}
3418
[email protected]9edc6b22010-12-23 02:00:263419GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353420 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453421 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203422 if (framebuffer != NULL) {
3423 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:463424 } else if (offscreen_target_frame_buffer_.get()) {
3425 return offscreen_target_color_format_;
3426 } else {
3427 return back_buffer_color_format_;
3428 }
3429}
3430
3431GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353432 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453433 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203434 if (framebuffer != NULL) {
3435 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:263436 } else if (offscreen_target_frame_buffer_.get()) {
3437 return offscreen_target_color_format_;
3438 } else {
[email protected]32fe9aa2011-01-21 23:47:133439 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:263440 }
3441}
3442
[email protected]9a5afa432011-07-22 18:16:393443void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]2ad674132013-06-05 07:48:513444 if (!offscreen_saved_color_texture_info_.get())
3445 return;
3446 GLenum target = offscreen_saved_color_texture_info_->texture()->target();
3447 glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
3448 texture_manager()->SetLevelInfo(
3449 offscreen_saved_color_texture_info_.get(),
3450 GL_TEXTURE_2D,
3451 0, // level
3452 GL_RGBA,
3453 offscreen_size_.width(),
3454 offscreen_size_.height(),
3455 1, // depth
3456 0, // border
3457 GL_RGBA,
3458 GL_UNSIGNED_BYTE,
3459 true);
[email protected]737191ee72014-03-09 08:02:423460 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513461 "UpdateParentTextureInfo",
3462 GetErrorState(),
3463 offscreen_saved_color_texture_info_.get(),
3464 GL_TEXTURE_MAG_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263465 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423466 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513467 "UpdateParentTextureInfo",
3468 GetErrorState(),
3469 offscreen_saved_color_texture_info_.get(),
3470 GL_TEXTURE_MIN_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263471 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423472 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513473 "UpdateParentTextureInfo",
3474 GetErrorState(),
3475 offscreen_saved_color_texture_info_.get(),
3476 GL_TEXTURE_WRAP_S,
3477 GL_CLAMP_TO_EDGE);
[email protected]737191ee72014-03-09 08:02:423478 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513479 "UpdateParentTextureInfo",
3480 GetErrorState(),
3481 offscreen_saved_color_texture_info_.get(),
3482 GL_TEXTURE_WRAP_T,
3483 GL_CLAMP_TO_EDGE);
[email protected]c986af502013-08-14 01:04:443484 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
3485 &state_, target);
[email protected]2ad674132013-06-05 07:48:513486 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
[email protected]6217d392010-03-25 22:08:353487}
3488
[email protected]799b4b22011-08-22 17:09:593489void GLES2DecoderImpl::SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:073490 const base::Callback<void(gfx::Size, float)>& callback) {
[email protected]9d37f062011-11-22 01:24:523491 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:003492}
3493
[email protected]1d82e822013-04-10 21:32:323494Logger* GLES2DecoderImpl::GetLogger() {
3495 return &logger_;
[email protected]6b6e7ee2011-12-13 08:04:523496}
3497
[email protected]cac16542014-01-15 17:53:513498void GLES2DecoderImpl::BeginDecoding() {
3499 gpu_tracer_->BeginDecoding();
dyencb86f2f2014-12-09 18:35:413500 gpu_trace_commands_ = gpu_tracer_->IsTracing() && *gpu_decoder_category_;
vmiura1c2b1de2014-09-19 19:03:243501 gpu_debug_commands_ = log_commands() || debug() || gpu_trace_commands_ ||
3502 (*cb_command_trace_category_ != 0);
[email protected]cac16542014-01-15 17:53:513503}
3504
3505void GLES2DecoderImpl::EndDecoding() {
3506 gpu_tracer_->EndDecoding();
3507}
3508
[email protected]d3eba342013-04-18 21:11:503509ErrorState* GLES2DecoderImpl::GetErrorState() {
3510 return state_.GetErrorState();
3511}
3512
[email protected]e3932abb2013-03-13 00:01:373513void GLES2DecoderImpl::SetShaderCacheCallback(
3514 const ShaderCacheCallback& callback) {
3515 shader_cache_callback_ = callback;
3516}
3517
[email protected]840a7e462013-02-27 01:29:513518void GLES2DecoderImpl::SetWaitSyncPointCallback(
3519 const WaitSyncPointCallback& callback) {
3520 wait_sync_point_callback_ = callback;
3521}
3522
[email protected]85a4ac22013-05-31 01:58:473523AsyncPixelTransferManager*
3524 GLES2DecoderImpl::GetAsyncPixelTransferManager() {
3525 return async_pixel_transfer_manager_.get();
3526}
3527
3528void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
3529 async_pixel_transfer_manager_.reset();
[email protected]32145a92012-12-17 09:01:593530}
3531
[email protected]498b5c072013-06-04 19:30:073532void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest(
3533 AsyncPixelTransferManager* manager) {
3534 async_pixel_transfer_manager_ = make_scoped_ptr(manager);
3535}
3536
[email protected]1318e922010-09-17 22:03:163537bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3538 uint32* service_texture_id) {
[email protected]370eaf12013-05-18 09:19:493539 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3540 if (texture_ref) {
3541 *service_texture_id = texture_ref->service_id();
[email protected]1318e922010-09-17 22:03:163542 return true;
3543 }
3544 return false;
3545}
3546
[email protected]63b465922012-09-06 02:04:523547uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]c986af502013-08-14 01:04:443548 return texture_state_.texture_upload_count +
[email protected]b68b100752013-06-05 08:34:483549 async_pixel_transfer_manager_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523550}
3551
3552base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]c986af502013-08-14 01:04:443553 return texture_state_.total_texture_upload_time +
[email protected]b68b100752013-06-05 08:34:483554 async_pixel_transfer_manager_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523555}
3556
3557base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3558 return total_processing_commands_time_;
3559}
3560
[email protected]dc25dda2012-09-27 21:36:303561void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3562 total_processing_commands_time_ += time;
3563}
3564
[email protected]63c9b052012-05-17 18:27:383565void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063566 if (!initialized())
3567 return;
3568
[email protected]63c9b052012-05-17 18:27:383569 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053570
[email protected]80eb6b52012-01-19 00:14:413571 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243572 state_.vertex_attrib_manager = NULL;
[email protected]81f20a622014-04-18 01:54:523573 state_.default_vertex_attrib_manager = NULL;
[email protected]1868a342012-11-07 15:56:023574 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243575 state_.bound_array_buffer = NULL;
[email protected]8ebd46c2014-01-08 12:06:133576 state_.current_queries.clear();
[email protected]9d3b2e12013-10-02 01:04:343577 framebuffer_state_.bound_read_framebuffer = NULL;
3578 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]e259eb412012-10-13 05:47:243579 state_.bound_renderbuffer = NULL;
orglofchcad5a6742014-11-07 19:51:123580 state_.bound_valuebuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413581
[email protected]cadac622013-06-11 16:46:363582 if (offscreen_saved_color_texture_info_.get()) {
[email protected]2ad674132013-06-05 07:48:513583 DCHECK(offscreen_target_color_texture_);
3584 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
3585 offscreen_saved_color_texture_->id());
3586 offscreen_saved_color_texture_->Invalidate();
3587 offscreen_saved_color_texture_info_ = NULL;
3588 }
[email protected]eadc96792010-10-27 19:39:393589 if (have_context) {
[email protected]c322e882012-05-23 18:06:183590 if (copy_texture_CHROMIUM_.get()) {
3591 copy_texture_CHROMIUM_->Destroy();
3592 copy_texture_CHROMIUM_.reset();
3593 }
[email protected]43410e92012-04-20 17:06:283594
sievers2384f2b2014-11-18 02:10:353595 clear_framebuffer_blit_.reset();
3596
[email protected]7cd76fd2013-06-02 21:11:113597 if (state_.current_program.get()) {
3598 program_manager()->UnuseProgram(shader_manager(),
3599 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:143600 }
3601
[email protected]b1122982010-05-17 23:04:243602 if (attrib_0_buffer_id_) {
3603 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3604 }
[email protected]8fbedc02010-11-18 18:43:403605 if (fixed_attrib_buffer_id_) {
3606 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3607 }
[email protected]b1122982010-05-17 23:04:243608
[email protected]4a4c18b2013-09-13 22:50:103609 if (validation_texture_) {
3610 glDeleteTextures(1, &validation_texture_);
3611 glDeleteFramebuffersEXT(1, &validation_fbo_multisample_);
3612 glDeleteFramebuffersEXT(1, &validation_fbo_);
3613 }
3614
[email protected]97872062010-11-03 19:07:053615 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543616 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053617 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543618 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053619 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023620 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053621 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153622 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053623 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153624 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053625 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023626 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053627 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543628 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273629 if (offscreen_resolved_frame_buffer_.get())
3630 offscreen_resolved_frame_buffer_->Destroy();
3631 if (offscreen_resolved_color_texture_.get())
3632 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053633 } else {
3634 if (offscreen_target_frame_buffer_.get())
3635 offscreen_target_frame_buffer_->Invalidate();
3636 if (offscreen_target_color_texture_.get())
3637 offscreen_target_color_texture_->Invalidate();
3638 if (offscreen_target_color_render_buffer_.get())
3639 offscreen_target_color_render_buffer_->Invalidate();
3640 if (offscreen_target_depth_render_buffer_.get())
3641 offscreen_target_depth_render_buffer_->Invalidate();
3642 if (offscreen_target_stencil_render_buffer_.get())
3643 offscreen_target_stencil_render_buffer_->Invalidate();
3644 if (offscreen_saved_frame_buffer_.get())
3645 offscreen_saved_frame_buffer_->Invalidate();
3646 if (offscreen_saved_color_texture_.get())
3647 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273648 if (offscreen_resolved_frame_buffer_.get())
3649 offscreen_resolved_frame_buffer_->Invalidate();
3650 if (offscreen_resolved_color_texture_.get())
3651 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023652 }
[email protected]83a52d032013-07-24 10:30:373653
3654 // Current program must be cleared after calling ProgramManager::UnuseProgram.
3655 // Otherwise, we can leak objects. http://crbug.com/258772.
3656 // state_.current_program must be reset before group_ is reset because
3657 // the later deletes the ProgramManager object that referred by
3658 // state_.current_program object.
3659 state_.current_program = NULL;
3660
[email protected]43410e92012-04-20 17:06:283661 copy_texture_CHROMIUM_.reset();
sievers2384f2b2014-11-18 02:10:353662 clear_framebuffer_blit_.reset();
[email protected]97872062010-11-03 19:07:053663
[email protected]882ba1e22012-03-08 19:02:533664 if (query_manager_.get()) {
3665 query_manager_->Destroy(have_context);
3666 query_manager_.reset();
3667 }
3668
[email protected]944b62f32012-09-27 02:20:463669 if (vertex_array_manager_ .get()) {
3670 vertex_array_manager_->Destroy(have_context);
3671 vertex_array_manager_.reset();
3672 }
3673
[email protected]d2eaf52f2014-07-31 15:01:243674 if (image_manager_.get()) {
3675 image_manager_->Destroy(have_context);
3676 image_manager_.reset();
3677 }
3678
[email protected]97872062010-11-03 19:07:053679 offscreen_target_frame_buffer_.reset();
3680 offscreen_target_color_texture_.reset();
3681 offscreen_target_color_render_buffer_.reset();
3682 offscreen_target_depth_render_buffer_.reset();
3683 offscreen_target_stencil_render_buffer_.reset();
3684 offscreen_saved_frame_buffer_.reset();
3685 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273686 offscreen_resolved_frame_buffer_.reset();
3687 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463688
[email protected]03cef9b2014-04-03 15:58:143689 // Need to release these before releasing |group_| which may own the
3690 // ShaderTranslatorCache.
3691 fragment_translator_ = NULL;
3692 vertex_translator_ = NULL;
3693
[email protected]85a4ac22013-05-31 01:58:473694 // Should destroy the transfer manager before the texture manager held
3695 // by the context group.
3696 async_pixel_transfer_manager_.reset();
3697
[email protected]7cd76fd2013-06-02 21:11:113698 if (group_.get()) {
[email protected]ac5e4022014-01-24 12:44:393699 framebuffer_manager()->RemoveObserver(this);
[email protected]2d9d3b92013-01-18 01:07:233700 group_->Destroy(this, have_context);
3701 group_ = NULL;
3702 }
3703
3704 if (context_.get()) {
3705 context_->ReleaseCurrent(NULL);
3706 context_ = NULL;
3707 }
3708
[email protected]e51bdf32011-11-23 22:21:463709#if defined(OS_MACOSX)
3710 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3711 it != texture_to_io_surface_map_.end(); ++it) {
3712 CFRelease(it->second);
3713 }
3714 texture_to_io_surface_map_.clear();
3715#endif
[email protected]96449d2c2009-11-25 00:01:323716}
3717
[email protected]63c9b052012-05-17 18:27:383718void GLES2DecoderImpl::SetSurface(
3719 const scoped_refptr<gfx::GLSurface>& surface) {
3720 DCHECK(context_->IsCurrent(NULL));
3721 DCHECK(surface_.get());
3722 surface_ = surface;
3723 RestoreCurrentFramebufferBindings();
3724}
3725
[email protected]aba551b2014-02-08 03:38:323726void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
3727 if (!offscreen_saved_color_texture_.get()) {
3728 LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context";
3729 return;
3730 }
[email protected]2ad674132013-06-05 07:48:513731 if (!offscreen_saved_color_texture_info_.get()) {
[email protected]3c644d82011-06-20 19:58:243732 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]f46476932013-06-08 05:36:073733 offscreen_saved_color_texture_info_ = TextureRef::Create(
3734 texture_manager(), 0, service_id);
[email protected]2ad674132013-06-05 07:48:513735 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(),
3736 GL_TEXTURE_2D);
[email protected]9a5afa432011-07-22 18:16:393737 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243738 }
[email protected]aba551b2014-02-08 03:38:323739 mailbox_manager()->ProduceTexture(
sievers8b373ec52014-10-24 23:04:063740 mailbox, offscreen_saved_color_texture_info_->texture());
[email protected]3c644d82011-06-20 19:58:243741}
3742
[email protected]799b4b22011-08-22 17:09:593743bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3744 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3745 if (!is_offscreen) {
3746 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3747 << " with an onscreen framebuffer.";
3748 return false;
3749 }
3750
3751 if (offscreen_size_ == size)
3752 return true;
3753
3754 offscreen_size_ = size;
3755 int w = offscreen_size_.width();
3756 int h = offscreen_size_.height();
3757 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3758 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3759 << "to allocate storage due to excessive dimensions.";
3760 return false;
3761 }
3762
3763 // Reallocate the offscreen target buffers.
3764 DCHECK(offscreen_target_color_format_);
3765 if (IsOffscreenBufferMultisampled()) {
3766 if (!offscreen_target_color_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253767 feature_info_.get(),
3768 offscreen_size_,
3769 offscreen_target_color_format_,
3770 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593771 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3772 << "to allocate storage for offscreen target color buffer.";
3773 return false;
3774 }
3775 } else {
3776 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093777 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593778 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3779 << "to allocate storage for offscreen target color texture.";
3780 return false;
3781 }
3782 }
3783 if (offscreen_target_depth_format_ &&
3784 !offscreen_target_depth_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253785 feature_info_.get(),
3786 offscreen_size_,
3787 offscreen_target_depth_format_,
3788 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593789 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3790 << "to allocate storage for offscreen target depth buffer.";
3791 return false;
3792 }
3793 if (offscreen_target_stencil_format_ &&
3794 !offscreen_target_stencil_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253795 feature_info_.get(),
3796 offscreen_size_,
3797 offscreen_target_stencil_format_,
3798 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593799 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3800 << "to allocate storage for offscreen target stencil buffer.";
3801 return false;
3802 }
3803
3804 // Attach the offscreen target buffers to the target frame buffer.
3805 if (IsOffscreenBufferMultisampled()) {
3806 offscreen_target_frame_buffer_->AttachRenderBuffer(
3807 GL_COLOR_ATTACHMENT0,
3808 offscreen_target_color_render_buffer_.get());
3809 } else {
3810 offscreen_target_frame_buffer_->AttachRenderTexture(
3811 offscreen_target_color_texture_.get());
3812 }
3813 if (offscreen_target_depth_format_) {
3814 offscreen_target_frame_buffer_->AttachRenderBuffer(
3815 GL_DEPTH_ATTACHMENT,
3816 offscreen_target_depth_render_buffer_.get());
3817 }
3818 const bool packed_depth_stencil =
3819 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3820 if (packed_depth_stencil) {
3821 offscreen_target_frame_buffer_->AttachRenderBuffer(
3822 GL_STENCIL_ATTACHMENT,
3823 offscreen_target_depth_render_buffer_.get());
3824 } else if (offscreen_target_stencil_format_) {
3825 offscreen_target_frame_buffer_->AttachRenderBuffer(
3826 GL_STENCIL_ATTACHMENT,
3827 offscreen_target_stencil_render_buffer_.get());
3828 }
3829
3830 if (offscreen_target_frame_buffer_->CheckStatus() !=
3831 GL_FRAMEBUFFER_COMPLETE) {
3832 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3833 << "because offscreen FBO was incomplete.";
3834 return false;
3835 }
3836
3837 // Clear the target frame buffer.
3838 {
3839 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3840 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
pkasting45796dc2014-10-17 04:18:323841 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1.f);
[email protected]454157e2014-05-03 02:49:453842 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]799b4b22011-08-22 17:09:593843 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473844 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3845 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]799b4b22011-08-22 17:09:593846 glClearDepth(0);
[email protected]454157e2014-05-03 02:49:453847 state_.SetDeviceDepthMask(GL_TRUE);
3848 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]799b4b22011-08-22 17:09:593849 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3850 RestoreClearState();
3851 }
[email protected]d85ef76d2011-09-08 22:21:433852
3853 // Destroy the offscreen resolved framebuffers.
3854 if (offscreen_resolved_frame_buffer_.get())
3855 offscreen_resolved_frame_buffer_->Destroy();
3856 if (offscreen_resolved_color_texture_.get())
3857 offscreen_resolved_color_texture_->Destroy();
3858 offscreen_resolved_color_texture_.reset();
3859 offscreen_resolved_frame_buffer_.reset();
3860
[email protected]799b4b22011-08-22 17:09:593861 return true;
[email protected]6217d392010-03-25 22:08:353862}
3863
vmiuracd108592014-09-08 14:36:343864error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(uint32 immediate_data_size,
3865 const void* cmd_data) {
3866 const gles2::cmds::ResizeCHROMIUM& c =
3867 *static_cast<const gles2::cmds::ResizeCHROMIUM*>(cmd_data);
[email protected]09e17272012-11-30 10:30:443868 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023869 return error::kDeferCommandUntilLater;
3870
[email protected]799b4b22011-08-22 17:09:593871 GLuint width = static_cast<GLuint>(c.width);
3872 GLuint height = static_cast<GLuint>(c.height);
[email protected]729c0b42013-05-26 02:05:073873 GLfloat scale_factor = c.scale_factor;
[email protected]799b4b22011-08-22 17:09:593874 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:413875
3876 width = std::max(1U, width);
3877 height = std::max(1U, height);
3878
[email protected]a0d989162011-11-22 13:15:073879#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3880 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003881 // Make sure that we are done drawing to the back buffer before resizing.
3882 glFinish();
3883#endif
[email protected]799b4b22011-08-22 17:09:593884 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3885 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493886 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3887 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3888 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593889 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493890 }
[email protected]7ff86b92010-11-25 17:50:003891 }
[email protected]799b4b22011-08-22 17:09:593892
[email protected]9d37f062011-11-22 01:24:523893 if (!resize_callback_.is_null()) {
[email protected]729c0b42013-05-26 02:05:073894 resize_callback_.Run(gfx::Size(width, height), scale_factor);
[email protected]0e9346b2013-03-16 16:35:443895 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493896 if (!context_->IsCurrent(surface_.get())) {
3897 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3898 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053899 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493900 }
[email protected]658f7562011-09-09 05:24:053901 }
[email protected]799b4b22011-08-22 17:09:593902
3903 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393904}
3905
[email protected]96449d2c2009-11-25 00:01:323906const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3907 if (command_id > kStartPoint && command_id < kNumCommands) {
3908 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3909 }
3910 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3911}
3912
vmiura8266ca72014-09-09 21:37:003913// Decode a command, and call the corresponding GL functions.
3914// NOTE: DoCommand() is slower than calling DoCommands() on larger batches
3915// of commands at once, and is now only used for tests that need to track
3916// individual commands.
3917error::Error GLES2DecoderImpl::DoCommand(unsigned int command,
3918 unsigned int arg_count,
3919 const void* cmd_data) {
3920 return DoCommands(1, cmd_data, arg_count + 1, 0);
3921}
3922
3923// Decode multiple commands, and call the corresponding GL functions.
3924// NOTE: 'buffer' is a pointer to the command buffer. As such, it could be
3925// changed by a (malicious) client at any time, so if validation has to happen,
3926// it should operate on a copy of them.
3927// NOTE: This is duplicating code from AsyncAPIInterface::DoCommands() in the
3928// interest of performance in this critical execution loop.
vmiura1c2b1de2014-09-19 19:03:243929template <bool DebugImpl>
3930error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands,
3931 const void* buffer,
3932 int num_entries,
3933 int* entries_processed) {
vmiura8266ca72014-09-09 21:37:003934 commands_to_process_ = num_commands;
[email protected]f7a64ee2010-02-01 22:24:143935 error::Error result = error::kNoError;
vmiura8266ca72014-09-09 21:37:003936 const CommandBufferEntry* cmd_data =
3937 static_cast<const CommandBufferEntry*>(buffer);
3938 int process_pos = 0;
3939 unsigned int command = 0;
3940
3941 while (process_pos < num_entries && result == error::kNoError &&
3942 commands_to_process_--) {
3943 const unsigned int size = cmd_data->value_header.size;
3944 command = cmd_data->value_header.command;
3945
3946 if (size == 0) {
3947 result = error::kInvalidSize;
3948 break;
3949 }
3950
3951 if (static_cast<int>(size) + process_pos > num_entries) {
3952 result = error::kOutOfBounds;
3953 break;
3954 }
3955
vmiura1c2b1de2014-09-19 19:03:243956 if (DebugImpl) {
3957 TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
3958 GetCommandName(command));
vmiura8266ca72014-09-09 21:37:003959
vmiura1c2b1de2014-09-19 19:03:243960 if (log_commands()) {
3961 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]"
3962 << "cmd: " << GetCommandName(command);
3963 }
vmiura8266ca72014-09-09 21:37:003964 }
3965
3966 const unsigned int arg_count = size - 1;
3967 unsigned int command_index = command - kStartPoint - 1;
3968 if (command_index < arraysize(command_info)) {
3969 const CommandInfo& info = command_info[command_index];
3970 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3971 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3972 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
3973 bool doing_gpu_trace = false;
vmiura1c2b1de2014-09-19 19:03:243974 if (DebugImpl && gpu_trace_commands_) {
vmiura8266ca72014-09-09 21:37:003975 if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) {
3976 doing_gpu_trace = true;
dyencb86f2f2014-12-09 18:35:413977 gpu_tracer_->Begin(TRACE_DISABLED_BY_DEFAULT("gpu_decoder"),
3978 GetCommandName(command),
3979 kTraceDecoder);
vmiura8266ca72014-09-09 21:37:003980 }
[email protected]cac16542014-01-15 17:53:513981 }
[email protected]cac16542014-01-15 17:53:513982
vmiura8266ca72014-09-09 21:37:003983 uint32 immediate_data_size = (arg_count - info_arg_count) *
3984 sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:323985
vmiura8266ca72014-09-09 21:37:003986 result = (this->*info.cmd_handler)(immediate_data_size, cmd_data);
[email protected]cac16542014-01-15 17:53:513987
vmiura1c2b1de2014-09-19 19:03:243988 if (DebugImpl && doing_gpu_trace)
vmiura8266ca72014-09-09 21:37:003989 gpu_tracer_->End(kTraceDecoder);
[email protected]cac16542014-01-15 17:53:513990
vmiura1c2b1de2014-09-19 19:03:243991 if (DebugImpl && debug()) {
vmiura8266ca72014-09-09 21:37:003992 GLenum error;
3993 while ((error = glGetError()) != GL_NO_ERROR) {
3994 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
3995 << "GL ERROR: " << GLES2Util::GetStringEnum(error)
3996 << " : " << GetCommandName(command);
3997 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
3998 }
[email protected]b9849abf2009-11-25 19:13:193999 }
vmiura8266ca72014-09-09 21:37:004000 } else {
4001 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:324002 }
4003 } else {
vmiura8266ca72014-09-09 21:37:004004 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:324005 }
vmiura1c2b1de2014-09-19 19:03:244006
4007 if (DebugImpl) {
4008 TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
4009 GetCommandName(command));
4010 }
4011
vmiura8266ca72014-09-09 21:37:004012 if (result == error::kNoError &&
4013 current_decoder_error_ != error::kNoError) {
[email protected]a3a93e7b2010-08-28 00:48:564014 result = current_decoder_error_;
4015 current_decoder_error_ = error::kNoError;
vmiura8266ca72014-09-09 21:37:004016 }
4017
4018 if (result != error::kDeferCommandUntilLater) {
4019 process_pos += size;
4020 cmd_data += size;
4021 }
[email protected]a3a93e7b2010-08-28 00:48:564022 }
vmiura8266ca72014-09-09 21:37:004023
4024 if (entries_processed)
4025 *entries_processed = process_pos;
4026
4027 if (error::IsError(result)) {
4028 LOG(ERROR) << "Error: " << result << " for Command "
4029 << GetCommandName(command);
4030 }
4031
[email protected]b9849abf2009-11-25 19:13:194032 return result;
[email protected]96449d2c2009-11-25 00:01:324033}
4034
vmiura1c2b1de2014-09-19 19:03:244035error::Error GLES2DecoderImpl::DoCommands(unsigned int num_commands,
4036 const void* buffer,
4037 int num_entries,
4038 int* entries_processed) {
4039 if (gpu_debug_commands_) {
4040 return DoCommandsImpl<true>(
4041 num_commands, buffer, num_entries, entries_processed);
4042 } else {
4043 return DoCommandsImpl<false>(
4044 num_commands, buffer, num_entries, entries_processed);
4045 }
4046}
4047
[email protected]ed9f9cd2013-02-27 21:12:354048void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
4049 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:504050}
4051
[email protected]ae51d192010-04-27 00:48:034052bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:354053 if (GetProgram(client_id)) {
[email protected]ae51d192010-04-27 00:48:034054 return false;
4055 }
[email protected]96449d2c2009-11-25 00:01:324056 GLuint service_id = glCreateProgram();
[email protected]ae51d192010-04-27 00:48:034057 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:354058 CreateProgram(client_id, service_id);
[email protected]96449d2c2009-11-25 00:01:324059 }
[email protected]ae51d192010-04-27 00:48:034060 return true;
[email protected]96449d2c2009-11-25 00:01:324061}
4062
[email protected]ae51d192010-04-27 00:48:034063bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:354064 if (GetShader(client_id)) {
[email protected]ae51d192010-04-27 00:48:034065 return false;
[email protected]96449d2c2009-11-25 00:01:324066 }
[email protected]ae51d192010-04-27 00:48:034067 GLuint service_id = glCreateShader(type);
4068 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:354069 CreateShader(client_id, service_id, type);
[email protected]ae51d192010-04-27 00:48:034070 }
4071 return true;
[email protected]96449d2c2009-11-25 00:01:324072}
4073
[email protected]882ba1e22012-03-08 19:02:534074void GLES2DecoderImpl::DoFinish() {
4075 glFinish();
[email protected]5a36dc132013-07-23 23:17:554076 ProcessPendingReadPixels();
revemancc241eb2014-11-11 03:30:374077 ProcessPendingQueries(true);
[email protected]882ba1e22012-03-08 19:02:534078}
4079
4080void GLES2DecoderImpl::DoFlush() {
4081 glFlush();
revemancc241eb2014-11-11 03:30:374082 ProcessPendingQueries(false);
[email protected]882ba1e22012-03-08 19:02:534083}
4084
[email protected]3916c97e2010-02-25 03:20:504085void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:454086 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:024087 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:514088 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:534089 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:504090 return;
4091 }
[email protected]e259eb412012-10-13 05:47:244092 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:454093 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:504094}
4095
[email protected]051b1372010-04-12 02:42:084096void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:074097 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:084098 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034099 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:074100 buffer = GetBuffer(client_id);
4101 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:354102 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224103 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4104 "glBindBuffer",
4105 "id not generated by glGenBuffers");
[email protected]bf5a8d132011-08-16 08:39:354106 return;
4107 }
4108
[email protected]b10492f2013-03-08 05:24:074109 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:034110 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354111 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:074112 buffer = GetBuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034113 }
[email protected]051b1372010-04-12 02:42:084114 }
[email protected]b10492f2013-03-08 05:24:074115 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
4116 if (buffer) {
4117 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:514118 LOCAL_SET_GL_ERROR(
4119 GL_INVALID_OPERATION,
4120 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:474121 return;
4122 }
[email protected]b10492f2013-03-08 05:24:074123 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:474124 }
[email protected]96449d2c2009-11-25 00:01:324125 switch (target) {
4126 case GL_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:074127 state_.bound_array_buffer = buffer;
[email protected]96449d2c2009-11-25 00:01:324128 break;
4129 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:074130 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
[email protected]96449d2c2009-11-25 00:01:324131 break;
4132 default:
[email protected]a93bb842010-02-16 23:03:474133 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:324134 break;
4135 }
[email protected]051b1372010-04-12 02:42:084136 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:324137}
4138
[email protected]f3b191b2013-06-19 03:43:544139bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha(
4140 bool all_draw_buffers) {
4141 Framebuffer* framebuffer =
4142 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
4143 if (!all_draw_buffers || !framebuffer) {
4144 return (GLES2Util::GetChannelsForFormat(
4145 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
4146 }
4147 return framebuffer->HasAlphaMRT();
[email protected]297ca1c2011-06-20 23:08:464148}
4149
4150bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:354151 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454152 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204153 if (framebuffer) {
4154 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:464155 }
4156 if (offscreen_target_frame_buffer_.get()) {
4157 return offscreen_target_depth_format_ != 0;
4158 }
4159 return back_buffer_has_depth_;
4160}
4161
4162bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:354163 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454164 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204165 if (framebuffer) {
4166 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:464167 }
4168 if (offscreen_target_frame_buffer_.get()) {
4169 return offscreen_target_stencil_format_ != 0 ||
4170 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
4171 }
4172 return back_buffer_has_stencil_;
4173}
4174
4175void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]c986af502013-08-14 01:04:444176 if (framebuffer_state_.clear_state_dirty) {
[email protected]454157e2014-05-03 02:49:454177 bool have_alpha = BoundFramebufferHasColorAttachmentWithAlpha(true);
4178 state_.SetDeviceColorMask(state_.color_mask_red,
4179 state_.color_mask_green,
4180 state_.color_mask_blue,
4181 state_.color_mask_alpha && have_alpha);
4182
[email protected]297ca1c2011-06-20 23:08:464183 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]454157e2014-05-03 02:49:454184 state_.SetDeviceDepthMask(state_.depth_mask && have_depth);
4185
[email protected]297ca1c2011-06-20 23:08:464186 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]454157e2014-05-03 02:49:454187 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424188 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]454157e2014-05-03 02:49:454189 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424190 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]454157e2014-05-03 02:49:454191
4192 state_.SetDeviceCapabilityState(
4193 GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
4194 state_.SetDeviceCapabilityState(
[email protected]f731b9462012-10-30 00:35:224195 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
[email protected]c986af502013-08-14 01:04:444196 framebuffer_state_.clear_state_dirty = false;
[email protected]297ca1c2011-06-20 23:08:464197 }
4198}
4199
[email protected]1868a342012-11-07 15:56:024200GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]7cd76fd2013-06-02 21:11:114201 return (offscreen_target_frame_buffer_.get())
4202 ? offscreen_target_frame_buffer_->id()
4203 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0);
[email protected]1868a342012-11-07 15:56:024204}
4205
[email protected]8875a5f2014-06-27 08:33:474206void GLES2DecoderImpl::RestoreState(const ContextState* prev_state) {
[email protected]962bfbe72013-05-24 11:16:144207 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
4208 "context", logger_.GetLogPrefix());
[email protected]29a4d902013-02-26 20:18:064209 // Restore the Framebuffer first because of bugs in Intel drivers.
4210 // Intel drivers incorrectly clip the viewport settings to
4211 // the size of the current framebuffer object.
4212 RestoreFramebufferBindings();
[email protected]5baa86bc2014-01-16 04:33:164213 state_.RestoreState(prev_state);
[email protected]29a4d902013-02-26 20:18:064214}
4215
4216void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]9d3b2e12013-10-02 01:04:344217 GLuint service_id =
4218 framebuffer_state_.bound_draw_framebuffer.get()
4219 ? framebuffer_state_.bound_draw_framebuffer->service_id()
4220 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064221 if (!features().chromium_framebuffer_multisample) {
4222 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
4223 } else {
4224 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
[email protected]9d3b2e12013-10-02 01:04:344225 service_id = framebuffer_state_.bound_read_framebuffer.get()
4226 ? framebuffer_state_.bound_read_framebuffer->service_id()
[email protected]7cd76fd2013-06-02 21:11:114227 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064228 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
4229 }
[email protected]70d34263c2013-01-09 00:27:454230 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:064231}
4232
[email protected]8875a5f2014-06-27 08:33:474233void GLES2DecoderImpl::RestoreRenderbufferBindings() {
4234 state_.RestoreRenderbufferBindings();
4235}
4236
[email protected]29a4d902013-02-26 20:18:064237void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
[email protected]62e65f02013-05-29 22:28:104238 Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
4239 if (texture) {
[email protected]9bc9a2e82013-04-03 03:56:254240 GLenum target = texture->target();
4241 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:064242 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254243 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:064244 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254245 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:064246 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254247 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:064248 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254249 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:064250 RestoreTextureUnitBindings(state_.active_texture_unit);
4251 }
[email protected]70d34263c2013-01-09 00:27:454252}
4253
[email protected]cd2ef752014-02-12 23:16:034254void GLES2DecoderImpl::ClearAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524255 // Must use native VAO 0, as RestoreAllAttributes can't fully restore
4256 // other VAOs.
4257 if (feature_info_->feature_flags().native_vertex_array_object)
4258 glBindVertexArrayOES(0);
4259
[email protected]cd2ef752014-02-12 23:16:034260 for (uint32 i = 0; i < group_->max_vertex_attribs(); ++i) {
4261 if (i != 0) // Never disable attribute 0
4262 glDisableVertexAttribArray(i);
4263 if(features().angle_instanced_arrays)
4264 glVertexAttribDivisorANGLE(i, 0);
4265 }
4266}
4267
4268void GLES2DecoderImpl::RestoreAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524269 state_.RestoreVertexAttribs();
[email protected]cd2ef752014-02-12 23:16:034270}
4271
[email protected]454157e2014-05-03 02:49:454272void GLES2DecoderImpl::SetIgnoreCachedStateForTest(bool ignore) {
4273 state_.SetIgnoreCachedStateForTest(ignore);
4274}
4275
[email protected]70d34263c2013-01-09 00:27:454276void GLES2DecoderImpl::OnFboChanged() const {
4277 if (workarounds().restore_scissor_on_fbo_change)
[email protected]28718a92013-04-04 12:12:514278 state_.fbo_binding_for_scissor_workaround_dirty_ = true;
ccameron4ff12a732014-12-12 21:38:194279
4280 if (workarounds().gl_begin_gl_end_on_fbo_change_to_backbuffer) {
4281 GLint bound_fbo_unsigned = -1;
4282 glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &bound_fbo_unsigned);
4283 GLuint bound_fbo = static_cast<GLuint>(bound_fbo_unsigned);
4284 if (surface_ && surface_->GetBackingFrameBufferObject() == bound_fbo)
4285 surface_->NotifyWasBound();
4286 }
[email protected]28718a92013-04-04 12:12:514287}
4288
4289// Called after the FBO is checked for completeness.
4290void GLES2DecoderImpl::OnUseFramebuffer() const {
4291 if (state_.fbo_binding_for_scissor_workaround_dirty_) {
4292 state_.fbo_binding_for_scissor_workaround_dirty_ = false;
[email protected]81fc9d02013-03-14 23:53:324293 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:514294 glScissor(state_.scissor_x,
4295 state_.scissor_y,
4296 state_.scissor_width,
4297 state_.scissor_height);
4298
4299 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
4300 // it's unclear how this bug works.
4301 glFlush();
4302 }
[email protected]b177ae22011-11-01 03:29:114303}
4304
[email protected]051b1372010-04-12 02:42:084305void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:064306 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:084307 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034308 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:064309 framebuffer = GetFramebuffer(client_id);
4310 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:354311 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224312 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4313 "glBindFramebuffer",
4314 "id not generated by glGenFramebuffers");
4315 return;
[email protected]bf5a8d132011-08-16 08:39:354316 }
4317
[email protected]4d8f0dd2013-03-09 14:37:064318 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:034319 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354320 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:064321 framebuffer = GetFramebuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034322 } else {
[email protected]4d8f0dd2013-03-09 14:37:064323 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:084324 }
[email protected]4d8f0dd2013-03-09 14:37:064325 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084326 }
[email protected]4d8f0dd2013-03-09 14:37:064327 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:304328
4329 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344330 framebuffer_state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304331 }
[email protected]cac16542014-01-15 17:53:514332
4333 // vmiura: This looks like dup code
[email protected]8e3e0662010-08-23 18:46:304334 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344335 framebuffer_state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304336 }
[email protected]6217d392010-03-25 22:08:354337
[email protected]c986af502013-08-14 01:04:444338 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:464339
[email protected]b177ae22011-11-01 03:29:114340 // If we are rendering to the backbuffer get the FBO id for any simulated
4341 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:064342 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:114343 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:464344 }
[email protected]6217d392010-03-25 22:08:354345
[email protected]051b1372010-04-12 02:42:084346 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:454347 OnFboChanged();
[email protected]86093972010-03-11 00:13:564348}
4349
[email protected]051b1372010-04-12 02:42:084350void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:274351 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:084352 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034353 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:274354 renderbuffer = GetRenderbuffer(client_id);
4355 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:354356 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224357 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4358 "glBindRenderbuffer",
4359 "id not generated by glGenRenderbuffers");
[email protected]bf5a8d132011-08-16 08:39:354360 return;
4361 }
4362
[email protected]8875a5f2014-06-27 08:33:474363 // It's a new id so make a renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:034364 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354365 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:274366 renderbuffer = GetRenderbuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034367 } else {
[email protected]ee2a79c32013-03-10 03:50:274368 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:084369 }
[email protected]ee2a79c32013-03-10 03:50:274370 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084371 }
[email protected]caa13ed2014-02-17 11:29:204372 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenderbuffer");
[email protected]ee2a79c32013-03-10 03:50:274373 state_.bound_renderbuffer = renderbuffer;
[email protected]8875a5f2014-06-27 08:33:474374 state_.bound_renderbuffer_valid = true;
4375 glBindRenderbufferEXT(GL_RENDERBUFFER, service_id);
[email protected]86093972010-03-11 00:13:564376}
4377
[email protected]051b1372010-04-12 02:42:084378void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:494379 TextureRef* texture_ref = NULL;
[email protected]051b1372010-04-12 02:42:084380 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034381 if (client_id != 0) {
[email protected]370eaf12013-05-18 09:19:494382 texture_ref = GetTexture(client_id);
4383 if (!texture_ref) {
[email protected]bf5a8d132011-08-16 08:39:354384 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224385 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4386 "glBindTexture",
4387 "id not generated by glGenTextures");
4388 return;
[email protected]bf5a8d132011-08-16 08:39:354389 }
4390
[email protected]02965c22013-03-09 02:40:074391 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:034392 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:414393 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:354394 CreateTexture(client_id, service_id);
[email protected]370eaf12013-05-18 09:19:494395 texture_ref = GetTexture(client_id);
[email protected]ae51d192010-04-27 00:48:034396 }
4397 } else {
[email protected]370eaf12013-05-18 09:19:494398 texture_ref = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:084399 }
[email protected]ae51d192010-04-27 00:48:034400
[email protected]1958e0e2010-04-22 05:17:154401 // Check the texture exists
[email protected]5ebf59f2014-04-08 03:51:574402 if (texture_ref) {
4403 Texture* texture = texture_ref->texture();
4404 // Check that we are not trying to bind it to a different target.
4405 if (texture->target() != 0 && texture->target() != target) {
4406 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4407 "glBindTexture",
4408 "texture bound to more than 1 target.");
4409 return;
4410 }
4411 LogClientServiceForInfo(texture, client_id, "glBindTexture");
4412 if (texture->target() == 0) {
4413 texture_manager()->SetTarget(texture_ref, target);
4414 }
4415 glBindTexture(target, texture->service_id());
4416 } else {
4417 glBindTexture(target, 0);
[email protected]1958e0e2010-04-22 05:17:154418 }
[email protected]32145a92012-12-17 09:01:594419
[email protected]e259eb412012-10-13 05:47:244420 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:504421 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:474422 switch (target) {
4423 case GL_TEXTURE_2D:
[email protected]370eaf12013-05-18 09:19:494424 unit.bound_texture_2d = texture_ref;
[email protected]a93bb842010-02-16 23:03:474425 break;
4426 case GL_TEXTURE_CUBE_MAP:
[email protected]370eaf12013-05-18 09:19:494427 unit.bound_texture_cube_map = texture_ref;
[email protected]a93bb842010-02-16 23:03:474428 break;
[email protected]61eeb33f2011-07-26 15:30:314429 case GL_TEXTURE_EXTERNAL_OES:
[email protected]370eaf12013-05-18 09:19:494430 unit.bound_texture_external_oes = texture_ref;
[email protected]61eeb33f2011-07-26 15:30:314431 break;
[email protected]e51bdf32011-11-23 22:21:464432 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]370eaf12013-05-18 09:19:494433 unit.bound_texture_rectangle_arb = texture_ref;
[email protected]e51bdf32011-11-23 22:21:464434 break;
[email protected]a93bb842010-02-16 23:03:474435 default:
4436 NOTREACHED(); // Validation should prevent us getting here.
4437 break;
4438 }
4439}
4440
[email protected]07f54fcc2009-12-22 02:46:304441void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244442 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:124443 if (index != 0 ||
4444 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:244445 glDisableVertexAttribArray(index);
4446 }
[email protected]07f54fcc2009-12-22 02:46:304447 } else {
[email protected]ab09b612013-03-11 22:11:514448 LOCAL_SET_GL_ERROR(
4449 GL_INVALID_VALUE,
4450 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304451 }
4452}
4453
[email protected]60f22d32012-12-12 00:31:584454void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
4455 GLsizei numAttachments,
4456 const GLenum* attachments) {
[email protected]ed9f9cd2013-02-27 21:12:354457 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:584458 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4459
4460 // Validates the attachments. If one of them fails
4461 // the whole command fails.
4462 for (GLsizei i = 0; i < numAttachments; ++i) {
4463 if ((framebuffer &&
4464 !validators_->attachment.IsValid(attachments[i])) ||
4465 (!framebuffer &&
4466 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:514467 LOCAL_SET_GL_ERROR_INVALID_ENUM(
4468 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:584469 return;
4470 }
4471 }
4472
4473 // Marks each one of them as not cleared
4474 for (GLsizei i = 0; i < numAttachments; ++i) {
4475 if (framebuffer) {
4476 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
4477 texture_manager(),
4478 attachments[i],
4479 false);
4480 } else {
4481 switch (attachments[i]) {
4482 case GL_COLOR_EXT:
4483 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
4484 break;
4485 case GL_DEPTH_EXT:
4486 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
4487 case GL_STENCIL_EXT:
4488 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
4489 break;
4490 default:
4491 NOTREACHED();
4492 break;
4493 }
4494 }
4495 }
4496
[email protected]d49c5402013-09-11 15:39:024497 // If the default framebuffer is bound but we are still rendering to an
4498 // FBO, translate attachment names that refer to default framebuffer
4499 // channels to corresponding framebuffer attachments.
4500 scoped_ptr<GLenum[]> translated_attachments(new GLenum[numAttachments]);
4501 for (GLsizei i = 0; i < numAttachments; ++i) {
4502 GLenum attachment = attachments[i];
4503 if (!framebuffer && GetBackbufferServiceId()) {
4504 switch (attachment) {
4505 case GL_COLOR_EXT:
4506 attachment = GL_COLOR_ATTACHMENT0;
4507 break;
4508 case GL_DEPTH_EXT:
4509 attachment = GL_DEPTH_ATTACHMENT;
4510 break;
4511 case GL_STENCIL_EXT:
4512 attachment = GL_STENCIL_ATTACHMENT;
4513 break;
4514 default:
4515 NOTREACHED();
4516 return;
4517 }
4518 }
4519 translated_attachments[i] = attachment;
4520 }
4521
boliu2e7d8a7a2014-10-16 20:35:204522 ScopedRenderTo do_render(framebuffer);
zmo68fcdc62014-12-05 21:51:494523 if (feature_info_->gl_version_info().is_es3) {
4524 glInvalidateFramebuffer(
4525 target, numAttachments, translated_attachments.get());
4526 } else {
4527 glDiscardFramebufferEXT(
4528 target, numAttachments, translated_attachments.get());
4529 }
[email protected]60f22d32012-12-12 00:31:584530}
4531
[email protected]07f54fcc2009-12-22 02:46:304532void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244533 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:304534 glEnableVertexAttribArray(index);
4535 } else {
[email protected]ab09b612013-03-11 22:11:514536 LOCAL_SET_GL_ERROR(
4537 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304538 }
4539}
4540
[email protected]a93bb842010-02-16 23:03:474541void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]c986af502013-08-14 01:04:444542 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
4543 &state_, target);
[email protected]370eaf12013-05-18 09:19:494544 if (!texture_ref ||
4545 !texture_manager()->CanGenerateMipmaps(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:514546 LOCAL_SET_GL_ERROR(
4547 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:474548 return;
4549 }
[email protected]38c0a972012-05-12 00:48:024550
[email protected]12d95352012-12-14 07:23:544551 if (target == GL_TEXTURE_CUBE_MAP) {
4552 for (int i = 0; i < 6; ++i) {
4553 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]370eaf12013-05-18 09:19:494554 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
[email protected]ab09b612013-03-11 22:11:514555 LOCAL_SET_GL_ERROR(
4556 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544557 return;
4558 }
4559 }
4560 } else {
[email protected]370eaf12013-05-18 09:19:494561 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
[email protected]ab09b612013-03-11 22:11:514562 LOCAL_SET_GL_ERROR(
4563 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544564 return;
4565 }
[email protected]7687479c2012-05-14 23:54:044566 }
4567
[email protected]ab09b612013-03-11 22:11:514568 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:194569 // Workaround for Mac driver bug. In the large scheme of things setting
4570 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:564571 // hit so there's probably no need to make this conditional. The bug appears
4572 // to be that if the filtering mode is set to something that doesn't require
4573 // mipmaps for rendering, or is never set to something other than the default,
4574 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:154575 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:194576 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4577 }
[email protected]a93bb842010-02-16 23:03:474578 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:154579 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]370eaf12013-05-18 09:19:494580 glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
4581 texture_ref->texture()->min_filter());
[email protected]c892a4e12012-05-08 18:20:194582 }
[email protected]ab09b612013-03-11 22:11:514583 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:024584 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:494585 texture_manager()->MarkMipmapsGenerated(texture_ref);
[email protected]38c0a972012-05-12 00:48:024586 }
[email protected]a93bb842010-02-16 23:03:474587}
4588
[email protected]b273e432010-04-12 17:23:584589bool GLES2DecoderImpl::GetHelper(
4590 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:584591 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:154592 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4593 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434594 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4595 *num_written = 1;
[email protected]c959a09a2014-03-27 11:44:214596 // Return the GL implementation's preferred format and (see below type)
4597 // if we have the GL extension that exposes this. This allows the GPU
4598 // client to use the implementation's preferred format for glReadPixels
4599 // for optimisation.
4600 //
4601 // A conflicting extension (GL_ARB_ES2_compatibility) specifies an error
4602 // case when requested on integer/floating point buffers but which is
4603 // acceptable on GLES2 and with the GL_OES_read_format extension.
4604 //
4605 // Therefore if an error occurs we swallow the error and use the
4606 // internal implementation.
[email protected]ad84a3a2012-06-08 21:42:434607 if (params) {
[email protected]c959a09a2014-03-27 11:44:214608 if (context_->HasExtension("GL_OES_read_format")) {
4609 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4610 GetErrorState());
4611 glGetIntegerv(pname, params);
4612 if (glGetError() == GL_NO_ERROR)
4613 return true;
4614 }
[email protected]68586372013-12-11 01:27:594615 *params = GLES2Util::GetPreferredGLReadPixelsFormat(
4616 GetBoundReadFrameBufferInternalFormat());
[email protected]ad84a3a2012-06-08 21:42:434617 }
4618 return true;
4619 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4620 *num_written = 1;
4621 if (params) {
[email protected]c959a09a2014-03-27 11:44:214622 if (context_->HasExtension("GL_OES_read_format")) {
4623 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4624 GetErrorState());
4625 glGetIntegerv(pname, params);
4626 if (glGetError() == GL_NO_ERROR)
4627 return true;
4628 }
[email protected]68586372013-12-11 01:27:594629 *params = GLES2Util::GetPreferredGLReadPixelsType(
4630 GetBoundReadFrameBufferInternalFormat(),
4631 GetBoundReadFrameBufferTextureType());
[email protected]ad84a3a2012-06-08 21:42:434632 }
4633 return true;
4634 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4635 *num_written = 1;
4636 if (params) {
4637 *params = group_->max_fragment_uniform_vectors();
4638 }
4639 return true;
4640 case GL_MAX_VARYING_VECTORS:
4641 *num_written = 1;
4642 if (params) {
4643 *params = group_->max_varying_vectors();
4644 }
4645 return true;
4646 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4647 *num_written = 1;
4648 if (params) {
4649 *params = group_->max_vertex_uniform_vectors();
4650 }
4651 return true;
[email protected]4e8a5b122010-05-08 22:00:104652 }
[email protected]5cb735d2011-10-13 01:37:234653 }
4654 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:244655 case GL_MAX_VIEWPORT_DIMS:
4656 if (offscreen_target_frame_buffer_.get()) {
4657 *num_written = 2;
4658 if (params) {
4659 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4660 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4661 }
4662 return true;
4663 }
[email protected]5cb735d2011-10-13 01:37:234664 return false;
[email protected]84afefa2011-10-19 21:45:534665 case GL_MAX_SAMPLES:
4666 *num_written = 1;
4667 if (params) {
4668 params[0] = renderbuffer_manager()->max_samples();
4669 }
4670 return true;
4671 case GL_MAX_RENDERBUFFER_SIZE:
4672 *num_written = 1;
4673 if (params) {
4674 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4675 }
4676 return true;
[email protected]5cb735d2011-10-13 01:37:234677 case GL_MAX_TEXTURE_SIZE:
4678 *num_written = 1;
4679 if (params) {
4680 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4681 }
4682 return true;
4683 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4684 *num_written = 1;
4685 if (params) {
4686 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4687 }
4688 return true;
[email protected]2f143d482013-03-14 18:04:494689 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4690 *num_written = 1;
4691 if (params) {
4692 params[0] = group_->max_color_attachments();
4693 }
4694 return true;
4695 case GL_MAX_DRAW_BUFFERS_ARB:
4696 *num_written = 1;
4697 if (params) {
4698 params[0] = group_->max_draw_buffers();
4699 }
4700 return true;
[email protected]297ca1c2011-06-20 23:08:464701 case GL_ALPHA_BITS:
4702 *num_written = 1;
4703 if (params) {
4704 GLint v = 0;
4705 glGetIntegerv(GL_ALPHA_BITS, &v);
[email protected]f3b191b2013-06-19 03:43:544706 params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
[email protected]297ca1c2011-06-20 23:08:464707 }
4708 return true;
4709 case GL_DEPTH_BITS:
4710 *num_written = 1;
4711 if (params) {
4712 GLint v = 0;
4713 glGetIntegerv(GL_DEPTH_BITS, &v);
4714 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4715 }
4716 return true;
4717 case GL_STENCIL_BITS:
4718 *num_written = 1;
4719 if (params) {
4720 GLint v = 0;
4721 glGetIntegerv(GL_STENCIL_BITS, &v);
4722 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4723 }
4724 return true;
[email protected]656dcaad2010-05-07 17:18:374725 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114726 *num_written = validators_->compressed_texture_format.GetValues().size();
4727 if (params) {
4728 for (GLint ii = 0; ii < *num_written; ++ii) {
4729 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4730 }
4731 }
[email protected]656dcaad2010-05-07 17:18:374732 return true;
[email protected]b273e432010-04-12 17:23:584733 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4734 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104735 if (params) {
[email protected]302ce6d2011-07-07 23:28:114736 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104737 }
[email protected]b273e432010-04-12 17:23:584738 return true;
4739 case GL_NUM_SHADER_BINARY_FORMATS:
4740 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104741 if (params) {
[email protected]302ce6d2011-07-07 23:28:114742 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104743 }
[email protected]b273e432010-04-12 17:23:584744 return true;
4745 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114746 *num_written = validators_->shader_binary_format.GetValues().size();
4747 if (params) {
4748 for (GLint ii = 0; ii < *num_written; ++ii) {
4749 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4750 }
4751 }
4752 return true;
[email protected]b273e432010-04-12 17:23:584753 case GL_SHADER_COMPILER:
4754 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104755 if (params) {
4756 *params = GL_TRUE;
4757 }
[email protected]b273e432010-04-12 17:23:584758 return true;
[email protected]6b8cf1a2010-05-06 16:13:584759 case GL_ARRAY_BUFFER_BINDING:
4760 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104761 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114762 if (state_.bound_array_buffer.get()) {
[email protected]4e8a5b122010-05-08 22:00:104763 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:244764 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:104765 &client_id);
4766 *params = client_id;
4767 } else {
4768 *params = 0;
4769 }
[email protected]6b8cf1a2010-05-06 16:13:584770 }
4771 return true;
4772 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4773 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104774 if (params) {
[email protected]e259eb412012-10-13 05:47:244775 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:104776 GLuint client_id = 0;
4777 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:254778 state_.vertex_attrib_manager->element_array_buffer()->
4779 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104780 *params = client_id;
4781 } else {
4782 *params = 0;
4783 }
[email protected]6b8cf1a2010-05-06 16:13:584784 }
4785 return true;
4786 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304787 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584788 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104789 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354790 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454791 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204792 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104793 GLuint client_id = 0;
4794 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204795 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304796 *params = client_id;
4797 } else {
4798 *params = 0;
4799 }
4800 }
4801 return true;
[email protected]ebfb73c2012-08-15 02:37:454802 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304803 *num_written = 1;
4804 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354805 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454806 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204807 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304808 GLuint client_id = 0;
4809 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204810 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104811 *params = client_id;
4812 } else {
4813 *params = 0;
4814 }
[email protected]6b8cf1a2010-05-06 16:13:584815 }
4816 return true;
4817 case GL_RENDERBUFFER_BINDING:
4818 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104819 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354820 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204821 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4822 if (renderbuffer) {
[email protected]62e65f02013-05-29 22:28:104823 *params = renderbuffer->client_id();
[email protected]4e8a5b122010-05-08 22:00:104824 } else {
4825 *params = 0;
4826 }
[email protected]6b8cf1a2010-05-06 16:13:584827 }
4828 return true;
4829 case GL_CURRENT_PROGRAM:
4830 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104831 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114832 if (state_.current_program.get()) {
[email protected]4e8a5b122010-05-08 22:00:104833 GLuint client_id = 0;
4834 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244835 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104836 *params = client_id;
4837 } else {
4838 *params = 0;
4839 }
[email protected]6b8cf1a2010-05-06 16:13:584840 }
4841 return true;
[email protected]bf835842012-11-19 15:21:514842 case GL_VERTEX_ARRAY_BINDING_OES:
4843 *num_written = 1;
4844 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114845 if (state_.vertex_attrib_manager.get() !=
[email protected]81f20a622014-04-18 01:54:524846 state_.default_vertex_attrib_manager.get()) {
[email protected]bf835842012-11-19 15:21:514847 GLuint client_id = 0;
4848 vertex_array_manager_->GetClientId(
4849 state_.vertex_attrib_manager->service_id(), &client_id);
4850 *params = client_id;
4851 } else {
4852 *params = 0;
4853 }
4854 }
4855 return true;
[email protected]4e8a5b122010-05-08 22:00:104856 case GL_TEXTURE_BINDING_2D:
4857 *num_written = 1;
4858 if (params) {
[email protected]e259eb412012-10-13 05:47:244859 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114860 if (unit.bound_texture_2d.get()) {
[email protected]62e65f02013-05-29 22:28:104861 *params = unit.bound_texture_2d->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584862 } else {
4863 *params = 0;
4864 }
[email protected]6b8cf1a2010-05-06 16:13:584865 }
[email protected]4e8a5b122010-05-08 22:00:104866 return true;
4867 case GL_TEXTURE_BINDING_CUBE_MAP:
4868 *num_written = 1;
4869 if (params) {
[email protected]e259eb412012-10-13 05:47:244870 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114871 if (unit.bound_texture_cube_map.get()) {
[email protected]62e65f02013-05-29 22:28:104872 *params = unit.bound_texture_cube_map->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584873 } else {
4874 *params = 0;
4875 }
[email protected]6b8cf1a2010-05-06 16:13:584876 }
[email protected]4e8a5b122010-05-08 22:00:104877 return true;
[email protected]61eeb33f2011-07-26 15:30:314878 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4879 *num_written = 1;
4880 if (params) {
[email protected]e259eb412012-10-13 05:47:244881 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114882 if (unit.bound_texture_external_oes.get()) {
[email protected]62e65f02013-05-29 22:28:104883 *params = unit.bound_texture_external_oes->client_id();
[email protected]61eeb33f2011-07-26 15:30:314884 } else {
4885 *params = 0;
4886 }
4887 }
4888 return true;
[email protected]e51bdf32011-11-23 22:21:464889 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4890 *num_written = 1;
4891 if (params) {
[email protected]e259eb412012-10-13 05:47:244892 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114893 if (unit.bound_texture_rectangle_arb.get()) {
[email protected]62e65f02013-05-29 22:28:104894 *params = unit.bound_texture_rectangle_arb->client_id();
[email protected]e51bdf32011-11-23 22:21:464895 } else {
4896 *params = 0;
4897 }
4898 }
4899 return true;
[email protected]6c75c712012-06-19 15:43:174900 case GL_UNPACK_FLIP_Y_CHROMIUM:
4901 *num_written = 1;
4902 if (params) {
4903 params[0] = unpack_flip_y_;
4904 }
4905 return true;
4906 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4907 *num_written = 1;
4908 if (params) {
4909 params[0] = unpack_premultiply_alpha_;
4910 }
4911 return true;
4912 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4913 *num_written = 1;
4914 if (params) {
4915 params[0] = unpack_unpremultiply_alpha_;
4916 }
4917 return true;
[email protected]6eda6822014-04-03 23:00:504918 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
4919 *num_written = 1;
4920 if (params) {
4921 params[0] = group_->bind_generates_resource() ? 1 : 0;
4922 }
4923 return true;
[email protected]b273e432010-04-12 17:23:584924 default:
[email protected]2f143d482013-03-14 18:04:494925 if (pname >= GL_DRAW_BUFFER0_ARB &&
4926 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
4927 *num_written = 1;
4928 if (params) {
4929 Framebuffer* framebuffer =
4930 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4931 if (framebuffer) {
4932 params[0] = framebuffer->GetDrawBuffer(pname);
4933 } else { // backbuffer
4934 if (pname == GL_DRAW_BUFFER0_ARB)
4935 params[0] = group_->draw_buffer();
4936 else
4937 params[0] = GL_NONE;
4938 }
4939 }
4940 return true;
4941 }
[email protected]4e8a5b122010-05-08 22:00:104942 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534943 return false;
[email protected]b273e432010-04-12 17:23:584944 }
4945}
4946
[email protected]4e8a5b122010-05-08 22:00:104947bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4948 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264949 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534950 return true;
4951 }
[email protected]4e8a5b122010-05-08 22:00:104952 return GetHelper(pname, NULL, num_values);
4953}
4954
[email protected]7d3c36e2013-07-12 14:13:164955GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) {
4956 if (GL_MAX_SAMPLES == pname &&
4957 features().use_img_for_multisampled_render_to_texture) {
4958 return GL_MAX_SAMPLES_IMG;
4959 }
4960 return pname;
4961}
4962
[email protected]b273e432010-04-12 17:23:584963void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4964 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104965 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534966 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554967 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:264968 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:534969 GetHelper(pname, values.get(), &num_written);
4970 }
[email protected]b273e432010-04-12 17:23:584971 for (GLsizei ii = 0; ii < num_written; ++ii) {
4972 params[ii] = static_cast<GLboolean>(values[ii]);
4973 }
4974 } else {
[email protected]7d3c36e2013-07-12 14:13:164975 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584976 glGetBooleanv(pname, params);
4977 }
4978}
4979
4980void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4981 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104982 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:264983 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:534984 if (GetHelper(pname, NULL, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554985 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]f63b1232012-10-31 07:03:534986 GetHelper(pname, values.get(), &num_written);
4987 for (GLsizei ii = 0; ii < num_written; ++ii) {
4988 params[ii] = static_cast<GLfloat>(values[ii]);
4989 }
4990 } else {
[email protected]7d3c36e2013-07-12 14:13:164991 pname = AdjustGetPname(pname);
[email protected]f63b1232012-10-31 07:03:534992 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:584993 }
[email protected]b273e432010-04-12 17:23:584994 }
4995}
4996
4997void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4998 DCHECK(params);
4999 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:265000 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:535001 !GetHelper(pname, params, &num_written)) {
[email protected]7d3c36e2013-07-12 14:13:165002 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:585003 glGetIntegerv(pname, params);
5004 }
5005}
5006
[email protected]a0c3e972010-04-21 00:49:135007void GLES2DecoderImpl::DoGetProgramiv(
5008 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:425009 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
5010 if (!program) {
[email protected]a0c3e972010-04-21 00:49:135011 return;
5012 }
[email protected]df37b9932013-03-08 05:21:425013 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:135014}
5015
[email protected]17cfbe0e2013-03-07 01:26:085016void GLES2DecoderImpl::DoGetBufferParameteriv(
5017 GLenum target, GLenum pname, GLint* params) {
[email protected]0fbba3732013-07-17 15:40:135018 // Just delegate it. Some validation is actually done before this.
5019 buffer_manager()->ValidateAndDoGetBufferParameteriv(
5020 &state_, target, pname, params);
[email protected]17cfbe0e2013-03-07 01:26:085021}
5022
[email protected]258a3313f2011-10-18 20:13:575023void GLES2DecoderImpl::DoBindAttribLocation(
[email protected]df37b9932013-03-08 05:21:425024 GLuint program_id, GLuint index, const char* name) {
[email protected]258a3313f2011-10-18 20:13:575025 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:515026 LOCAL_SET_GL_ERROR(
5027 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:575028 return;
5029 }
[email protected]68dcb1f2012-04-07 00:14:565030 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:515031 LOCAL_SET_GL_ERROR(
5032 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:565033 return;
5034 }
5035 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:515036 LOCAL_SET_GL_ERROR(
5037 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:565038 return;
5039 }
[email protected]df37b9932013-03-08 05:21:425040 Program* program = GetProgramInfoNotShader(
5041 program_id, "glBindAttribLocation");
5042 if (!program) {
[email protected]258a3313f2011-10-18 20:13:575043 return;
[email protected]558847a2010-03-24 07:02:545044 }
zmo460b593e2014-10-13 23:07:455045 // At this point, the program's shaders may not be translated yet,
5046 // therefore, we may not find the hashed attribute name.
5047 // glBindAttribLocation call with original name is useless.
5048 // So instead, we should simply cache the binding, and then call
5049 // Program::ExecuteBindAttribLocationCalls() right before link.
[email protected]df37b9932013-03-08 05:21:425050 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
zmo460b593e2014-10-13 23:07:455051 // TODO(zmo): Get rid of the following glBindAttribLocation call.
[email protected]df37b9932013-03-08 05:21:425052 glBindAttribLocation(program->service_id(), index, name);
[email protected]258a3313f2011-10-18 20:13:575053}
5054
[email protected]558847a2010-03-24 07:02:545055error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
vmiuracd108592014-09-08 14:36:345056 uint32 immediate_data_size,
5057 const void* cmd_data) {
5058 const gles2::cmds::BindAttribLocationBucket& c =
5059 *static_cast<const gles2::cmds::BindAttribLocationBucket*>(cmd_data);
[email protected]6b8cf1a2010-05-06 16:13:585060 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:545061 GLuint index = static_cast<GLuint>(c.index);
5062 Bucket* bucket = GetBucket(c.name_bucket_id);
5063 if (!bucket || bucket->size() == 0) {
5064 return error::kInvalidArguments;
5065 }
5066 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:185067 if (!bucket->GetAsString(&name_str)) {
5068 return error::kInvalidArguments;
5069 }
[email protected]258a3313f2011-10-18 20:13:575070 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:545071 return error::kNoError;
5072}
5073
[email protected]2be6abf32012-06-26 00:28:335074void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:425075 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:335076 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:515077 LOCAL_SET_GL_ERROR(
5078 GL_INVALID_VALUE,
5079 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:335080 return;
5081 }
5082 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:515083 LOCAL_SET_GL_ERROR(
5084 GL_INVALID_OPERATION,
5085 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:335086 return;
5087 }
5088 if (location < 0 || static_cast<uint32>(location) >=
5089 (group_->max_fragment_uniform_vectors() +
5090 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:515091 LOCAL_SET_GL_ERROR(
5092 GL_INVALID_VALUE,
5093 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:335094 return;
5095 }
[email protected]df37b9932013-03-08 05:21:425096 Program* program = GetProgramInfoNotShader(
5097 program_id, "glBindUniformLocationCHROMIUM");
5098 if (!program) {
[email protected]2be6abf32012-06-26 00:28:335099 return;
5100 }
[email protected]df37b9932013-03-08 05:21:425101 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:515102 LOCAL_SET_GL_ERROR(
5103 GL_INVALID_VALUE,
5104 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:335105 }
5106}
5107
[email protected]2be6abf32012-06-26 00:28:335108error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
5109 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:345110 const void* cmd_data) {
5111 const gles2::cmds::BindUniformLocationCHROMIUMBucket& c =
5112 *static_cast<const gles2::cmds::BindUniformLocationCHROMIUMBucket*>(
5113 cmd_data);
[email protected]2be6abf32012-06-26 00:28:335114 GLuint program = static_cast<GLuint>(c.program);
5115 GLint location = static_cast<GLint>(c.location);
5116 Bucket* bucket = GetBucket(c.name_bucket_id);
5117 if (!bucket || bucket->size() == 0) {
5118 return error::kInvalidArguments;
5119 }
5120 std::string name_str;
5121 if (!bucket->GetAsString(&name_str)) {
5122 return error::kInvalidArguments;
5123 }
5124 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
5125 return error::kNoError;
5126}
5127
vmiuracd108592014-09-08 14:36:345128error::Error GLES2DecoderImpl::HandleDeleteShader(uint32 immediate_data_size,
5129 const void* cmd_data) {
5130 const gles2::cmds::DeleteShader& c =
5131 *static_cast<const gles2::cmds::DeleteShader*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:035132 GLuint client_id = c.shader;
5133 if (client_id) {
[email protected]df37b9932013-03-08 05:21:425134 Shader* shader = GetShader(client_id);
5135 if (shader) {
5136 if (!shader->IsDeleted()) {
5137 glDeleteShader(shader->service_id());
5138 shader_manager()->MarkAsDeleted(shader);
[email protected]ca488e12010-12-13 20:06:145139 }
[email protected]ae51d192010-04-27 00:48:035140 } else {
[email protected]ab09b612013-03-11 22:11:515141 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:035142 }
[email protected]96449d2c2009-11-25 00:01:325143 }
[email protected]f7a64ee2010-02-01 22:24:145144 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:325145}
5146
vmiuracd108592014-09-08 14:36:345147error::Error GLES2DecoderImpl::HandleDeleteProgram(uint32 immediate_data_size,
5148 const void* cmd_data) {
5149 const gles2::cmds::DeleteProgram& c =
5150 *static_cast<const gles2::cmds::DeleteProgram*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:035151 GLuint client_id = c.program;
5152 if (client_id) {
[email protected]df37b9932013-03-08 05:21:425153 Program* program = GetProgram(client_id);
5154 if (program) {
5155 if (!program->IsDeleted()) {
5156 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:145157 }
[email protected]ae51d192010-04-27 00:48:035158 } else {
[email protected]ab09b612013-03-11 22:11:515159 LOCAL_SET_GL_ERROR(
5160 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:035161 }
[email protected]96449d2c2009-11-25 00:01:325162 }
[email protected]f7a64ee2010-02-01 22:24:145163 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:325164}
5165
[email protected]a7266a92012-06-28 02:11:085166error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:445167 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:205168 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]297ca1c2011-06-20 23:08:465169 ApplyDirtyState();
boliu2e7d8a7a2014-10-16 20:35:205170 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
sievers2384f2b2014-11-18 02:10:355171 if (workarounds().gl_clear_broken) {
5172 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::ClearWorkaround",
5173 GetErrorState());
5174 if (!BoundFramebufferHasDepthAttachment())
5175 mask &= ~GL_DEPTH_BUFFER_BIT;
5176 if (!BoundFramebufferHasStencilAttachment())
5177 mask &= ~GL_STENCIL_BUFFER_BIT;
5178 clear_framebuffer_blit_->ClearFramebuffer(
5179 this, GetBoundReadFrameBufferSize(), mask, state_.color_clear_red,
5180 state_.color_clear_green, state_.color_clear_blue,
5181 state_.color_clear_alpha, state_.depth_clear, state_.stencil_clear);
5182 return error::kNoError;
5183 }
[email protected]3a03a8f2011-03-19 00:51:275184 glClear(mask);
5185 }
[email protected]a7266a92012-06-28 02:11:085186 return error::kNoError;
5187}
5188
[email protected]36cef8ce2010-03-16 07:34:455189void GLES2DecoderImpl::DoFramebufferRenderbuffer(
5190 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:035191 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:065192 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5193 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515194 LOCAL_SET_GL_ERROR(
5195 GL_INVALID_OPERATION,
5196 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455197 return;
5198 }
[email protected]ae51d192010-04-27 00:48:035199 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:275200 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:035201 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:275202 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
5203 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515204 LOCAL_SET_GL_ERROR(
5205 GL_INVALID_OPERATION,
5206 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:035207 return;
5208 }
[email protected]ee2a79c32013-03-10 03:50:275209 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:035210 }
[email protected]ab09b612013-03-11 22:11:515211 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:035212 glFramebufferRenderbufferEXT(
5213 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:515214 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:265215 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:275216 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:285217 }
[email protected]9d3b2e12013-10-02 01:04:345218 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445219 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465220 }
[email protected]81fc9d02013-03-14 23:53:325221 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:285222}
5223
[email protected]3a2e7c7b2010-08-06 01:12:285224void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465225 if (SetCapabilityState(cap, false)) {
5226 glDisable(cap);
5227 }
[email protected]3a2e7c7b2010-08-06 01:12:285228}
5229
5230void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465231 if (SetCapabilityState(cap, true)) {
5232 glEnable(cap);
5233 }
[email protected]3a2e7c7b2010-08-06 01:12:285234}
5235
[email protected]88a61bf2012-10-27 13:00:425236void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
5237 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
5238 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
5239 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:285240}
5241
[email protected]b04e24c2013-01-08 18:35:255242void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:425243 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
5244 state_.sample_coverage_invert = (invert != 0);
5245 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:285246}
5247
[email protected]0d6bfdc2011-11-02 01:32:205248// Assumes framebuffer is complete.
5249void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:065250 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:305251 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:205252 // bind this to the DRAW point, clear then bind back to READ
5253 // TODO(gman): I don't think there is any guarantee that an FBO that
5254 // is complete on the READ attachment will be complete as a DRAW
5255 // attachment.
5256 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:065257 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:305258 }
[email protected]3a2e7c7b2010-08-06 01:12:285259 GLbitfield clear_bits = 0;
[email protected]ee757922014-06-06 05:21:425260 if (framebuffer->HasUnclearedColorAttachments()) {
[email protected]297ca1c2011-06-20 23:08:465261 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:205262 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:465263 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:065264 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
5265 1.0f);
[email protected]454157e2014-05-03 02:49:455266 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285267 clear_bits |= GL_COLOR_BUFFER_BIT;
[email protected]0e58af82014-08-08 14:02:535268 if (feature_info_->feature_flags().ext_draw_buffers)
5269 framebuffer->PrepareDrawBuffersForClear();
[email protected]3a2e7c7b2010-08-06 01:12:285270 }
5271
[email protected]4d8f0dd2013-03-09 14:37:065272 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
5273 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285274 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:475275 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
5276 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]3a2e7c7b2010-08-06 01:12:285277 clear_bits |= GL_STENCIL_BUFFER_BIT;
5278 }
5279
[email protected]4d8f0dd2013-03-09 14:37:065280 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
5281 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285282 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:455283 state_.SetDeviceDepthMask(GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285284 clear_bits |= GL_DEPTH_BUFFER_BIT;
5285 }
5286
[email protected]454157e2014-05-03 02:49:455287 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]3a2e7c7b2010-08-06 01:12:285288 glClear(clear_bits);
5289
brucedawson18249152014-10-31 23:02:325290 if ((clear_bits & GL_COLOR_BUFFER_BIT) != 0 &&
[email protected]0e58af82014-08-08 14:02:535291 feature_info_->feature_flags().ext_draw_buffers)
[email protected]ee757922014-06-06 05:21:425292 framebuffer->RestoreDrawBuffersAfterClear();
5293
[email protected]968351b2011-12-20 08:26:515294 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:065295 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:285296
[email protected]c007aa02010-09-02 22:22:405297 RestoreClearState();
5298
5299 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:065300 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
5301 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:485302 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:065303 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
5304 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:485305 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:405306 }
5307}
5308
5309void GLES2DecoderImpl::RestoreClearState() {
[email protected]c986af502013-08-14 01:04:445310 framebuffer_state_.clear_state_dirty = true;
[email protected]e259eb412012-10-13 05:47:245311 glClearColor(
5312 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
5313 state_.color_clear_alpha);
5314 glClearStencil(state_.stencil_clear);
5315 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:225316 if (state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:455317 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]3a2e7c7b2010-08-06 01:12:285318 }
[email protected]36cef8ce2010-03-16 07:34:455319}
5320
5321GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:355322 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:305323 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:205324 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:455325 return GL_FRAMEBUFFER_COMPLETE;
5326 }
[email protected]0d6bfdc2011-11-02 01:32:205327 GLenum completeness = framebuffer->IsPossiblyComplete();
5328 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
5329 return completeness;
5330 }
[email protected]73276522012-11-09 05:50:205331 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:455332}
5333
5334void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:035335 GLenum target, GLenum attachment, GLenum textarget,
5336 GLuint client_texture_id, GLint level) {
[email protected]7d3c36e2013-07-12 14:13:165337 DoFramebufferTexture2DCommon(
5338 "glFramebufferTexture2D", target, attachment,
5339 textarget, client_texture_id, level, 0);
5340}
5341
5342void GLES2DecoderImpl::DoFramebufferTexture2DMultisample(
5343 GLenum target, GLenum attachment, GLenum textarget,
5344 GLuint client_texture_id, GLint level, GLsizei samples) {
[email protected]7d3c36e2013-07-12 14:13:165345 DoFramebufferTexture2DCommon(
5346 "glFramebufferTexture2DMultisample", target, attachment,
5347 textarget, client_texture_id, level, samples);
5348}
5349
5350void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
5351 const char* name, GLenum target, GLenum attachment, GLenum textarget,
5352 GLuint client_texture_id, GLint level, GLsizei samples) {
5353 if (samples > renderbuffer_manager()->max_samples()) {
5354 LOCAL_SET_GL_ERROR(
5355 GL_INVALID_VALUE,
5356 "glFramebufferTexture2DMultisample", "samples too large");
5357 return;
5358 }
[email protected]4d8f0dd2013-03-09 14:37:065359 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5360 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515361 LOCAL_SET_GL_ERROR(
5362 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165363 name, "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:455364 return;
5365 }
[email protected]ae51d192010-04-27 00:48:035366 GLuint service_id = 0;
[email protected]370eaf12013-05-18 09:19:495367 TextureRef* texture_ref = NULL;
[email protected]ae51d192010-04-27 00:48:035368 if (client_texture_id) {
[email protected]370eaf12013-05-18 09:19:495369 texture_ref = GetTexture(client_texture_id);
5370 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:515371 LOCAL_SET_GL_ERROR(
5372 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165373 name, "unknown texture_ref");
[email protected]ae51d192010-04-27 00:48:035374 return;
5375 }
[email protected]370eaf12013-05-18 09:19:495376 service_id = texture_ref->service_id();
[email protected]ae51d192010-04-27 00:48:035377 }
[email protected]0d6bfdc2011-11-02 01:32:205378
[email protected]80eb6b52012-01-19 00:14:415379 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:515380 LOCAL_SET_GL_ERROR(
5381 GL_INVALID_VALUE,
[email protected]7d3c36e2013-07-12 14:13:165382 name, "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:205383 return;
5384 }
5385
[email protected]91c94eb2013-10-22 10:32:545386 if (texture_ref)
5387 DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget);
5388
[email protected]7d3c36e2013-07-12 14:13:165389 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
5390 if (0 == samples) {
5391 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
5392 } else {
5393 if (features().use_img_for_multisampled_render_to_texture) {
5394 glFramebufferTexture2DMultisampleIMG(target, attachment, textarget,
5395 service_id, level, samples);
5396 } else {
5397 glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
5398 service_id, level, samples);
5399 }
5400 }
5401 GLenum error = LOCAL_PEEK_GL_ERROR(name);
[email protected]9edc6b22010-12-23 02:00:265402 if (error == GL_NO_ERROR) {
[email protected]7d3c36e2013-07-12 14:13:165403 framebuffer->AttachTexture(attachment, texture_ref, textarget, level,
5404 samples);
[email protected]3a2e7c7b2010-08-06 01:12:285405 }
[email protected]9d3b2e12013-10-02 01:04:345406 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445407 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465408 }
[email protected]91c94eb2013-10-22 10:32:545409
5410 if (texture_ref)
5411 DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget);
5412
[email protected]81fc9d02013-03-14 23:53:325413 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:455414}
5415
zmo84c08202014-11-23 15:28:405416void GLES2DecoderImpl::DoFramebufferTextureLayer(
5417 GLenum target, GLenum attachment, GLuint client_texture_id,
5418 GLint level, GLint layer) {
5419 // TODO(zmo): Unsafe ES3 API, missing states update.
5420 GLuint service_id = 0;
5421 TextureRef* texture_ref = NULL;
5422 if (client_texture_id) {
5423 texture_ref = GetTexture(client_texture_id);
5424 if (!texture_ref) {
5425 LOCAL_SET_GL_ERROR(
5426 GL_INVALID_OPERATION,
5427 "glFramebufferTextureLayer", "unknown texture_ref");
5428 return;
5429 }
5430 service_id = texture_ref->service_id();
5431 }
5432 glFramebufferTextureLayer(target, attachment, service_id, level, layer);
5433}
5434
[email protected]36cef8ce2010-03-16 07:34:455435void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
5436 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:065437 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5438 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515439 LOCAL_SET_GL_ERROR(
5440 GL_INVALID_OPERATION,
[email protected]caa13ed2014-02-17 11:29:205441 "glGetFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455442 return;
5443 }
[email protected]74c1ec42010-08-12 01:55:575444 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
[email protected]62e65f02013-05-29 22:28:105445 const Framebuffer::Attachment* attachment_object =
5446 framebuffer->GetAttachment(attachment);
5447 *params = attachment_object ? attachment_object->object_name() : 0;
5448 } else {
[email protected]7d3c36e2013-07-12 14:13:165449 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT &&
5450 features().use_img_for_multisampled_render_to_texture) {
5451 pname = GL_TEXTURE_SAMPLES_IMG;
5452 }
[email protected]62e65f02013-05-29 22:28:105453 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:575454 }
[email protected]36cef8ce2010-03-16 07:34:455455}
5456
5457void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
5458 GLenum target, GLenum pname, GLint* params) {
[email protected]ed9f9cd2013-02-27 21:12:355459 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205460 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5461 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515462 LOCAL_SET_GL_ERROR(
5463 GL_INVALID_OPERATION,
5464 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455465 return;
5466 }
[email protected]8875a5f2014-06-27 08:33:475467
5468 EnsureRenderbufferBound();
[email protected]3a03a8f2011-03-19 00:51:275469 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:435470 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5471 *params = renderbuffer->internal_format();
5472 break;
5473 case GL_RENDERBUFFER_WIDTH:
5474 *params = renderbuffer->width();
5475 break;
5476 case GL_RENDERBUFFER_HEIGHT:
5477 *params = renderbuffer->height();
5478 break;
[email protected]7d3c36e2013-07-12 14:13:165479 case GL_RENDERBUFFER_SAMPLES_EXT:
5480 if (features().use_img_for_multisampled_render_to_texture) {
5481 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG,
5482 params);
5483 } else {
5484 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT,
5485 params);
5486 }
[email protected]ad84a3a2012-06-08 21:42:435487 default:
5488 glGetRenderbufferParameterivEXT(target, pname, params);
5489 break;
[email protected]b71f52c2010-06-18 22:20:205490 }
[email protected]36cef8ce2010-03-16 07:34:455491}
5492
[email protected]49cabed2013-11-13 18:15:185493void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:305494 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
5495 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5496 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:445497 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]0c16343f2013-03-08 20:40:165498
[email protected]49cabed2013-11-13 18:15:185499 if (!CheckBoundFramebuffersValid("glBlitFramebufferCHROMIUM")) {
[email protected]0c16343f2013-03-08 20:40:165500 return;
5501 }
5502
[email protected]454157e2014-05-03 02:49:455503 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
boliu2e7d8a7a2014-10-16 20:35:205504 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]f42f05b2013-11-15 21:46:185505 BlitFramebufferHelper(
5506 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]454157e2014-05-03 02:49:455507 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST,
5508 state_.enable_flags.scissor_test);
[email protected]f42f05b2013-11-15 21:46:185509}
5510
[email protected]8875a5f2014-06-27 08:33:475511void GLES2DecoderImpl::EnsureRenderbufferBound() {
5512 if (!state_.bound_renderbuffer_valid) {
5513 state_.bound_renderbuffer_valid = true;
5514 glBindRenderbufferEXT(GL_RENDERBUFFER,
5515 state_.bound_renderbuffer.get()
5516 ? state_.bound_renderbuffer->service_id()
5517 : 0);
5518 }
5519}
5520
[email protected]f42f05b2013-11-15 21:46:185521void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(
5522 const FeatureInfo* feature_info,
5523 GLenum target,
5524 GLsizei samples,
5525 GLenum internal_format,
5526 GLsizei width,
5527 GLsizei height) {
5528 // TODO(sievers): This could be resolved at the GL binding level, but the
5529 // binding process is currently a bit too 'brute force'.
zmo68fcdc62014-12-05 21:51:495530 if (feature_info->gl_version_info().is_angle) {
[email protected]f42f05b2013-11-15 21:46:185531 glRenderbufferStorageMultisampleANGLE(
5532 target, samples, internal_format, width, height);
5533 } else if (feature_info->feature_flags().use_core_framebuffer_multisample) {
5534 glRenderbufferStorageMultisample(
5535 target, samples, internal_format, width, height);
5536 } else {
5537 glRenderbufferStorageMultisampleEXT(
5538 target, samples, internal_format, width, height);
5539 }
5540}
5541
5542void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0,
5543 GLint srcY0,
5544 GLint srcX1,
5545 GLint srcY1,
5546 GLint dstX0,
5547 GLint dstY0,
5548 GLint dstX1,
5549 GLint dstY1,
5550 GLbitfield mask,
5551 GLenum filter) {
5552 // TODO(sievers): This could be resolved at the GL binding level, but the
5553 // binding process is currently a bit too 'brute force'.
zmo68fcdc62014-12-05 21:51:495554 if (feature_info_->gl_version_info().is_angle) {
[email protected]5094b0f2010-11-09 19:45:245555 glBlitFramebufferANGLE(
5556 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]f42f05b2013-11-15 21:46:185557 } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) {
5558 glBlitFramebuffer(
5559 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]5094b0f2010-11-09 19:45:245560 } else {
5561 glBlitFramebufferEXT(
5562 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5563 }
[email protected]8e3e0662010-08-23 18:46:305564}
5565
[email protected]49cabed2013-11-13 18:15:185566bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample(
5567 GLsizei samples,
5568 GLenum internalformat,
5569 GLsizei width,
5570 GLsizei height) {
[email protected]84afefa2011-10-19 21:45:535571 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:515572 LOCAL_SET_GL_ERROR(
5573 GL_INVALID_VALUE,
5574 "glRenderbufferStorageMultisample", "samples too large");
[email protected]49cabed2013-11-13 18:15:185575 return false;
[email protected]84afefa2011-10-19 21:45:535576 }
5577
5578 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5579 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515580 LOCAL_SET_GL_ERROR(
5581 GL_INVALID_VALUE,
5582 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185583 return false;
[email protected]84afefa2011-10-19 21:45:535584 }
5585
[email protected]7989c9e2013-01-23 06:39:265586 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235587 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5588 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515589 LOCAL_SET_GL_ERROR(
5590 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205591 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185592 return false;
[email protected]8e3e0662010-08-23 18:46:305593 }
5594
[email protected]7989c9e2013-01-23 06:39:265595 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515596 LOCAL_SET_GL_ERROR(
5597 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205598 "glRenderbufferStorageMultisample", "out of memory");
[email protected]49cabed2013-11-13 18:15:185599 return false;
5600 }
5601
5602 return true;
5603}
5604
5605void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM(
5606 GLenum target, GLsizei samples, GLenum internalformat,
5607 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185608 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5609 if (!renderbuffer) {
5610 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5611 "glRenderbufferStorageMultisampleCHROMIUM",
5612 "no renderbuffer bound");
5613 return;
5614 }
5615
5616 if (!ValidateRenderbufferStorageMultisample(
5617 samples, internalformat, width, height)) {
[email protected]7989c9e2013-01-23 06:39:265618 return;
5619 }
5620
[email protected]8875a5f2014-06-27 08:33:475621 EnsureRenderbufferBound();
[email protected]8e102e102013-09-20 22:50:235622 GLenum impl_format =
5623 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5624 internalformat);
[email protected]49cabed2013-11-13 18:15:185625 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(
5626 "glRenderbufferStorageMultisampleCHROMIUM");
[email protected]f42f05b2013-11-15 21:46:185627 RenderbufferStorageMultisampleHelper(
Daniel Cheng3d7ce9f2014-08-26 00:26:255628 feature_info_.get(), target, samples, impl_format, width, height);
[email protected]49cabed2013-11-13 18:15:185629 GLenum error =
5630 LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM");
[email protected]9edc6b22010-12-23 02:00:265631 if (error == GL_NO_ERROR) {
[email protected]4a4c18b2013-09-13 22:50:105632
5633 if (workarounds().validate_multisample_buffer_allocation) {
5634 if (!VerifyMultisampleRenderbufferIntegrity(
5635 renderbuffer->service_id(), impl_format)) {
5636 LOCAL_SET_GL_ERROR(
5637 GL_OUT_OF_MEMORY,
[email protected]49cabed2013-11-13 18:15:185638 "glRenderbufferStorageMultisampleCHROMIUM", "out of memory");
[email protected]4a4c18b2013-09-13 22:50:105639 return;
5640 }
5641 }
5642
[email protected]968351b2011-12-20 08:26:515643 // TODO(gman): If renderbuffers tracked which framebuffers they were
5644 // attached to we could just mark those framebuffers as not complete.
5645 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205646 renderbuffer_manager()->SetInfo(
5647 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265648 }
[email protected]8e3e0662010-08-23 18:46:305649}
5650
[email protected]49cabed2013-11-13 18:15:185651// This is the handler for multisampled_render_to_texture extensions.
5652void GLES2DecoderImpl::DoRenderbufferStorageMultisampleEXT(
5653 GLenum target, GLsizei samples, GLenum internalformat,
5654 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185655 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5656 if (!renderbuffer) {
5657 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5658 "glRenderbufferStorageMultisampleEXT",
5659 "no renderbuffer bound");
5660 return;
5661 }
5662
5663 if (!ValidateRenderbufferStorageMultisample(
5664 samples, internalformat, width, height)) {
5665 return;
5666 }
5667
[email protected]8875a5f2014-06-27 08:33:475668 EnsureRenderbufferBound();
[email protected]49cabed2013-11-13 18:15:185669 GLenum impl_format =
5670 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5671 internalformat);
5672 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT");
5673 if (features().use_img_for_multisampled_render_to_texture) {
5674 glRenderbufferStorageMultisampleIMG(
5675 target, samples, impl_format, width, height);
5676 } else {
5677 glRenderbufferStorageMultisampleEXT(
5678 target, samples, impl_format, width, height);
5679 }
5680 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT");
5681 if (error == GL_NO_ERROR) {
5682 // TODO(gman): If renderbuffers tracked which framebuffers they were
5683 // attached to we could just mark those framebuffers as not complete.
5684 framebuffer_manager()->IncFramebufferStateChangeCount();
5685 renderbuffer_manager()->SetInfo(
5686 renderbuffer, samples, internalformat, width, height);
5687 }
5688}
5689
[email protected]4a4c18b2013-09-13 22:50:105690// This function validates the allocation of a multisampled renderbuffer
5691// by clearing it to a key color, blitting the contents to a texture, and
5692// reading back the color to ensure it matches the key.
5693bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity(
5694 GLuint renderbuffer, GLenum format) {
5695
5696 // Only validate color buffers.
5697 // These formats have been selected because they are very common or are known
5698 // to be used by the WebGL backbuffer. If problems are observed with other
5699 // color formats they can be added here.
5700 switch(format) {
5701 case GL_RGB:
5702 case GL_RGB8:
5703 case GL_RGBA:
5704 case GL_RGBA8:
5705 break;
5706 default:
5707 return true;
5708 }
5709
5710 GLint draw_framebuffer, read_framebuffer;
5711
5712 // Cache framebuffer and texture bindings.
5713 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer);
5714 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer);
5715
5716 if (!validation_texture_) {
5717 GLint bound_texture;
5718 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
5719
5720 // Create additional resources needed for the verification.
5721 glGenTextures(1, &validation_texture_);
5722 glGenFramebuffersEXT(1, &validation_fbo_multisample_);
5723 glGenFramebuffersEXT(1, &validation_fbo_);
5724
5725 // Texture only needs to be 1x1.
5726 glBindTexture(GL_TEXTURE_2D, validation_texture_);
5727 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB,
5728 GL_UNSIGNED_BYTE, NULL);
5729
5730 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5731 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5732 GL_TEXTURE_2D, validation_texture_, 0);
5733
5734 glBindTexture(GL_TEXTURE_2D, bound_texture);
5735 }
5736
5737 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5738 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5739 GL_RENDERBUFFER, renderbuffer);
5740
5741 // Cache current state and reset it to the values we require.
5742 GLboolean scissor_enabled = false;
5743 glGetBooleanv(GL_SCISSOR_TEST, &scissor_enabled);
5744 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455745 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]4a4c18b2013-09-13 22:50:105746
[email protected]454157e2014-05-03 02:49:455747 GLboolean color_mask[4] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
[email protected]4a4c18b2013-09-13 22:50:105748 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask);
[email protected]454157e2014-05-03 02:49:455749 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]4a4c18b2013-09-13 22:50:105750
5751 GLfloat clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5752 glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color);
5753 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
5754
5755 // Clear the buffer to the desired key color.
5756 glClear(GL_COLOR_BUFFER_BIT);
5757
5758 // Blit from the multisample buffer to a standard texture.
5759 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, validation_fbo_multisample_);
5760 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, validation_fbo_);
5761
[email protected]f42f05b2013-11-15 21:46:185762 BlitFramebufferHelper(
5763 0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
[email protected]4a4c18b2013-09-13 22:50:105764
5765 // Read a pixel from the buffer.
5766 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5767
5768 unsigned char pixel[3] = {0, 0, 0};
5769 glReadPixels(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);
5770
5771 // Detach the renderbuffer.
5772 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5773 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5774 GL_RENDERBUFFER, 0);
5775
5776 // Restore cached state.
5777 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455778 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]4a4c18b2013-09-13 22:50:105779
[email protected]454157e2014-05-03 02:49:455780 state_.SetDeviceColorMask(
5781 color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
[email protected]4a4c18b2013-09-13 22:50:105782 glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
5783 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, draw_framebuffer);
5784 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, read_framebuffer);
5785
5786 // Return true if the pixel matched the desired key color.
5787 return (pixel[0] == 0xFF &&
5788 pixel[1] == 0x00 &&
5789 pixel[2] == 0xFF);
5790}
5791
[email protected]36cef8ce2010-03-16 07:34:455792void GLES2DecoderImpl::DoRenderbufferStorage(
5793 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:355794 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205795 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5796 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515797 LOCAL_SET_GL_ERROR(
5798 GL_INVALID_OPERATION,
5799 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455800 return;
5801 }
[email protected]876f6fee2010-08-02 23:10:325802
[email protected]84afefa2011-10-19 21:45:535803 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5804 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515805 LOCAL_SET_GL_ERROR(
5806 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535807 return;
5808 }
5809
[email protected]7989c9e2013-01-23 06:39:265810 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235811 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5812 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515813 LOCAL_SET_GL_ERROR(
5814 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265815 return;
5816 }
5817
5818 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515819 LOCAL_SET_GL_ERROR(
5820 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265821 return;
[email protected]b71f52c2010-06-18 22:20:205822 }
[email protected]876f6fee2010-08-02 23:10:325823
[email protected]8875a5f2014-06-27 08:33:475824 EnsureRenderbufferBound();
[email protected]ab09b612013-03-11 22:11:515825 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:265826 glRenderbufferStorageEXT(
[email protected]8e102e102013-09-20 22:50:235827 target,
5828 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5829 internalformat),
5830 width,
5831 height);
[email protected]ab09b612013-03-11 22:11:515832 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:265833 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515834 // TODO(gman): If tetxures tracked which framebuffers they were attached to
5835 // we could just mark those framebuffers as not complete.
5836 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205837 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:265838 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265839 }
[email protected]36cef8ce2010-03-16 07:34:455840}
5841
[email protected]df37b9932013-03-08 05:21:425842void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:385843 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:425844 Program* program = GetProgramInfoNotShader(
5845 program_id, "glLinkProgram");
5846 if (!program) {
[email protected]a93bb842010-02-16 23:03:475847 return;
5848 }
[email protected]05afda12011-01-20 00:17:345849
[email protected]df37b9932013-03-08 05:21:425850 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]65dfc602012-07-23 20:39:395851 ShaderTranslator* vertex_translator = NULL;
5852 ShaderTranslator* fragment_translator = NULL;
5853 if (use_shader_translator_) {
[email protected]7cd76fd2013-06-02 21:11:115854 vertex_translator = vertex_translator_.get();
5855 fragment_translator = fragment_translator_.get();
[email protected]65dfc602012-07-23 20:39:395856 }
[email protected]df37b9932013-03-08 05:21:425857 if (program->Link(shader_manager(),
[email protected]7cd76fd2013-06-02 21:11:115858 vertex_translator,
5859 fragment_translator,
[email protected]008401532014-02-07 00:10:505860 workarounds().count_all_in_varyings_packing ?
5861 Program::kCountAll : Program::kCountOnlyStaticallyUsed,
[email protected]7cd76fd2013-06-02 21:11:115862 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:425863 if (program == state_.current_program.get()) {
[email protected]b05955552014-02-06 18:41:185864 if (workarounds().use_current_program_after_successful_link)
[email protected]df37b9932013-03-08 05:21:425865 glUseProgram(program->service_id());
[email protected]b05955552014-02-06 18:41:185866 if (workarounds().clear_uniforms_before_first_program_use)
5867 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:545868 }
5869 }
vmiura8266ca72014-09-09 21:37:005870
5871 // LinkProgram can be very slow. Exit command processing to allow for
5872 // context preemption and GPU watchdog checks.
5873 ExitCommandProcessingEarly();
[email protected]07f54fcc2009-12-22 02:46:305874};
5875
zmobcb3fdd62014-12-11 00:49:035876void GLES2DecoderImpl::DoSamplerParameterfv(
5877 GLuint sampler, GLenum pname, const GLfloat* params) {
5878 DCHECK(params);
5879 glSamplerParameterf(sampler, pname, params[0]);
5880}
5881
5882void GLES2DecoderImpl::DoSamplerParameteriv(
5883 GLuint sampler, GLenum pname, const GLint* params) {
5884 DCHECK(params);
5885 glSamplerParameteri(sampler, pname, params[0]);
5886}
5887
[email protected]3916c97e2010-02-25 03:20:505888void GLES2DecoderImpl::DoTexParameterf(
5889 GLenum target, GLenum pname, GLfloat param) {
[email protected]c986af502013-08-14 01:04:445890 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5891 &state_, target);
[email protected]02965c22013-03-09 02:40:075892 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515893 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245894 return;
[email protected]07f54fcc2009-12-22 02:46:305895 }
[email protected]cbb22e42011-05-12 23:36:245896
[email protected]737191ee72014-03-09 08:02:425897 texture_manager()->SetParameterf(
5898 "glTexParameterf", GetErrorState(), texture, pname, param);
[email protected]07f54fcc2009-12-22 02:46:305899}
5900
[email protected]3916c97e2010-02-25 03:20:505901void GLES2DecoderImpl::DoTexParameteri(
5902 GLenum target, GLenum pname, GLint param) {
[email protected]c986af502013-08-14 01:04:445903 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5904 &state_, target);
[email protected]02965c22013-03-09 02:40:075905 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515906 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245907 return;
[email protected]3916c97e2010-02-25 03:20:505908 }
[email protected]cbb22e42011-05-12 23:36:245909
[email protected]737191ee72014-03-09 08:02:425910 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505911 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:505912}
5913
5914void GLES2DecoderImpl::DoTexParameterfv(
5915 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]c986af502013-08-14 01:04:445916 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5917 &state_, target);
[email protected]02965c22013-03-09 02:40:075918 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515919 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245920 return;
[email protected]3916c97e2010-02-25 03:20:505921 }
[email protected]cbb22e42011-05-12 23:36:245922
[email protected]737191ee72014-03-09 08:02:425923 texture_manager()->SetParameterf(
5924 "glTexParameterfv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505925}
5926
5927void GLES2DecoderImpl::DoTexParameteriv(
5928 GLenum target, GLenum pname, const GLint* params) {
[email protected]c986af502013-08-14 01:04:445929 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5930 &state_, target);
[email protected]02965c22013-03-09 02:40:075931 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515932 LOCAL_SET_GL_ERROR(
5933 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245934 return;
[email protected]3916c97e2010-02-25 03:20:505935 }
[email protected]cbb22e42011-05-12 23:36:245936
[email protected]737191ee72014-03-09 08:02:425937 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505938 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505939}
5940
orglofchcad5a6742014-11-07 19:51:125941bool GLES2DecoderImpl::CheckCurrentValuebuffer(const char* function_name) {
5942 if (!state_.bound_valuebuffer.get()) {
5943 // There is no valuebuffer bound
5944 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
5945 "no valuebuffer in use");
5946 return false;
5947 }
5948 return true;
5949}
5950
5951bool GLES2DecoderImpl::CheckCurrentValuebufferForSubscription(
5952 GLenum subscription,
5953 const char* function_name) {
5954 if (!CheckCurrentValuebuffer(function_name)) {
5955 return false;
5956 }
5957 if (!state_.bound_valuebuffer.get()->IsSubscribed(subscription)) {
5958 // The valuebuffer is not subscribed to the target
5959 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
5960 "valuebuffer is not subscribed");
5961 return false;
5962 }
5963 return true;
5964}
5965
5966bool GLES2DecoderImpl::CheckSubscriptionTarget(GLint location,
5967 GLenum subscription,
5968 const char* function_name) {
5969 if (!CheckCurrentProgramForUniform(location, function_name)) {
5970 return false;
5971 }
5972 GLint real_location = -1;
5973 GLint array_index = -1;
5974 const Program::UniformInfo* info =
5975 state_.current_program->GetUniformInfoByFakeLocation(
5976 location, &real_location, &array_index);
5977 if (!info) {
5978 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "unknown location");
5979 return false;
5980 }
5981 if ((ValuebufferManager::ApiTypeForSubscriptionTarget(subscription) &
5982 info->accepts_api_type) == 0) {
5983 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
5984 "wrong type for subscription");
5985 return false;
5986 }
5987 return true;
5988}
5989
[email protected]939e7362010-05-13 20:49:105990bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]7cd76fd2013-06-02 21:11:115991 if (!state_.current_program.get()) {
[email protected]ad84a3a2012-06-08 21:42:435992 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:515993 LOCAL_SET_GL_ERROR(
5994 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:435995 return false;
[email protected]939e7362010-05-13 20:49:105996 }
[email protected]e259eb412012-10-13 05:47:245997 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:515998 LOCAL_SET_GL_ERROR(
5999 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:106000 return false;
6001 }
6002 return true;
6003}
6004
6005bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
6006 GLint location, const char* function_name) {
6007 if (!CheckCurrentProgram(function_name)) {
6008 return false;
6009 }
6010 return location != -1;
6011}
6012
zmof9a81360f2014-10-17 00:06:146013bool GLES2DecoderImpl::CheckDrawingFeedbackLoops() {
6014 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
6015 if (!framebuffer)
6016 return false;
6017 const Framebuffer::Attachment* attachment =
6018 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
6019 if (!attachment)
6020 return false;
6021
6022 DCHECK(state_.current_program.get());
6023 const Program::SamplerIndices& sampler_indices =
6024 state_.current_program->sampler_indices();
6025 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
6026 const Program::UniformInfo* uniform_info =
6027 state_.current_program->GetUniformInfo(sampler_indices[ii]);
6028 DCHECK(uniform_info);
6029 if (uniform_info->type != GL_SAMPLER_2D)
6030 continue;
6031 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6032 GLuint texture_unit_index = uniform_info->texture_units[jj];
6033 if (texture_unit_index >= state_.texture_units.size())
6034 continue;
6035 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
6036 TextureRef* texture_ref =
6037 texture_unit.GetInfoForSamplerType(GL_SAMPLER_2D).get();
6038 if (attachment->IsTexture(texture_ref))
6039 return true;
6040 }
6041 }
6042 return false;
6043}
6044
orglofchcad5a6742014-11-07 19:51:126045bool GLES2DecoderImpl::CheckUniformForApiType(
6046 const Program::UniformInfo* info,
6047 const char* function_name,
6048 Program::UniformApiType api_type) {
6049 DCHECK(info);
6050 if ((api_type & info->accepts_api_type) == 0) {
6051 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6052 "wrong uniform function for type");
6053 return false;
6054 }
6055 return true;
6056}
6057
[email protected]43c2f1f2011-03-25 18:35:366058bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]9b1f1b52014-03-12 10:40:136059 GLint fake_location,
6060 const char* function_name,
6061 Program::UniformApiType api_type,
6062 GLint* real_location,
6063 GLenum* type,
6064 GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:366065 DCHECK(type);
6066 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:126067 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:526068
[email protected]1b0a6752012-02-22 03:44:126069 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:106070 return false;
6071 }
[email protected]43c2f1f2011-03-25 18:35:366072 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:356073 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:246074 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:126075 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:366076 if (!info) {
[email protected]ab09b612013-03-11 22:11:516077 LOCAL_SET_GL_ERROR(
6078 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:106079 return false;
6080 }
orglofchcad5a6742014-11-07 19:51:126081 if (!CheckUniformForApiType(info, function_name, api_type)) {
[email protected]476ccb72012-12-06 15:52:526082 return false;
6083 }
[email protected]43c2f1f2011-03-25 18:35:366084 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:516085 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436086 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:366087 return false;
6088 }
6089 *count = std::min(info->size - array_index, *count);
6090 if (*count <= 0) {
6091 return false;
6092 }
6093 *type = info->type;
[email protected]939e7362010-05-13 20:49:106094 return true;
6095}
6096
[email protected]1b0a6752012-02-22 03:44:126097void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
6098 GLenum type = 0;
6099 GLsizei count = 1;
6100 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136101 if (!PrepForSetUniformByLocation(fake_location,
6102 "glUniform1i",
6103 Program::kUniform1i,
6104 &real_location,
6105 &type,
6106 &count)) {
[email protected]3916c97e2010-02-25 03:20:506107 return;
6108 }
[email protected]e259eb412012-10-13 05:47:246109 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:026110 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:516111 LOCAL_SET_GL_ERROR(
6112 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:466113 return;
6114 }
[email protected]1b0a6752012-02-22 03:44:126115 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:506116}
6117
6118void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:126119 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:366120 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126121 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136122 if (!PrepForSetUniformByLocation(fake_location,
6123 "glUniform1iv",
6124 Program::kUniform1i,
6125 &real_location,
6126 &type,
6127 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366128 return;
6129 }
[email protected]74727112012-06-13 21:18:086130 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
6131 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:246132 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:026133 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:516134 LOCAL_SET_GL_ERROR(
6135 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:466136 return;
6137 }
[email protected]43c2f1f2011-03-25 18:35:366138 }
[email protected]1b0a6752012-02-22 03:44:126139 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:506140}
6141
[email protected]939e7362010-05-13 20:49:106142void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:126143 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366144 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126145 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136146 if (!PrepForSetUniformByLocation(fake_location,
6147 "glUniform1fv",
6148 Program::kUniform1f,
6149 &real_location,
6150 &type,
6151 &count)) {
[email protected]939e7362010-05-13 20:49:106152 return;
6153 }
6154 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:556155 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:106156 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:536157 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106158 }
[email protected]1b0a6752012-02-22 03:44:126159 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106160 } else {
[email protected]1b0a6752012-02-22 03:44:126161 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106162 }
6163}
6164
6165void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:126166 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366167 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126168 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136169 if (!PrepForSetUniformByLocation(fake_location,
6170 "glUniform2fv",
6171 Program::kUniform2f,
6172 &real_location,
6173 &type,
6174 &count)) {
[email protected]939e7362010-05-13 20:49:106175 return;
6176 }
6177 if (type == GL_BOOL_VEC2) {
6178 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:556179 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106180 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536181 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106182 }
[email protected]1b0a6752012-02-22 03:44:126183 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106184 } else {
[email protected]1b0a6752012-02-22 03:44:126185 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106186 }
6187}
6188
6189void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:126190 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366191 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126192 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136193 if (!PrepForSetUniformByLocation(fake_location,
6194 "glUniform3fv",
6195 Program::kUniform3f,
6196 &real_location,
6197 &type,
6198 &count)) {
[email protected]939e7362010-05-13 20:49:106199 return;
6200 }
6201 if (type == GL_BOOL_VEC3) {
6202 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:556203 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106204 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536205 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106206 }
[email protected]1b0a6752012-02-22 03:44:126207 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106208 } else {
[email protected]1b0a6752012-02-22 03:44:126209 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106210 }
6211}
6212
6213void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:126214 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366215 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126216 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136217 if (!PrepForSetUniformByLocation(fake_location,
6218 "glUniform4fv",
6219 Program::kUniform4f,
6220 &real_location,
6221 &type,
6222 &count)) {
[email protected]939e7362010-05-13 20:49:106223 return;
6224 }
6225 if (type == GL_BOOL_VEC4) {
6226 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:556227 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106228 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536229 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106230 }
[email protected]1b0a6752012-02-22 03:44:126231 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106232 } else {
[email protected]1b0a6752012-02-22 03:44:126233 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106234 }
6235}
6236
[email protected]43c2f1f2011-03-25 18:35:366237void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:126238 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366239 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126240 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136241 if (!PrepForSetUniformByLocation(fake_location,
6242 "glUniform2iv",
6243 Program::kUniform2i,
6244 &real_location,
6245 &type,
6246 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366247 return;
6248 }
[email protected]1b0a6752012-02-22 03:44:126249 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366250}
6251
6252void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:126253 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366254 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126255 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136256 if (!PrepForSetUniformByLocation(fake_location,
6257 "glUniform3iv",
6258 Program::kUniform3i,
6259 &real_location,
6260 &type,
6261 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366262 return;
6263 }
[email protected]1b0a6752012-02-22 03:44:126264 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366265}
6266
6267void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:126268 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366269 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126270 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136271 if (!PrepForSetUniformByLocation(fake_location,
6272 "glUniform4iv",
6273 Program::kUniform4i,
6274 &real_location,
6275 &type,
6276 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366277 return;
6278 }
[email protected]1b0a6752012-02-22 03:44:126279 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366280}
6281
6282void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:126283 GLint fake_location, GLsizei count, GLboolean transpose,
6284 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366285 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126286 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136287 if (!PrepForSetUniformByLocation(fake_location,
6288 "glUniformMatrix2fv",
6289 Program::kUniformMatrix2f,
6290 &real_location,
6291 &type,
6292 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366293 return;
6294 }
[email protected]1b0a6752012-02-22 03:44:126295 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366296}
6297
6298void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:126299 GLint fake_location, GLsizei count, GLboolean transpose,
6300 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366301 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126302 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136303 if (!PrepForSetUniformByLocation(fake_location,
6304 "glUniformMatrix3fv",
6305 Program::kUniformMatrix3f,
6306 &real_location,
6307 &type,
6308 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366309 return;
6310 }
[email protected]1b0a6752012-02-22 03:44:126311 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366312}
6313
6314void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:126315 GLint fake_location, GLsizei count, GLboolean transpose,
6316 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366317 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126318 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136319 if (!PrepForSetUniformByLocation(fake_location,
6320 "glUniformMatrix4fv",
6321 Program::kUniformMatrix4f,
6322 &real_location,
6323 &type,
6324 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366325 return;
6326 }
[email protected]1b0a6752012-02-22 03:44:126327 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366328}
6329
[email protected]df37b9932013-03-08 05:21:426330void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:036331 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:426332 Program* program = NULL;
6333 if (program_id) {
6334 program = GetProgramInfoNotShader(program_id, "glUseProgram");
6335 if (!program) {
[email protected]ae51d192010-04-27 00:48:036336 return;
6337 }
[email protected]df37b9932013-03-08 05:21:426338 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:506339 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:516340 LOCAL_SET_GL_ERROR(
6341 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:506342 return;
6343 }
[email protected]df37b9932013-03-08 05:21:426344 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:506345 }
[email protected]7cd76fd2013-06-02 21:11:116346 if (state_.current_program.get()) {
6347 program_manager()->UnuseProgram(shader_manager(),
6348 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:146349 }
[email protected]df37b9932013-03-08 05:21:426350 state_.current_program = program;
6351 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:546352 glUseProgram(service_id);
[email protected]7cd76fd2013-06-02 21:11:116353 if (state_.current_program.get()) {
6354 program_manager()->UseProgram(state_.current_program.get());
[email protected]b05955552014-02-06 18:41:186355 if (workarounds().clear_uniforms_before_first_program_use)
6356 program_manager()->ClearUniforms(program);
[email protected]ca488e12010-12-13 20:06:146357 }
[email protected]3916c97e2010-02-25 03:20:506358}
6359
[email protected]ab09b612013-03-11 22:11:516360void GLES2DecoderImpl::RenderWarning(
6361 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:326362 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016363}
6364
[email protected]ab09b612013-03-11 22:11:516365void GLES2DecoderImpl::PerformanceWarning(
6366 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:506367 logger_.LogMessage(filename, line,
6368 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016369}
6370
[email protected]91c94eb2013-10-22 10:32:546371void GLES2DecoderImpl::DoWillUseTexImageIfNeeded(
6372 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546373 // Image is already in use if texture is attached to a framebuffer.
6374 if (texture && !texture->IsAttachedToFramebuffer()) {
6375 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6376 if (image) {
6377 ScopedGLErrorSuppressor suppressor(
6378 "GLES2DecoderImpl::DoWillUseTexImageIfNeeded",
6379 GetErrorState());
6380 glBindTexture(textarget, texture->service_id());
6381 image->WillUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026382 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546383 }
6384 }
6385}
6386
6387void GLES2DecoderImpl::DoDidUseTexImageIfNeeded(
6388 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546389 // Image is still in use if texture is attached to a framebuffer.
6390 if (texture && !texture->IsAttachedToFramebuffer()) {
6391 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6392 if (image) {
6393 ScopedGLErrorSuppressor suppressor(
6394 "GLES2DecoderImpl::DoDidUseTexImageIfNeeded",
6395 GetErrorState());
6396 glBindTexture(textarget, texture->service_id());
6397 image->DidUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026398 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546399 }
6400 }
6401}
6402
[email protected]e56131d22013-07-28 16:14:116403bool GLES2DecoderImpl::PrepareTexturesForRender() {
[email protected]7cd76fd2013-06-02 21:11:116404 DCHECK(state_.current_program.get());
[email protected]91c94eb2013-10-22 10:32:546405 if (!texture_manager()->HaveUnrenderableTextures() &&
[email protected]7bffe9e12014-01-27 23:02:556406 !texture_manager()->HaveImages()) {
[email protected]e56131d22013-07-28 16:14:116407 return true;
[email protected]ef526492010-06-02 23:12:256408 }
[email protected]e2367b42013-05-31 03:37:216409
[email protected]ef526492010-06-02 23:12:256410 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:356411 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:246412 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506413 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356414 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246415 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506416 DCHECK(uniform_info);
6417 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6418 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026419 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246420 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]91c94eb2013-10-22 10:32:546421 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366422 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]91c94eb2013-10-22 10:32:546423 GLenum textarget = GetBindTargetForSamplerType(uniform_info->type);
6424 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]ef526492010-06-02 23:12:256425 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:506426 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6427 glBindTexture(
[email protected]91c94eb2013-10-22 10:32:546428 textarget,
[email protected]00f893d2010-08-24 18:55:496429 texture_manager()->black_texture_id(uniform_info->type));
dongseong.hwang7d87d722015-01-14 20:02:406430 if (!texture_ref) {
6431 LOCAL_RENDER_WARNING(
6432 std::string("there is no texture bound to the unit ") +
6433 base::IntToString(texture_unit_index));
6434 } else {
6435 LOCAL_RENDER_WARNING(
6436 std::string("texture bound to texture unit ") +
6437 base::IntToString(texture_unit_index) +
6438 " is not renderable. It maybe non-power-of-2 and have"
6439 " incompatible texture filtering.");
6440 }
[email protected]91c94eb2013-10-22 10:32:546441 continue;
[email protected]3916c97e2010-02-25 03:20:506442 }
[email protected]91c94eb2013-10-22 10:32:546443
[email protected]4e7b89202014-01-28 01:44:066444 if (textarget != GL_TEXTURE_CUBE_MAP) {
6445 Texture* texture = texture_ref->texture();
6446 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6447 if (image && !texture->IsAttachedToFramebuffer()) {
6448 ScopedGLErrorSuppressor suppressor(
6449 "GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState());
6450 textures_set = true;
6451 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6452 image->WillUseTexImage();
6453 continue;
6454 }
[email protected]91c94eb2013-10-22 10:32:546455 }
[email protected]3916c97e2010-02-25 03:20:506456 }
6457 // else: should this be an error?
6458 }
6459 }
[email protected]e56131d22013-07-28 16:14:116460 return !textures_set;
[email protected]3916c97e2010-02-25 03:20:506461}
6462
[email protected]91c94eb2013-10-22 10:32:546463void GLES2DecoderImpl::RestoreStateForTextures() {
[email protected]7cd76fd2013-06-02 21:11:116464 DCHECK(state_.current_program.get());
[email protected]ed9f9cd2013-02-27 21:12:356465 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116466 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506467 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356468 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246469 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506470 DCHECK(uniform_info);
6471 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6472 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026473 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246474 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]7cd76fd2013-06-02 21:11:116475 TextureRef* texture_ref =
[email protected]91c94eb2013-10-22 10:32:546476 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496477 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]3916c97e2010-02-25 03:20:506478 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]370eaf12013-05-18 09:19:496479 // Get the texture_ref info that was previously bound here.
[email protected]7cd76fd2013-06-02 21:11:116480 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D
6481 ? texture_unit.bound_texture_2d.get()
6482 : texture_unit.bound_texture_cube_map.get();
[email protected]3916c97e2010-02-25 03:20:506483 glBindTexture(texture_unit.bind_target,
[email protected]370eaf12013-05-18 09:19:496484 texture_ref ? texture_ref->service_id() : 0);
[email protected]91c94eb2013-10-22 10:32:546485 continue;
6486 }
6487
[email protected]4e7b89202014-01-28 01:44:066488 if (texture_unit.bind_target != GL_TEXTURE_CUBE_MAP) {
6489 Texture* texture = texture_ref->texture();
6490 gfx::GLImage* image =
6491 texture->GetLevelImage(texture_unit.bind_target, 0);
6492 if (image && !texture->IsAttachedToFramebuffer()) {
6493 ScopedGLErrorSuppressor suppressor(
6494 "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState());
6495 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6496 image->DidUseTexImage();
6497 continue;
6498 }
[email protected]3916c97e2010-02-25 03:20:506499 }
6500 }
6501 }
6502 }
6503 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:246504 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:306505}
6506
[email protected]0d6bfdc2011-11-02 01:32:206507bool GLES2DecoderImpl::ClearUnclearedTextures() {
6508 // Only check if there are some uncleared textures.
6509 if (!texture_manager()->HaveUnsafeTextures()) {
6510 return true;
6511 }
6512
6513 // 1: Check all textures we are about to render with.
[email protected]7cd76fd2013-06-02 21:11:116514 if (state_.current_program.get()) {
[email protected]ed9f9cd2013-02-27 21:12:356515 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116516 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:206517 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356518 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246519 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:206520 DCHECK(uniform_info);
6521 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6522 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026523 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246524 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:496525 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366526 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496527 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
6528 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
[email protected]0d6bfdc2011-11-02 01:32:206529 return false;
6530 }
6531 }
6532 }
6533 }
6534 }
6535 }
6536 return true;
6537}
6538
[email protected]c6aef902012-02-14 03:31:426539bool GLES2DecoderImpl::IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:106540 const char* function_name, GLuint max_vertex_accessed, bool instanced,
6541 GLsizei primcount) {
6542 DCHECK(instanced || primcount == 1);
6543
[email protected]689fa1c52010-06-09 18:35:036544 // NOTE: We specifically do not check current_program->IsValid() because
6545 // it could never be invalid since glUseProgram would have failed. While
6546 // glLinkProgram could later mark the program as invalid the previous
6547 // valid program will still function if it is still the current program.
[email protected]7cd76fd2013-06-02 21:11:116548 if (!state_.current_program.get()) {
[email protected]3916c97e2010-02-25 03:20:506549 // The program does not exist.
6550 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:516551 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:506552 return false;
6553 }
[email protected]c6aef902012-02-14 03:31:426554
zmof9a81360f2014-10-17 00:06:146555 if (CheckDrawingFeedbackLoops()) {
6556 LOCAL_SET_GL_ERROR(
6557 GL_INVALID_OPERATION, function_name,
6558 "Source and destination textures of the draw are the same.");
6559 return false;
6560 }
6561
[email protected]7cd76fd2013-06-02 21:11:116562 return state_.vertex_attrib_manager
6563 ->ValidateBindings(function_name,
6564 this,
6565 feature_info_.get(),
6566 state_.current_program.get(),
6567 max_vertex_accessed,
[email protected]ac6904d62014-07-30 12:00:106568 instanced,
[email protected]7cd76fd2013-06-02 21:11:116569 primcount);
[email protected]b1122982010-05-17 23:04:246570}
6571
[email protected]c13e1da62011-09-09 21:48:306572bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:436573 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:306574 DCHECK(simulated);
6575 *simulated = false;
6576
[email protected]876f6fee2010-08-02 23:10:326577 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:306578 return true;
[email protected]876f6fee2010-08-02 23:10:326579
[email protected]ac77603c72013-03-08 13:52:066580 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:356581 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:246582 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:246583 bool attrib_0_used =
6584 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:066585 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:306586 return true;
[email protected]b1122982010-05-17 23:04:246587 }
6588
[email protected]b1122982010-05-17 23:04:246589 // Make a buffer with a single repeated vec4 value enough to
6590 // simulate the constant value that is supposed to be here.
6591 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:306592 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:476593 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:306594
6595 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:476596 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306597 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516598 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306599 return false;
6600 }
6601
[email protected]ab09b612013-03-11 22:11:516602 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016603 "Attribute 0 is disabled. This has signficant performance penalty");
6604
[email protected]ab09b612013-03-11 22:11:516605 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:306606 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
6607
[email protected]8f0b86c2f2012-04-10 05:48:286608 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
6609 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:496610 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306611 GLenum error = glGetError();
6612 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516613 LOCAL_SET_GL_ERROR(
6614 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306615 return false;
6616 }
[email protected]fc753442011-02-04 19:49:496617 }
[email protected]af6380962012-11-29 23:24:136618
6619 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:286620 if (new_buffer ||
6621 (attrib_0_used &&
6622 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:136623 (value.v[0] != attrib_0_value_.v[0] ||
6624 value.v[1] != attrib_0_value_.v[1] ||
6625 value.v[2] != attrib_0_value_.v[2] ||
6626 value.v[3] != attrib_0_value_.v[3])))) {
6627 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:496628 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
6629 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:136630 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:246631 attrib_0_size_ = size_needed;
6632 }
6633
6634 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
6635
[email protected]ac77603c72013-03-08 13:52:066636 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:426637 glVertexAttribDivisorANGLE(0, 0);
6638
[email protected]c13e1da62011-09-09 21:48:306639 *simulated = true;
[email protected]b1122982010-05-17 23:04:246640 return true;
[email protected]b1122982010-05-17 23:04:246641}
6642
[email protected]3fc38e22014-05-30 00:13:236643void GLES2DecoderImpl::RestoreStateForAttrib(
6644 GLuint attrib_index, bool restore_array_binding) {
[email protected]ac77603c72013-03-08 13:52:066645 const VertexAttrib* attrib =
6646 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
[email protected]3fc38e22014-05-30 00:13:236647 if (restore_array_binding) {
6648 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
6649 Buffer* buffer = attrib->buffer();
6650 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
6651 glVertexAttribPointer(
6652 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
6653 attrib->gl_stride(), ptr);
6654 }
[email protected]ac77603c72013-03-08 13:52:066655 if (attrib->divisor())
6656 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:246657 glBindBuffer(
[email protected]3fc38e22014-05-30 00:13:236658 GL_ARRAY_BUFFER, state_.bound_array_buffer.get() ?
6659 state_.bound_array_buffer->service_id() : 0);
[email protected]43410e92012-04-20 17:06:286660
[email protected]265f8992012-07-20 01:03:146661 // Never touch vertex attribute 0's state (in particular, never
6662 // disable it) when running on desktop GL because it will never be
6663 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:066664 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:146665 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:066666 if (attrib->enabled()) {
6667 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146668 } else {
[email protected]ac77603c72013-03-08 13:52:066669 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146670 }
[email protected]43410e92012-04-20 17:06:286671 }
[email protected]b1122982010-05-17 23:04:246672}
[email protected]07f54fcc2009-12-22 02:46:306673
[email protected]8fbedc02010-11-18 18:43:406674bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:436675 const char* function_name,
[email protected]c6aef902012-02-14 03:31:426676 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:406677 DCHECK(simulated);
6678 *simulated = false;
6679 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
6680 return true;
6681
[email protected]e259eb412012-10-13 05:47:246682 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:406683 return true;
6684 }
6685
[email protected]ab09b612013-03-11 22:11:516686 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016687 "GL_FIXED attributes have a signficant performance penalty");
6688
[email protected]8fbedc02010-11-18 18:43:406689 // NOTE: we could be smart and try to check if a buffer is used
6690 // twice in 2 different attribs, find the overlapping parts and therefore
6691 // duplicate the minimum amount of data but this whole code path is not meant
6692 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
6693 // tests so we just add to the buffer attrib used.
6694
[email protected]c13e1da62011-09-09 21:48:306695 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:066696 const VertexAttribManager::VertexAttribList& enabled_attribs =
6697 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
6698 for (VertexAttribManager::VertexAttribList::const_iterator it =
6699 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6700 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356701 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066702 state_.current_program->GetAttribInfoByLocation(attrib->index());
6703 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
6704 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:426705 GLuint num_vertices = max_accessed + 1;
6706 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516707 LOCAL_SET_GL_ERROR(
6708 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426709 return false;
6710 }
[email protected]8fbedc02010-11-18 18:43:406711 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066712 attrib->CanAccess(max_accessed) &&
6713 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:476714 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:066715 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:476716 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:516717 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436718 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406719 return false;
6720 }
6721 }
6722 }
6723
[email protected]3aad1a32012-09-07 20:54:476724 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
6725 uint32 size_needed = 0;
6726 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306727 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516728 LOCAL_SET_GL_ERROR(
6729 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406730 return false;
6731 }
6732
[email protected]ab09b612013-03-11 22:11:516733 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:406734
6735 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:306736 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:406737 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306738 GLenum error = glGetError();
6739 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516740 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436741 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:306742 return false;
6743 }
[email protected]8fbedc02010-11-18 18:43:406744 }
6745
6746 // Copy the elements and convert to float
6747 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:066748 for (VertexAttribManager::VertexAttribList::const_iterator it =
6749 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6750 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356751 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066752 state_.current_program->GetAttribInfoByLocation(attrib->index());
6753 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:426754 max_vertex_accessed);
6755 GLuint num_vertices = max_accessed + 1;
6756 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516757 LOCAL_SET_GL_ERROR(
6758 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426759 return false;
6760 }
[email protected]8fbedc02010-11-18 18:43:406761 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066762 attrib->CanAccess(max_accessed) &&
6763 attrib->type() == GL_FIXED) {
penghuang5a3210b2014-10-29 18:24:366764 int num_elements = attrib->size() * num_vertices;
6765 const int src_size = num_elements * sizeof(int32);
6766 const int dst_size = num_elements * sizeof(float);
6767 scoped_ptr<float[]> data(new float[num_elements]);
[email protected]8fbedc02010-11-18 18:43:406768 const int32* src = reinterpret_cast<const int32 *>(
penghuang5a3210b2014-10-29 18:24:366769 attrib->buffer()->GetRange(attrib->offset(), src_size));
[email protected]8fbedc02010-11-18 18:43:406770 const int32* end = src + num_elements;
6771 float* dst = data.get();
6772 while (src != end) {
6773 *dst++ = static_cast<float>(*src++) / 65536.0f;
6774 }
penghuang5a3210b2014-10-29 18:24:366775 glBufferSubData(GL_ARRAY_BUFFER, offset, dst_size, data.get());
[email protected]8fbedc02010-11-18 18:43:406776 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066777 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:406778 reinterpret_cast<GLvoid*>(offset));
penghuang5a3210b2014-10-29 18:24:366779 offset += dst_size;
[email protected]8fbedc02010-11-18 18:43:406780 }
6781 }
6782 *simulated = true;
6783 return true;
6784}
6785
6786void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
6787 // There's no need to call glVertexAttribPointer because we shadow all the
6788 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:246789 glBindBuffer(
6790 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:116791 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
6792 : 0);
[email protected]8fbedc02010-11-18 18:43:406793}
6794
[email protected]ad84a3a2012-06-08 21:42:436795error::Error GLES2DecoderImpl::DoDrawArrays(
6796 const char* function_name,
6797 bool instanced,
6798 GLenum mode,
6799 GLint first,
6800 GLsizei count,
6801 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226802 error::Error error = WillAccessBoundFramebufferForDraw();
6803 if (error != error::kNoError)
6804 return error;
[email protected]38d139d2011-07-14 00:38:436805 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516806 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:436807 return error::kNoError;
6808 }
6809 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516810 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:436811 return error::kNoError;
6812 }
[email protected]c6aef902012-02-14 03:31:426813 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516814 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426815 return error::kNoError;
6816 }
[email protected]ad84a3a2012-06-08 21:42:436817 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:436818 return error::kNoError;
6819 }
6820 // We have to check this here because the prototype for glDrawArrays
6821 // is GLint not GLsizei.
6822 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:516823 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:436824 return error::kNoError;
6825 }
6826
[email protected]ac6904d62014-07-30 12:00:106827 if (count == 0 || primcount == 0) {
[email protected]ab09b612013-03-11 22:11:516828 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:436829 return error::kNoError;
6830 }
6831
6832 GLuint max_vertex_accessed = first + count - 1;
[email protected]ac6904d62014-07-30 12:00:106833 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206834 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516835 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206836 return error::kNoError;
6837 }
[email protected]c13e1da62011-09-09 21:48:306838 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436839 if (!SimulateAttrib0(
6840 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306841 return error::kNoError;
6842 }
[email protected]38d139d2011-07-14 00:38:436843 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436844 if (SimulateFixedAttribs(
6845 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6846 primcount)) {
[email protected]e56131d22013-07-28 16:14:116847 bool textures_set = !PrepareTexturesForRender();
[email protected]38d139d2011-07-14 00:38:436848 ApplyDirtyState();
[email protected]00c2cf92014-03-14 00:08:376849 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:426850 if (!instanced) {
6851 glDrawArrays(mode, first, count);
6852 } else {
6853 glDrawArraysInstancedANGLE(mode, first, count, primcount);
6854 }
[email protected]38d139d2011-07-14 00:38:436855 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546856 RestoreStateForTextures();
[email protected]38d139d2011-07-14 00:38:436857 }
6858 if (simulated_fixed_attribs) {
6859 RestoreStateForSimulatedFixedAttribs();
6860 }
6861 }
6862 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:236863 // We don't have to restore attrib 0 generic data at the end of this
6864 // function even if it is simulated. This is because we will simulate
6865 // it in each draw call, and attrib 0 generic data queries use cached
6866 // values instead of passing down to the underlying driver.
6867 RestoreStateForAttrib(0, false);
[email protected]38d139d2011-07-14 00:38:436868 }
[email protected]38d139d2011-07-14 00:38:436869 }
6870 return error::kNoError;
6871}
6872
vmiuracd108592014-09-08 14:36:346873error::Error GLES2DecoderImpl::HandleDrawArrays(uint32 immediate_data_size,
6874 const void* cmd_data) {
6875 const cmds::DrawArrays& c = *static_cast<const cmds::DrawArrays*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:436876 return DoDrawArrays("glDrawArrays",
6877 false,
[email protected]c6aef902012-02-14 03:31:426878 static_cast<GLenum>(c.mode),
6879 static_cast<GLint>(c.first),
6880 static_cast<GLsizei>(c.count),
[email protected]ac6904d62014-07-30 12:00:106881 1);
[email protected]c6aef902012-02-14 03:31:426882}
6883
6884error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
vmiuracd108592014-09-08 14:36:346885 uint32 immediate_data_size,
6886 const void* cmd_data) {
6887 const gles2::cmds::DrawArraysInstancedANGLE& c =
6888 *static_cast<const gles2::cmds::DrawArraysInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:156889 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516890 LOCAL_SET_GL_ERROR(
6891 GL_INVALID_OPERATION,
6892 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426893 return error::kNoError;
6894 }
[email protected]ad84a3a2012-06-08 21:42:436895 return DoDrawArrays("glDrawArraysIntancedANGLE",
6896 true,
[email protected]c6aef902012-02-14 03:31:426897 static_cast<GLenum>(c.mode),
6898 static_cast<GLint>(c.first),
6899 static_cast<GLsizei>(c.count),
6900 static_cast<GLsizei>(c.primcount));
6901}
6902
[email protected]ad84a3a2012-06-08 21:42:436903error::Error GLES2DecoderImpl::DoDrawElements(
6904 const char* function_name,
6905 bool instanced,
6906 GLenum mode,
6907 GLsizei count,
6908 GLenum type,
6909 int32 offset,
6910 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226911 error::Error error = WillAccessBoundFramebufferForDraw();
6912 if (error != error::kNoError)
6913 return error;
[email protected]e259eb412012-10-13 05:47:246914 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:516915 LOCAL_SET_GL_ERROR(
6916 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296917 return error::kNoError;
6918 }
6919
[email protected]8eee29c2010-04-29 03:38:296920 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516921 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296922 return error::kNoError;
6923 }
6924 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516925 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296926 return error::kNoError;
6927 }
[email protected]9438b012010-06-15 22:55:056928 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516929 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296930 return error::kNoError;
6931 }
[email protected]9438b012010-06-15 22:55:056932 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516933 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296934 return error::kNoError;
6935 }
[email protected]c6aef902012-02-14 03:31:426936 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516937 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426938 return error::kNoError;
6939 }
[email protected]8eee29c2010-04-29 03:38:296940
[email protected]ad84a3a2012-06-08 21:42:436941 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276942 return error::kNoError;
6943 }
6944
[email protected]ac6904d62014-07-30 12:00:106945 if (count == 0 || primcount == 0) {
[email protected]6c788fb72010-08-26 02:16:316946 return error::kNoError;
6947 }
6948
[email protected]8eee29c2010-04-29 03:38:296949 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:086950 Buffer* element_array_buffer =
6951 state_.vertex_attrib_manager->element_array_buffer();
6952
6953 if (!element_array_buffer->GetMaxValueForRange(
6954 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:516955 LOCAL_SET_GL_ERROR(
6956 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296957 return error::kNoError;
6958 }
6959
[email protected]ac6904d62014-07-30 12:00:106960 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206961 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516962 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206963 return error::kNoError;
6964 }
[email protected]c13e1da62011-09-09 21:48:306965 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436966 if (!SimulateAttrib0(
6967 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306968 return error::kNoError;
6969 }
[email protected]8fbedc02010-11-18 18:43:406970 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436971 if (SimulateFixedAttribs(
6972 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6973 primcount)) {
[email protected]e56131d22013-07-28 16:14:116974 bool textures_set = !PrepareTexturesForRender();
[email protected]297ca1c2011-06-20 23:08:466975 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:086976 // TODO(gman): Refactor to hide these details in BufferManager or
6977 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:406978 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:086979 bool used_client_side_array = false;
6980 if (element_array_buffer->IsClientSideArray()) {
6981 used_client_side_array = true;
6982 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6983 indices = element_array_buffer->GetRange(offset, 0);
6984 }
6985
[email protected]00c2cf92014-03-14 00:08:376986 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:426987 if (!instanced) {
6988 glDrawElements(mode, count, type, indices);
6989 } else {
6990 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6991 }
[email protected]17cfbe0e2013-03-07 01:26:086992
6993 if (used_client_side_array) {
6994 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
6995 element_array_buffer->service_id());
6996 }
6997
[email protected]8fbedc02010-11-18 18:43:406998 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546999 RestoreStateForTextures();
[email protected]8fbedc02010-11-18 18:43:407000 }
7001 if (simulated_fixed_attribs) {
7002 RestoreStateForSimulatedFixedAttribs();
7003 }
[email protected]ba3176a2009-12-16 18:19:467004 }
[email protected]b1122982010-05-17 23:04:247005 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:237006 // We don't have to restore attrib 0 generic data at the end of this
7007 // function even if it is simulated. This is because we will simulate
7008 // it in each draw call, and attrib 0 generic data queries use cached
7009 // values instead of passing down to the underlying driver.
7010 RestoreStateForAttrib(0, false);
[email protected]b1122982010-05-17 23:04:247011 }
[email protected]96449d2c2009-11-25 00:01:327012 }
[email protected]f7a64ee2010-02-01 22:24:147013 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327014}
7015
vmiuracd108592014-09-08 14:36:347016error::Error GLES2DecoderImpl::HandleDrawElements(uint32 immediate_data_size,
7017 const void* cmd_data) {
7018 const gles2::cmds::DrawElements& c =
7019 *static_cast<const gles2::cmds::DrawElements*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:437020 return DoDrawElements("glDrawElements",
7021 false,
[email protected]c6aef902012-02-14 03:31:427022 static_cast<GLenum>(c.mode),
7023 static_cast<GLsizei>(c.count),
7024 static_cast<GLenum>(c.type),
7025 static_cast<int32>(c.index_offset),
[email protected]ac6904d62014-07-30 12:00:107026 1);
[email protected]c6aef902012-02-14 03:31:427027}
7028
7029error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
vmiuracd108592014-09-08 14:36:347030 uint32 immediate_data_size,
7031 const void* cmd_data) {
7032 const gles2::cmds::DrawElementsInstancedANGLE& c =
7033 *static_cast<const gles2::cmds::DrawElementsInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:157034 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517035 LOCAL_SET_GL_ERROR(
7036 GL_INVALID_OPERATION,
7037 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:427038 return error::kNoError;
7039 }
[email protected]ad84a3a2012-06-08 21:42:437040 return DoDrawElements("glDrawElementsInstancedANGLE",
7041 true,
[email protected]c6aef902012-02-14 03:31:427042 static_cast<GLenum>(c.mode),
7043 static_cast<GLsizei>(c.count),
7044 static_cast<GLenum>(c.type),
7045 static_cast<int32>(c.index_offset),
7046 static_cast<GLsizei>(c.primcount));
7047}
7048
[email protected]269200b12010-11-18 22:53:067049GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:237050 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
7051 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:077052 Buffer* buffer = GetBuffer(buffer_id);
7053 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:037054 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:517055 LOCAL_SET_GL_ERROR(
7056 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:237057 } else {
[email protected]b10492f2013-03-08 05:24:077058 if (!buffer->GetMaxValueForRange(
7059 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:037060 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:517061 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:067062 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437063 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:237064 }
7065 }
7066 return max_vertex_accessed;
7067}
7068
zmo1bb3d1d2015-01-21 20:29:437069void GLES2DecoderImpl::DoShaderSource(
7070 GLuint client_id, GLsizei count, const char** data, const GLint* length) {
7071 std::string str;
7072 for (GLsizei ii = 0; ii < count; ++ii) {
7073 str.append(data[ii]);
7074 }
[email protected]df37b9932013-03-08 05:21:427075 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
7076 if (!shader) {
zmo1bb3d1d2015-01-21 20:29:437077 return;
[email protected]96449d2c2009-11-25 00:01:327078 }
[email protected]45bf5152010-02-12 00:11:317079 // Note: We don't actually call glShaderSource here. We wait until
7080 // the call to glCompileShader.
zmo576a0492014-09-13 01:12:327081 shader->set_source(str);
[email protected]558847a2010-03-24 07:02:547082}
7083
[email protected]ae51d192010-04-27 00:48:037084void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:387085 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:427086 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
7087 if (!shader) {
[email protected]45bf5152010-02-12 00:11:317088 return;
7089 }
[email protected]f57bb282010-11-12 00:51:347090 ShaderTranslator* translator = NULL;
[email protected]b1d2dcb2010-05-17 19:24:187091 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:427092 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]a550584e2010-09-17 18:01:457093 vertex_translator_.get() : fragment_translator_.get();
[email protected]de17df392010-04-23 21:09:417094 }
[email protected]de17df392010-04-23 21:09:417095
zmo576a0492014-09-13 01:12:327096 shader->DoCompile(
[email protected]b05955552014-02-06 18:41:187097 translator,
7098 feature_info_->feature_flags().angle_translated_shader_source ?
zmo576a0492014-09-13 01:12:327099 Shader::kANGLE : Shader::kGL);
vmiura8266ca72014-09-09 21:37:007100
7101 // CompileShader can be very slow. Exit command processing to allow for
7102 // context preemption and GPU watchdog checks.
7103 ExitCommandProcessingEarly();
7104}
[email protected]45bf5152010-02-12 00:11:317105
[email protected]ddd968b82010-03-02 00:44:297106void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:427107 GLuint shader_id, GLenum pname, GLint* params) {
7108 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
7109 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:297110 return;
7111 }
[email protected]8f1ccdac2010-05-19 21:01:487112 switch (pname) {
7113 case GL_SHADER_SOURCE_LENGTH:
zmo576a0492014-09-13 01:12:327114 *params = shader->source().size();
7115 if (*params)
7116 ++(*params);
[email protected]8f1ccdac2010-05-19 21:01:487117 return;
7118 case GL_COMPILE_STATUS:
zmo576a0492014-09-13 01:12:327119 *params = compile_shader_always_succeeds_ ? true : shader->valid();
[email protected]e5186162010-06-14 18:54:417120 return;
[email protected]8f1ccdac2010-05-19 21:01:487121 case GL_INFO_LOG_LENGTH:
zmo576a0492014-09-13 01:12:327122 *params = shader->log_info().size();
7123 if (*params)
7124 ++(*params);
[email protected]e5186162010-06-14 18:54:417125 return;
[email protected]d6a53e42011-10-05 00:09:367126 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
zmo576a0492014-09-13 01:12:327127 *params = shader->translated_source().size();
7128 if (*params)
7129 ++(*params);
[email protected]d6a53e42011-10-05 00:09:367130 return;
[email protected]8f1ccdac2010-05-19 21:01:487131 default:
7132 break;
[email protected]ddd968b82010-03-02 00:44:297133 }
[email protected]df37b9932013-03-08 05:21:427134 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:297135}
7136
vmiuracd108592014-09-08 14:36:347137error::Error GLES2DecoderImpl::HandleGetShaderSource(uint32 immediate_data_size,
7138 const void* cmd_data) {
7139 const gles2::cmds::GetShaderSource& c =
7140 *static_cast<const gles2::cmds::GetShaderSource*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427141 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:037142 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7143 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427144 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
zmo576a0492014-09-13 01:12:327145 if (!shader || shader->source().empty()) {
[email protected]8eee29c2010-04-29 03:38:297146 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:297147 return error::kNoError;
7148 }
zmo576a0492014-09-13 01:12:327149 bucket->SetFromString(shader->source().c_str());
[email protected]ae51d192010-04-27 00:48:037150 return error::kNoError;
7151}
7152
[email protected]d6a53e42011-10-05 00:09:367153error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
7154 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:347155 const void* cmd_data) {
7156 const gles2::cmds::GetTranslatedShaderSourceANGLE& c =
7157 *static_cast<const gles2::cmds::GetTranslatedShaderSourceANGLE*>(
7158 cmd_data);
[email protected]df37b9932013-03-08 05:21:427159 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:367160 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7161 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427162 Shader* shader = GetShaderInfoNotProgram(
[email protected]caa13ed2014-02-17 11:29:207163 shader_id, "glGetTranslatedShaderSourceANGLE");
[email protected]df37b9932013-03-08 05:21:427164 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:367165 bucket->SetSize(0);
7166 return error::kNoError;
7167 }
7168
zmo576a0492014-09-13 01:12:327169 bucket->SetFromString(shader->translated_source().c_str());
[email protected]d6a53e42011-10-05 00:09:367170 return error::kNoError;
7171}
7172
[email protected]ae51d192010-04-27 00:48:037173error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
vmiuracd108592014-09-08 14:36:347174 uint32 immediate_data_size,
7175 const void* cmd_data) {
7176 const gles2::cmds::GetProgramInfoLog& c =
7177 *static_cast<const gles2::cmds::GetProgramInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427178 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:587179 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7180 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427181 Program* program = GetProgramInfoNotShader(
7182 program_id, "glGetProgramInfoLog");
7183 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:467184 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:037185 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:317186 }
[email protected]df37b9932013-03-08 05:21:427187 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:037188 return error::kNoError;
7189}
7190
7191error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
vmiuracd108592014-09-08 14:36:347192 uint32 immediate_data_size,
7193 const void* cmd_data) {
7194 const gles2::cmds::GetShaderInfoLog& c =
7195 *static_cast<const gles2::cmds::GetShaderInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427196 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:587197 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7198 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427199 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
zmo576a0492014-09-13 01:12:327200 if (!shader) {
[email protected]9a14ae612011-08-08 17:51:467201 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:037202 return error::kNoError;
7203 }
zmo576a0492014-09-13 01:12:327204 bucket->SetFromString(shader->log_info().c_str());
[email protected]ae51d192010-04-27 00:48:037205 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327206}
7207
[email protected]d058bca2012-11-26 10:27:267208bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
7209 return state_.GetEnabled(cap);
7210}
7211
[email protected]1958e0e2010-04-22 05:17:157212bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:217213 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107214 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157215}
7216
7217bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:357218 const Framebuffer* framebuffer =
7219 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107220 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157221}
7222
7223bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:367224 // IsProgram is true for programs as soon as they are created, until they are
7225 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:357226 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:107227 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157228}
7229
7230bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:357231 const Renderbuffer* renderbuffer =
7232 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107233 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157234}
7235
7236bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:367237 // IsShader is true for shaders as soon as they are created, until they
7238 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:357239 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:107240 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157241}
7242
7243bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:497244 const TextureRef* texture_ref = GetTexture(client_id);
7245 return texture_ref && texture_ref->texture()->IsValid();
[email protected]ae51d192010-04-27 00:48:037246}
7247
7248void GLES2DecoderImpl::DoAttachShader(
7249 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:427250 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587251 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:427252 if (!program) {
[email protected]ae51d192010-04-27 00:48:037253 return;
[email protected]1958e0e2010-04-22 05:17:157254 }
[email protected]df37b9932013-03-08 05:21:427255 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
7256 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037257 return;
7258 }
[email protected]df37b9932013-03-08 05:21:427259 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517260 LOCAL_SET_GL_ERROR(
7261 GL_INVALID_OPERATION,
7262 "glAttachShader",
7263 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:317264 return;
7265 }
[email protected]df37b9932013-03-08 05:21:427266 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037267}
7268
7269void GLES2DecoderImpl::DoDetachShader(
7270 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:427271 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587272 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:427273 if (!program) {
[email protected]ae51d192010-04-27 00:48:037274 return;
7275 }
[email protected]df37b9932013-03-08 05:21:427276 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
7277 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037278 return;
7279 }
[email protected]df37b9932013-03-08 05:21:427280 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517281 LOCAL_SET_GL_ERROR(
7282 GL_INVALID_OPERATION,
7283 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:227284 return;
7285 }
[email protected]df37b9932013-03-08 05:21:427286 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037287}
7288
7289void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:427290 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587291 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:427292 if (!program) {
[email protected]ae51d192010-04-27 00:48:037293 return;
7294 }
[email protected]df37b9932013-03-08 05:21:427295 program->Validate();
[email protected]1958e0e2010-04-22 05:17:157296}
7297
[email protected]ac77603c72013-03-08 13:52:067298void GLES2DecoderImpl::GetVertexAttribHelper(
7299 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:247300 switch (pname) {
7301 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:067302 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:247303 if (buffer && !buffer->IsDeleted()) {
7304 GLuint client_id;
7305 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
7306 *params = client_id;
7307 }
7308 break;
7309 }
7310 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:067311 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:247312 break;
7313 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:067314 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:247315 break;
7316 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:067317 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:247318 break;
7319 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:067320 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:247321 break;
7322 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:067323 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:247324 break;
[email protected]c6aef902012-02-14 03:31:427325 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:067326 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:427327 break;
[email protected]ac77603c72013-03-08 13:52:067328 default:
7329 NOTREACHED();
7330 break;
7331 }
7332}
7333
[email protected]4c6f5462014-03-05 00:26:567334void GLES2DecoderImpl::DoGetTexParameterfv(
7335 GLenum target, GLenum pname, GLfloat* params) {
7336 InitTextureMaxAnisotropyIfNeeded(target, pname);
7337 glGetTexParameterfv(target, pname, params);
7338}
7339
7340void GLES2DecoderImpl::DoGetTexParameteriv(
7341 GLenum target, GLenum pname, GLint* params) {
7342 InitTextureMaxAnisotropyIfNeeded(target, pname);
7343 glGetTexParameteriv(target, pname, params);
7344}
7345
7346void GLES2DecoderImpl::InitTextureMaxAnisotropyIfNeeded(
7347 GLenum target, GLenum pname) {
7348 if (!workarounds().init_texture_max_anisotropy)
7349 return;
7350 if (pname != GL_TEXTURE_MAX_ANISOTROPY_EXT ||
7351 !validators_->texture_parameter.IsValid(pname)) {
7352 return;
7353 }
7354
7355 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
7356 &state_, target);
7357 if (!texture_ref) {
7358 LOCAL_SET_GL_ERROR(
7359 GL_INVALID_OPERATION,
7360 "glGetTexParamter{fi}v", "unknown texture for target");
7361 return;
7362 }
7363 Texture* texture = texture_ref->texture();
7364 texture->InitTextureMaxAnisotropyIfNeeded(target);
7365}
7366
[email protected]ac77603c72013-03-08 13:52:067367void GLES2DecoderImpl::DoGetVertexAttribfv(
7368 GLuint index, GLenum pname, GLfloat* params) {
7369 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7370 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517371 LOCAL_SET_GL_ERROR(
7372 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067373 return;
7374 }
7375 switch (pname) {
7376 case GL_CURRENT_VERTEX_ATTRIB: {
7377 const Vec4& value = state_.attrib_values[index];
7378 params[0] = value.v[0];
7379 params[1] = value.v[1];
7380 params[2] = value.v[2];
7381 params[3] = value.v[3];
7382 break;
7383 }
7384 default: {
7385 GLint value = 0;
7386 GetVertexAttribHelper(attrib, pname, &value);
7387 *params = static_cast<GLfloat>(value);
7388 break;
7389 }
7390 }
7391}
7392
7393void GLES2DecoderImpl::DoGetVertexAttribiv(
7394 GLuint index, GLenum pname, GLint* params) {
7395 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7396 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517397 LOCAL_SET_GL_ERROR(
7398 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067399 return;
7400 }
7401 switch (pname) {
[email protected]af6380962012-11-29 23:24:137402 case GL_CURRENT_VERTEX_ATTRIB: {
7403 const Vec4& value = state_.attrib_values[index];
7404 params[0] = static_cast<GLint>(value.v[0]);
7405 params[1] = static_cast<GLint>(value.v[1]);
7406 params[2] = static_cast<GLint>(value.v[2]);
7407 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:247408 break;
[email protected]af6380962012-11-29 23:24:137409 }
[email protected]b1122982010-05-17 23:04:247410 default:
[email protected]ac77603c72013-03-08 13:52:067411 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:247412 break;
7413 }
7414}
7415
[email protected]af6380962012-11-29 23:24:137416bool GLES2DecoderImpl::SetVertexAttribValue(
7417 const char* function_name, GLuint index, const GLfloat* value) {
7418 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:517419 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:137420 return false;
[email protected]b1122982010-05-17 23:04:247421 }
[email protected]af6380962012-11-29 23:24:137422 Vec4& v = state_.attrib_values[index];
7423 v.v[0] = value[0];
7424 v.v[1] = value[1];
7425 v.v[2] = value[2];
7426 v.v[3] = value[3];
7427 return true;
7428}
7429
7430void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
7431 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
7432 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
7433 glVertexAttrib1f(index, v0);
7434 }
[email protected]b1122982010-05-17 23:04:247435}
7436
7437void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:137438 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
7439 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
7440 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:247441 }
[email protected]b1122982010-05-17 23:04:247442}
7443
7444void GLES2DecoderImpl::DoVertexAttrib3f(
7445 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:137446 GLfloat v[4] = { v0, v1, v2, 1.0f, };
7447 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
7448 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:247449 }
[email protected]b1122982010-05-17 23:04:247450}
7451
7452void GLES2DecoderImpl::DoVertexAttrib4f(
7453 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:137454 GLfloat v[4] = { v0, v1, v2, v3, };
7455 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
7456 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:247457 }
[email protected]b1122982010-05-17 23:04:247458}
7459
7460void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137461 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
7462 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
7463 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:247464 }
[email protected]b1122982010-05-17 23:04:247465}
7466
7467void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137468 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
7469 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
7470 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:247471 }
[email protected]b1122982010-05-17 23:04:247472}
7473
7474void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137475 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
7476 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
7477 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:247478 }
[email protected]b1122982010-05-17 23:04:247479}
7480
7481void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137482 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
7483 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:247484 }
[email protected]b1122982010-05-17 23:04:247485}
7486
zmo0c4b7cf2014-11-26 00:52:117487error::Error GLES2DecoderImpl::HandleVertexAttribIPointer(
7488 uint32 immediate_data_size,
7489 const void* cmd_data) {
7490 // TODO(zmo): Unsafe ES3 API, missing states update.
7491 if (!unsafe_es3_apis_enabled())
7492 return error::kUnknownCommand;
7493 const gles2::cmds::VertexAttribIPointer& c =
7494 *static_cast<const gles2::cmds::VertexAttribIPointer*>(cmd_data);
7495 GLuint indx = c.indx;
7496 GLint size = c.size;
7497 GLenum type = c.type;
7498 GLsizei stride = c.stride;
7499 GLsizei offset = c.offset;
7500 const void* ptr = reinterpret_cast<const void*>(offset);
7501 glVertexAttribIPointer(indx, size, type, stride, ptr);
7502 return error::kNoError;
7503}
7504
[email protected]f7a64ee2010-02-01 22:24:147505error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
vmiuracd108592014-09-08 14:36:347506 uint32 immediate_data_size,
7507 const void* cmd_data) {
7508 const gles2::cmds::VertexAttribPointer& c =
7509 *static_cast<const gles2::cmds::VertexAttribPointer*>(cmd_data);
[email protected]944b62f32012-09-27 02:20:467510
[email protected]7cd76fd2013-06-02 21:11:117511 if (!state_.bound_array_buffer.get() ||
7512 state_.bound_array_buffer->IsDeleted()) {
7513 if (state_.vertex_attrib_manager.get() ==
[email protected]81f20a622014-04-18 01:54:527514 state_.default_vertex_attrib_manager.get()) {
[email protected]ab09b612013-03-11 22:11:517515 LOCAL_SET_GL_ERROR(
7516 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:467517 return error::kNoError;
7518 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:517519 LOCAL_SET_GL_ERROR(
7520 GL_INVALID_VALUE,
7521 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:467522 return error::kNoError;
7523 }
[email protected]96449d2c2009-11-25 00:01:327524 }
[email protected]8eee29c2010-04-29 03:38:297525
7526 GLuint indx = c.indx;
7527 GLint size = c.size;
7528 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:327529 GLboolean normalized = static_cast<GLboolean>(c.normalized);
[email protected]8eee29c2010-04-29 03:38:297530 GLsizei stride = c.stride;
7531 GLsizei offset = c.offset;
7532 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:057533 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517534 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:297535 return error::kNoError;
7536 }
[email protected]9438b012010-06-15 22:55:057537 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:517538 LOCAL_SET_GL_ERROR(
7539 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:297540 return error::kNoError;
7541 }
7542 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517543 LOCAL_SET_GL_ERROR(
7544 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:297545 return error::kNoError;
7546 }
7547 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:517548 LOCAL_SET_GL_ERROR(
7549 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:297550 return error::kNoError;
7551 }
7552 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:517553 LOCAL_SET_GL_ERROR(
7554 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:297555 return error::kNoError;
7556 }
7557 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:517558 LOCAL_SET_GL_ERROR(
7559 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:297560 return error::kNoError;
7561 }
7562 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:317563 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]a07a23602014-08-05 11:36:127564 // component_size must be a power of two to use & as optimized modulo.
7565 DCHECK(GLES2Util::IsPOT(component_size));
7566 if (offset & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517567 LOCAL_SET_GL_ERROR(
7568 GL_INVALID_OPERATION,
7569 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:317570 return error::kNoError;
7571 }
[email protected]a07a23602014-08-05 11:36:127572 if (stride & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517573 LOCAL_SET_GL_ERROR(
7574 GL_INVALID_OPERATION,
7575 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:297576 return error::kNoError;
7577 }
[email protected]7cd76fd2013-06-02 21:11:117578 state_.vertex_attrib_manager
7579 ->SetAttribInfo(indx,
7580 state_.bound_array_buffer.get(),
7581 size,
7582 type,
7583 normalized,
7584 stride,
7585 stride != 0 ? stride : component_size * size,
7586 offset);
[email protected]8fbedc02010-11-18 18:43:407587 if (type != GL_FIXED) {
7588 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
7589 }
[email protected]f7a64ee2010-02-01 22:24:147590 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327591}
7592
[email protected]43410e92012-04-20 17:06:287593void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
7594 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:247595 state_.viewport_x = x;
7596 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:027597 state_.viewport_width = std::min(width, viewport_max_width_);
7598 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:287599 glViewport(x, y, width, height);
7600}
7601
[email protected]c6aef902012-02-14 03:31:427602error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
vmiuracd108592014-09-08 14:36:347603 uint32 immediate_data_size,
7604 const void* cmd_data) {
7605 const gles2::cmds::VertexAttribDivisorANGLE& c =
7606 *static_cast<const gles2::cmds::VertexAttribDivisorANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:157607 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517608 LOCAL_SET_GL_ERROR(
7609 GL_INVALID_OPERATION,
7610 "glVertexAttribDivisorANGLE", "function not available");
[email protected]cedee332014-05-23 07:07:537611 return error::kNoError;
[email protected]c6aef902012-02-14 03:31:427612 }
7613 GLuint index = c.index;
7614 GLuint divisor = c.divisor;
7615 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517616 LOCAL_SET_GL_ERROR(
7617 GL_INVALID_VALUE,
7618 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:427619 return error::kNoError;
7620 }
7621
[email protected]e259eb412012-10-13 05:47:247622 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:427623 index,
7624 divisor);
7625 glVertexAttribDivisorANGLE(index, divisor);
7626 return error::kNoError;
7627}
7628
[email protected]68586372013-12-11 01:27:597629template <typename pixel_data_type>
7630static void WriteAlphaData(
7631 void *pixels, uint32 row_count, uint32 channel_count,
7632 uint32 alpha_channel_index, uint32 unpadded_row_size,
7633 uint32 padded_row_size, pixel_data_type alpha_value) {
7634 DCHECK_GT(channel_count, 0U);
7635 DCHECK_EQ(unpadded_row_size % sizeof(pixel_data_type), 0U);
7636 uint32 unpadded_row_size_in_elements =
7637 unpadded_row_size / sizeof(pixel_data_type);
7638 DCHECK_EQ(padded_row_size % sizeof(pixel_data_type), 0U);
7639 uint32 padded_row_size_in_elements =
7640 padded_row_size / sizeof(pixel_data_type);
7641 pixel_data_type* dst =
7642 static_cast<pixel_data_type*>(pixels) + alpha_channel_index;
7643 for (uint32 yy = 0; yy < row_count; ++yy) {
7644 pixel_data_type* end = dst + unpadded_row_size_in_elements;
7645 for (pixel_data_type* d = dst; d < end; d += channel_count) {
7646 *d = alpha_value;
7647 }
7648 dst += padded_row_size_in_elements;
7649 }
7650}
7651
[email protected]5a36dc132013-07-23 23:17:557652void GLES2DecoderImpl::FinishReadPixels(
7653 const cmds::ReadPixels& c,
7654 GLuint buffer) {
7655 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels");
7656 GLsizei width = c.width;
7657 GLsizei height = c.height;
7658 GLenum format = c.format;
7659 GLenum type = c.type;
7660 typedef cmds::ReadPixels::Result Result;
7661 uint32 pixels_size;
7662 Result* result = NULL;
7663 if (c.result_shm_id != 0) {
7664 result = GetSharedMemoryAs<Result*>(
7665 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7666 if (!result) {
7667 if (buffer != 0) {
7668 glDeleteBuffersARB(1, &buffer);
7669 }
7670 return;
7671 }
7672 }
7673 GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427674 width, height, 1, format, type, state_.pack_alignment, &pixels_size,
[email protected]5a36dc132013-07-23 23:17:557675 NULL, NULL);
7676 void* pixels = GetSharedMemoryAs<void*>(
7677 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
7678 if (!pixels) {
7679 if (buffer != 0) {
7680 glDeleteBuffersARB(1, &buffer);
7681 }
7682 return;
7683 }
7684
7685 if (buffer != 0) {
7686 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
[email protected]e585f9e22013-08-27 02:50:337687 void* data;
7688 if (features().map_buffer_range) {
7689 data = glMapBufferRange(
7690 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT);
7691 } else {
7692 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
7693 }
miub70d78592014-11-15 03:53:477694 if (!data) {
7695 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glMapBuffer",
7696 "Unable to map memory for readback.");
7697 return;
7698 }
[email protected]5a36dc132013-07-23 23:17:557699 memcpy(pixels, data, pixels_size);
7700 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't
7701 // have to restore the state.
7702 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
7703 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7704 glDeleteBuffersARB(1, &buffer);
7705 }
7706
7707 if (result != NULL) {
7708 *result = true;
7709 }
7710
7711 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7712 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7713 if ((channels_exist & 0x0008) == 0 &&
7714 workarounds().clear_alpha_in_readpixels) {
7715 // Set the alpha to 255 because some drivers are buggy in this regard.
7716 uint32 temp_size;
7717
7718 uint32 unpadded_row_size;
7719 uint32 padded_row_size;
7720 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427721 width, 2, 1, format, type, state_.pack_alignment, &temp_size,
[email protected]5a36dc132013-07-23 23:17:557722 &unpadded_row_size, &padded_row_size)) {
7723 return;
7724 }
[email protected]68586372013-12-11 01:27:597725
7726 uint32 channel_count = 0;
7727 uint32 alpha_channel = 0;
[email protected]5a36dc132013-07-23 23:17:557728 switch (format) {
7729 case GL_RGBA:
7730 case GL_BGRA_EXT:
[email protected]68586372013-12-11 01:27:597731 channel_count = 4;
7732 alpha_channel = 3;
[email protected]5a36dc132013-07-23 23:17:557733 break;
[email protected]68586372013-12-11 01:27:597734 case GL_ALPHA:
7735 channel_count = 1;
7736 alpha_channel = 0;
7737 break;
7738 }
7739
7740 if (channel_count > 0) {
7741 switch (type) {
7742 case GL_UNSIGNED_BYTE:
7743 WriteAlphaData<uint8>(
7744 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7745 padded_row_size, 0xFF);
7746 break;
7747 case GL_FLOAT:
7748 WriteAlphaData<float>(
7749 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7750 padded_row_size, 1.0f);
7751 break;
7752 case GL_HALF_FLOAT:
7753 WriteAlphaData<uint16>(
7754 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7755 padded_row_size, 0x3C00);
7756 break;
[email protected]5a36dc132013-07-23 23:17:557757 }
[email protected]5a36dc132013-07-23 23:17:557758 }
7759 }
7760}
7761
vmiuracd108592014-09-08 14:36:347762error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size,
7763 const void* cmd_data) {
7764 const gles2::cmds::ReadPixels& c =
7765 *static_cast<const gles2::cmds::ReadPixels*>(cmd_data);
[email protected]c959a09a2014-03-27 11:44:217766 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleReadPixels");
[email protected]c76fe672013-12-13 23:30:227767 error::Error fbo_error = WillAccessBoundFramebufferForRead();
7768 if (fbo_error != error::kNoError)
7769 return fbo_error;
[email protected]612d2f82009-12-08 20:49:317770 GLint x = c.x;
7771 GLint y = c.y;
7772 GLsizei width = c.width;
7773 GLsizei height = c.height;
7774 GLenum format = c.format;
7775 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:327776 GLboolean async = static_cast<GLboolean>(c.async);
[email protected]57f223832010-03-19 01:57:567777 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:517778 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:567779 return error::kNoError;
7780 }
[email protected]ed9f9cd2013-02-27 21:12:357781 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:187782 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347783 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427784 width, height, 1, format, type, state_.pack_alignment, &pixels_size,
[email protected]e259eb412012-10-13 05:47:247785 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187786 return error::kOutOfBounds;
7787 }
[email protected]612d2f82009-12-08 20:49:317788 void* pixels = GetSharedMemoryAs<void*>(
7789 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:107790 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147791 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467792 }
[email protected]de43f082013-04-02 01:16:107793 Result* result = NULL;
7794 if (c.result_shm_id != 0) {
7795 result = GetSharedMemoryAs<Result*>(
7796 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7797 if (!result) {
7798 return error::kOutOfBounds;
7799 }
7800 }
[email protected]a51788e2010-02-24 21:54:257801
[email protected]9438b012010-06-15 22:55:057802 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517803 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:297804 return error::kNoError;
7805 }
[email protected]68586372013-12-11 01:27:597806 if (!validators_->read_pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517807 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:127808 return error::kNoError;
7809 }
[email protected]68586372013-12-11 01:27:597810 if ((format != GL_RGBA && format != GL_BGRA_EXT && format != GL_RGB &&
7811 format != GL_ALPHA) || type != GL_UNSIGNED_BYTE) {
7812 // format and type are acceptable enums but not guaranteed to be supported
7813 // for this framebuffer. Have to ask gl if they are valid.
7814 GLint preferred_format = 0;
7815 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &preferred_format);
7816 GLint preferred_type = 0;
7817 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &preferred_type);
7818 if (format != static_cast<GLenum>(preferred_format) ||
7819 type != static_cast<GLenum>(preferred_type)) {
7820 LOCAL_SET_GL_ERROR(
7821 GL_INVALID_OPERATION, "glReadPixels", "format and type incompatible "
7822 "with the current read framebuffer");
7823 return error::kNoError;
7824 }
7825 }
[email protected]57f223832010-03-19 01:57:567826 if (width == 0 || height == 0) {
7827 return error::kNoError;
7828 }
7829
[email protected]57f223832010-03-19 01:57:567830 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:307831 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:567832
[email protected]3aad1a32012-09-07 20:54:477833 int32 max_x;
7834 int32 max_y;
7835 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:517836 LOCAL_SET_GL_ERROR(
7837 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:147838 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:317839 }
[email protected]57f223832010-03-19 01:57:567840
[email protected]2ea5950d2014-07-09 18:20:347841 if (!CheckBoundReadFramebufferColorAttachment("glReadPixels")) {
7842 return error::kNoError;
7843 }
7844
[email protected]0d6bfdc2011-11-02 01:32:207845 if (!CheckBoundFramebuffersValid("glReadPixels")) {
7846 return error::kNoError;
7847 }
7848
[email protected]caa13ed2014-02-17 11:29:207849 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixels");
[email protected]a0b78dc2011-11-11 10:43:107850
7851 ScopedResolvedFrameBufferBinder binder(this, false, true);
7852
[email protected]d37231fa2010-04-09 21:16:027853 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:567854 // The user requested an out of range area. Get the results 1 line
7855 // at a time.
7856 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:347857 uint32 unpadded_row_size;
7858 uint32 padded_row_size;
7859 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427860 width, 2, 1, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:347861 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:517862 LOCAL_SET_GL_ERROR(
7863 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567864 return error::kNoError;
7865 }
7866
7867 GLint dest_x_offset = std::max(-x, 0);
7868 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:347869 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427870 dest_x_offset, 1, 1, format, type, state_.pack_alignment,
7871 &dest_row_offset, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:517872 LOCAL_SET_GL_ERROR(
7873 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567874 return error::kNoError;
7875 }
7876
7877 // Copy each row into the larger dest rect.
7878 int8* dst = static_cast<int8*>(pixels);
7879 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:027880 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:567881 GLint read_width = read_end_x - read_x;
7882 for (GLint yy = 0; yy < height; ++yy) {
7883 GLint ry = y + yy;
7884
7885 // Clear the row.
7886 memset(dst, 0, unpadded_row_size);
7887
7888 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:027889 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:567890 glReadPixels(
7891 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
7892 }
7893 dst += padded_row_size;
7894 }
7895 } else {
[email protected]5a36dc132013-07-23 23:17:557896 if (async && features().use_async_readpixels) {
miu50cef602014-11-11 01:35:417897 GLuint buffer = 0;
[email protected]5a36dc132013-07-23 23:17:557898 glGenBuffersARB(1, &buffer);
7899 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
miub70d78592014-11-15 03:53:477900 // For ANGLE client version 2, GL_STREAM_READ is not available.
zmo68fcdc62014-12-05 21:51:497901 const GLenum usage_hint = feature_info_->gl_version_info().is_angle ?
7902 GL_STATIC_DRAW : GL_STREAM_READ;
miub70d78592014-11-15 03:53:477903 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, usage_hint);
[email protected]5a36dc132013-07-23 23:17:557904 GLenum error = glGetError();
7905 if (error == GL_NO_ERROR) {
7906 glReadPixels(x, y, width, height, format, type, 0);
7907 pending_readpixel_fences_.push(linked_ptr<FenceCallback>(
7908 new FenceCallback()));
7909 WaitForReadPixels(base::Bind(
7910 &GLES2DecoderImpl::FinishReadPixels,
7911 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr
7912 <GLES2DecoderImpl>(this),
7913 c, buffer));
7914 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7915 return error::kNoError;
[email protected]77bfe7442014-03-01 02:42:597916 } else {
7917 // On error, unbind pack buffer and fall through to sync readpixels
7918 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
miu50cef602014-11-11 01:35:417919 glDeleteBuffersARB(1, &buffer);
[email protected]5a36dc132013-07-23 23:17:557920 }
7921 }
[email protected]57f223832010-03-19 01:57:567922 glReadPixels(x, y, width, height, format, type, pixels);
7923 }
[email protected]ab09b612013-03-11 22:11:517924 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:257925 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:107926 if (result != NULL) {
7927 *result = true;
7928 }
[email protected]5a36dc132013-07-23 23:17:557929 FinishReadPixels(c, 0);
[email protected]a51788e2010-02-24 21:54:257930 }
[email protected]4848b9f82011-03-10 18:37:567931
[email protected]f7a64ee2010-02-01 22:24:147932 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327933}
7934
vmiuracd108592014-09-08 14:36:347935error::Error GLES2DecoderImpl::HandlePixelStorei(uint32 immediate_data_size,
7936 const void* cmd_data) {
7937 const gles2::cmds::PixelStorei& c =
7938 *static_cast<const gles2::cmds::PixelStorei*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:197939 GLenum pname = c.pname;
7940 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:057941 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:517942 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:127943 return error::kNoError;
7944 }
[email protected]222471d2011-11-30 18:06:397945 switch (pname) {
7946 case GL_PACK_ALIGNMENT:
7947 case GL_UNPACK_ALIGNMENT:
7948 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:517949 LOCAL_SET_GL_ERROR(
[email protected]caa13ed2014-02-17 11:29:207950 GL_INVALID_VALUE, "glPixelStorei", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:397951 return error::kNoError;
7952 }
[email protected]164d6d52012-05-05 00:55:037953 break;
[email protected]0a1e9ad2012-05-04 21:13:037954 case GL_UNPACK_FLIP_Y_CHROMIUM:
7955 unpack_flip_y_ = (param != 0);
7956 return error::kNoError;
7957 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
7958 unpack_premultiply_alpha_ = (param != 0);
7959 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:177960 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
7961 unpack_unpremultiply_alpha_ = (param != 0);
7962 return error::kNoError;
[email protected]222471d2011-11-30 18:06:397963 default:
7964 break;
[email protected]b9849abf2009-11-25 19:13:197965 }
7966 glPixelStorei(pname, param);
7967 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:437968 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247969 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437970 break;
7971 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:427972 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:437973 break;
7974 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247975 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437976 break;
7977 default:
7978 // Validation should have prevented us from getting here.
7979 NOTREACHED();
7980 break;
[email protected]b9849abf2009-11-25 19:13:197981 }
[email protected]f7a64ee2010-02-01 22:24:147982 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197983}
7984
[email protected]1c75a3702011-11-11 14:15:287985error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
vmiuracd108592014-09-08 14:36:347986 uint32 immediate_data_size,
7987 const void* cmd_data) {
7988 const gles2::cmds::PostSubBufferCHROMIUM& c =
7989 *static_cast<const gles2::cmds::PostSubBufferCHROMIUM*>(cmd_data);
[email protected]43ed3a72012-05-30 22:55:387990 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]a36ed4832014-04-24 16:40:277991 {
7992 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
7993 }
[email protected]b381ee32014-03-22 02:43:437994 if (!supports_post_sub_buffer_) {
[email protected]ab09b612013-03-11 22:11:517995 LOCAL_SET_GL_ERROR(
7996 GL_INVALID_OPERATION,
7997 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:287998 return error::kNoError;
7999 }
[email protected]8f9b8dd2013-09-12 18:05:138000 bool is_tracing;
8001 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
8002 &is_tracing);
8003 if (is_tracing) {
8004 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
8005 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
8006 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
8007 is_offscreen ? offscreen_size_ : surface_->GetSize());
8008 }
[email protected]7794d512012-04-17 20:36:498009 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:288010 return error::kNoError;
[email protected]7794d512012-04-17 20:36:498011 } else {
8012 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:288013 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:498014 }
[email protected]1c75a3702011-11-11 14:15:288015}
8016
[email protected]957f0642014-04-09 16:50:018017error::Error GLES2DecoderImpl::HandleScheduleOverlayPlaneCHROMIUM(
8018 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:348019 const void* cmd_data) {
8020 const gles2::cmds::ScheduleOverlayPlaneCHROMIUM& c =
8021 *static_cast<const gles2::cmds::ScheduleOverlayPlaneCHROMIUM*>(cmd_data);
[email protected]d286ebbc2014-07-03 17:19:108022 TextureRef* ref = texture_manager()->GetTexture(c.overlay_texture_id);
8023 if (!ref) {
8024 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
8025 "glScheduleOverlayPlaneCHROMIUM",
8026 "unknown texture");
8027 return error::kNoError;
8028 }
8029 gfx::GLImage* image =
8030 ref->texture()->GetLevelImage(ref->texture()->target(), 0);
8031 if (!image) {
8032 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
8033 "glScheduleOverlayPlaneCHROMIUM",
8034 "unsupported texture format");
8035 return error::kNoError;
8036 }
8037 gfx::OverlayTransform transform = GetGFXOverlayTransform(c.plane_transform);
8038 if (transform == gfx::OVERLAY_TRANSFORM_INVALID) {
8039 LOCAL_SET_GL_ERROR(GL_INVALID_ENUM,
8040 "glScheduleOverlayPlaneCHROMIUM",
8041 "invalid transform enum");
8042 return error::kNoError;
8043 }
8044 if (!surface_->ScheduleOverlayPlane(
8045 c.plane_z_order,
8046 transform,
8047 image,
8048 gfx::Rect(c.bounds_x, c.bounds_y, c.bounds_width, c.bounds_height),
8049 gfx::RectF(c.uv_x, c.uv_y, c.uv_width, c.uv_height))) {
8050 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
8051 "glScheduleOverlayPlaneCHROMIUM",
8052 "failed to schedule overlay");
8053 }
[email protected]957f0642014-04-09 16:50:018054 return error::kNoError;
8055}
8056
[email protected]558847a2010-03-24 07:02:548057error::Error GLES2DecoderImpl::GetAttribLocationHelper(
8058 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
8059 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:578060 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:518061 LOCAL_SET_GL_ERROR(
8062 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:578063 return error::kNoError;
8064 }
[email protected]df37b9932013-03-08 05:21:428065 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:588066 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:428067 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:148068 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198069 }
[email protected]df37b9932013-03-08 05:21:428070 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:518071 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438072 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:258073 return error::kNoError;
8074 }
[email protected]b9849abf2009-11-25 19:13:198075 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:548076 location_shm_id, location_shm_offset, sizeof(GLint));
8077 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:148078 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198079 }
[email protected]558847a2010-03-24 07:02:548080 // Require the client to init this incase the context is lost and we are no
8081 // longer executing commands.
8082 if (*location != -1) {
8083 return error::kGenericError;
8084 }
[email protected]df37b9932013-03-08 05:21:428085 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:148086 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198087}
8088
[email protected]558847a2010-03-24 07:02:548089error::Error GLES2DecoderImpl::HandleGetAttribLocation(
vmiuracd108592014-09-08 14:36:348090 uint32 immediate_data_size,
8091 const void* cmd_data) {
8092 const gles2::cmds::GetAttribLocation& c =
8093 *static_cast<const gles2::cmds::GetAttribLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:548094 Bucket* bucket = GetBucket(c.name_bucket_id);
8095 if (!bucket) {
8096 return error::kInvalidArguments;
8097 }
8098 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:188099 if (!bucket->GetAsString(&name_str)) {
8100 return error::kInvalidArguments;
8101 }
[email protected]558847a2010-03-24 07:02:548102 return GetAttribLocationHelper(
8103 c.program, c.location_shm_id, c.location_shm_offset, name_str);
8104}
8105
8106error::Error GLES2DecoderImpl::GetUniformLocationHelper(
8107 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
8108 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:578109 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:518110 LOCAL_SET_GL_ERROR(
8111 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:578112 return error::kNoError;
8113 }
[email protected]df37b9932013-03-08 05:21:428114 Program* program = GetProgramInfoNotShader(
[email protected]caa13ed2014-02-17 11:29:208115 client_id, "glGetUniformLocation");
[email protected]df37b9932013-03-08 05:21:428116 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:148117 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198118 }
[email protected]df37b9932013-03-08 05:21:428119 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:518120 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438121 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:258122 return error::kNoError;
8123 }
[email protected]b9849abf2009-11-25 19:13:198124 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:548125 location_shm_id, location_shm_offset, sizeof(GLint));
8126 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:148127 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198128 }
[email protected]558847a2010-03-24 07:02:548129 // Require the client to init this incase the context is lost an we are no
8130 // longer executing commands.
8131 if (*location != -1) {
8132 return error::kGenericError;
8133 }
[email protected]df37b9932013-03-08 05:21:428134 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:148135 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198136}
8137
[email protected]f7a64ee2010-02-01 22:24:148138error::Error GLES2DecoderImpl::HandleGetUniformLocation(
vmiuracd108592014-09-08 14:36:348139 uint32 immediate_data_size,
8140 const void* cmd_data) {
8141 const gles2::cmds::GetUniformLocation& c =
8142 *static_cast<const gles2::cmds::GetUniformLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:548143 Bucket* bucket = GetBucket(c.name_bucket_id);
8144 if (!bucket) {
8145 return error::kInvalidArguments;
8146 }
8147 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:188148 if (!bucket->GetAsString(&name_str)) {
8149 return error::kInvalidArguments;
8150 }
[email protected]558847a2010-03-24 07:02:548151 return GetUniformLocationHelper(
8152 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:198153}
8154
vmiuracd108592014-09-08 14:36:348155error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size,
8156 const void* cmd_data) {
8157 const gles2::cmds::GetString& c =
8158 *static_cast<const gles2::cmds::GetString*>(cmd_data);
[email protected]ddd968b82010-03-02 00:44:298159 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:058160 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:518161 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:298162 return error::kNoError;
8163 }
[email protected]959e9072013-09-20 16:58:388164 const char* str = reinterpret_cast<const char*>(glGetString(name));
[email protected]f0d74742011-10-03 16:31:048165 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:158166 switch (name) {
8167 case GL_VERSION:
8168 str = "OpenGL ES 2.0 Chromium";
8169 break;
8170 case GL_SHADING_LANGUAGE_VERSION:
8171 str = "OpenGL ES GLSL ES 1.0 Chromium";
8172 break;
[email protected]32939602012-05-09 06:25:168173 case GL_RENDERER:
[email protected]32939602012-05-09 06:25:168174 case GL_VENDOR:
[email protected]959e9072013-09-20 16:58:388175 // Return the unmasked VENDOR/RENDERER string for WebGL contexts.
8176 // They are used by WEBGL_debug_renderer_info.
8177 if (!force_webgl_glsl_validation_)
8178 str = "Chromium";
[email protected]32939602012-05-09 06:25:168179 break;
[email protected]1958e0e2010-04-22 05:17:158180 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:048181 {
[email protected]70dc60932013-06-04 03:33:498182 // For WebGL contexts, strip out the OES derivatives and
8183 // EXT frag depth extensions if they have not been enabled.
8184 if (force_webgl_glsl_validation_) {
[email protected]f0d74742011-10-03 16:31:048185 extensions = feature_info_->extensions();
[email protected]70dc60932013-06-04 03:33:498186 if (!derivatives_explicitly_enabled_) {
8187 size_t offset = extensions.find(kOESDerivativeExtension);
8188 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098189 extensions.replace(offset, arraysize(kOESDerivativeExtension),
[email protected]70dc60932013-06-04 03:33:498190 std::string());
8191 }
8192 }
8193 if (!frag_depth_explicitly_enabled_) {
8194 size_t offset = extensions.find(kEXTFragDepthExtension);
8195 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098196 extensions.replace(offset, arraysize(kEXTFragDepthExtension),
[email protected]70dc60932013-06-04 03:33:498197 std::string());
8198 }
[email protected]f0d74742011-10-03 16:31:048199 }
[email protected]aff39ac82013-06-08 04:53:138200 if (!draw_buffers_explicitly_enabled_) {
8201 size_t offset = extensions.find(kEXTDrawBuffersExtension);
8202 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098203 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension),
[email protected]aff39ac82013-06-08 04:53:138204 std::string());
8205 }
8206 }
[email protected]93c2fd82014-04-16 02:46:068207 if (!shader_texture_lod_explicitly_enabled_) {
8208 size_t offset = extensions.find(kEXTShaderTextureLodExtension);
8209 if (std::string::npos != offset) {
8210 extensions.replace(offset,
8211 arraysize(kEXTShaderTextureLodExtension),
8212 std::string());
8213 }
8214 }
[email protected]f0d74742011-10-03 16:31:048215 } else {
[email protected]6f5fac9d12012-06-26 21:02:458216 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:048217 }
[email protected]b381ee32014-03-22 02:43:438218 if (supports_post_sub_buffer_)
8219 extensions += " GL_CHROMIUM_post_sub_buffer";
[email protected]6f5fac9d12012-06-26 21:02:458220 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:048221 }
[email protected]1958e0e2010-04-22 05:17:158222 break;
8223 default:
[email protected]1958e0e2010-04-22 05:17:158224 break;
8225 }
[email protected]ddd968b82010-03-02 00:44:298226 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:158227 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:298228 return error::kNoError;
8229}
8230
vmiuracd108592014-09-08 14:36:348231error::Error GLES2DecoderImpl::HandleBufferData(uint32 immediate_data_size,
8232 const void* cmd_data) {
8233 const gles2::cmds::BufferData& c =
8234 *static_cast<const gles2::cmds::BufferData*>(cmd_data);
[email protected]0c86dbf2010-03-05 08:14:118235 GLenum target = static_cast<GLenum>(c.target);
8236 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
8237 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8238 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8239 GLenum usage = static_cast<GLenum>(c.usage);
8240 const void* data = NULL;
8241 if (data_shm_id != 0 || data_shm_offset != 0) {
8242 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
8243 if (!data) {
8244 return error::kOutOfBounds;
8245 }
8246 }
[email protected]0fbba3732013-07-17 15:40:138247 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:148248 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198249}
8250
[email protected]0c86dbf2010-03-05 08:14:118251void GLES2DecoderImpl::DoBufferSubData(
8252 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]0fbba3732013-07-17 15:40:138253 // Just delegate it. Some validation is actually done before this.
8254 buffer_manager()->ValidateAndDoBufferSubData(
8255 &state_, target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:198256}
8257
[email protected]0d6bfdc2011-11-02 01:32:208258bool GLES2DecoderImpl::ClearLevel(
8259 unsigned service_id,
8260 unsigned bind_target,
8261 unsigned target,
8262 int level,
[email protected]d8e6c9242014-02-20 16:56:258263 unsigned internal_format,
[email protected]0d6bfdc2011-11-02 01:32:208264 unsigned format,
8265 unsigned type,
8266 int width,
[email protected]4502e6492011-12-14 19:39:158267 int height,
8268 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:008269 uint32 channels = GLES2Util::GetChannelsForFormat(format);
[email protected]345ba902013-11-14 21:39:008270 if (feature_info_->feature_flags().angle_depth_texture &&
8271 (channels & GLES2Util::kDepth) != 0) {
[email protected]81375742012-06-08 00:04:008272 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
8273 // on depth formats.
8274 GLuint fb = 0;
8275 glGenFramebuffersEXT(1, &fb);
8276 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
8277
8278 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
8279 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
8280 GL_DEPTH_ATTACHMENT;
8281
8282 glFramebufferTexture2DEXT(
8283 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
8284 // ANGLE promises a depth only attachment ok.
8285 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
8286 GL_FRAMEBUFFER_COMPLETE) {
8287 return false;
8288 }
8289 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:478290 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
8291 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]81375742012-06-08 00:04:008292 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:458293 state_.SetDeviceDepthMask(GL_TRUE);
8294 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]81375742012-06-08 00:04:008295 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
8296
8297 RestoreClearState();
8298
8299 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:358300 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:008301 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
8302 GLuint fb_service_id =
8303 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
8304 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
8305 return true;
8306 }
8307
[email protected]45d15a62012-04-18 14:33:178308 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
8309
8310 uint32 size;
8311 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:348312 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428313 width, height, 1, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:178314 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:208315 return false;
8316 }
[email protected]45d15a62012-04-18 14:33:178317
[email protected]a5d3dad2012-05-26 04:34:448318 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
8319
[email protected]45d15a62012-04-18 14:33:178320 int tile_height;
8321
8322 if (size > kMaxZeroSize) {
8323 if (kMaxZeroSize < padded_row_size) {
8324 // That'd be an awfully large texture.
8325 return false;
8326 }
8327 // We should never have a large total size with a zero row size.
8328 DCHECK_GT(padded_row_size, 0U);
8329 tile_height = kMaxZeroSize / padded_row_size;
8330 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428331 width, tile_height, 1, format, type, state_.unpack_alignment, &size,
[email protected]e259eb412012-10-13 05:47:248332 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:178333 return false;
8334 }
[email protected]4502e6492011-12-14 19:39:158335 } else {
[email protected]45d15a62012-04-18 14:33:178336 tile_height = height;
8337 }
8338
8339 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:558340 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:178341 memset(zero.get(), 0, size);
8342 glBindTexture(bind_target, service_id);
8343
8344 GLint y = 0;
8345 while (y < height) {
8346 GLint h = y + tile_height > height ? height - y : tile_height;
8347 if (is_texture_immutable || h != height) {
8348 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
8349 } else {
[email protected]8f1d2aa2013-05-10 23:45:388350 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:258351 target, level, internal_format, width, h, 0, format, type,
8352 zero.get());
[email protected]45d15a62012-04-18 14:33:178353 }
8354 y += tile_height;
[email protected]4502e6492011-12-14 19:39:158355 }
[email protected]c986af502013-08-14 01:04:448356 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
8357 &state_, bind_target);
[email protected]02965c22013-03-09 02:40:078358 glBindTexture(bind_target, texture ? texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:208359 return true;
8360}
8361
[email protected]ad84a3a2012-06-08 21:42:438362namespace {
8363
8364const int kS3TCBlockWidth = 4;
8365const int kS3TCBlockHeight = 4;
8366const int kS3TCDXT1BlockSize = 8;
8367const int kS3TCDXT3AndDXT5BlockSize = 16;
8368
8369bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:518370 return (size == 1) ||
8371 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:438372}
8373
[email protected]8aec81ec2014-04-29 01:04:518374bool IsValidPVRTCSize(GLint level, GLsizei size) {
[email protected]a07a23602014-08-05 11:36:128375 return GLES2Util::IsPOT(size);
[email protected]8aec81ec2014-04-29 01:04:518376}
8377
[email protected]ad84a3a2012-06-08 21:42:438378} // anonymous namespace.
8379
8380bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
8381 const char* function_name,
8382 GLsizei width, GLsizei height, GLenum format, size_t size) {
8383 unsigned int bytes_required = 0;
8384
8385 switch (format) {
[email protected]8aec81ec2014-04-29 01:04:518386 case GL_ATC_RGB_AMD:
[email protected]ad84a3a2012-06-08 21:42:438387 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
[email protected]8aec81ec2014-04-29 01:04:518388 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8389 case GL_ETC1_RGB8_OES: {
[email protected]ad84a3a2012-06-08 21:42:438390 int num_blocks_across =
8391 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8392 int num_blocks_down =
8393 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8394 int num_blocks = num_blocks_across * num_blocks_down;
8395 bytes_required = num_blocks * kS3TCDXT1BlockSize;
8396 break;
8397 }
[email protected]8aec81ec2014-04-29 01:04:518398 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8399 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
[email protected]ad84a3a2012-06-08 21:42:438400 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8401 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8402 int num_blocks_across =
8403 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8404 int num_blocks_down =
8405 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8406 int num_blocks = num_blocks_across * num_blocks_down;
8407 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
8408 break;
8409 }
[email protected]8aec81ec2014-04-29 01:04:518410 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8411 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: {
8412 bytes_required = (std::max(width, 8) * std::max(height, 8) * 4 + 7)/8;
8413 break;
8414 }
8415 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8416 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8417 bytes_required = (std::max(width, 16) * std::max(height, 8) * 2 + 7)/8;
[email protected]2d3765b2012-10-03 00:31:078418 break;
8419 }
[email protected]ad84a3a2012-06-08 21:42:438420 default:
[email protected]ab09b612013-03-11 22:11:518421 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:438422 return false;
8423 }
8424
8425 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:518426 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438427 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
8428 return false;
8429 }
8430
8431 return true;
8432}
8433
8434bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
8435 const char* function_name,
8436 GLint level, GLsizei width, GLsizei height, GLenum format) {
8437 switch (format) {
8438 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8439 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8440 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8441 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8442 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:518443 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438444 GL_INVALID_OPERATION, function_name,
8445 "width or height invalid for level");
8446 return false;
8447 }
8448 return true;
8449 }
[email protected]8aec81ec2014-04-29 01:04:518450 case GL_ATC_RGB_AMD:
8451 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8452 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
8453 case GL_ETC1_RGB8_OES: {
[email protected]2d3765b2012-10-03 00:31:078454 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:518455 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078456 GL_INVALID_OPERATION, function_name,
8457 "width or height invalid for level");
8458 return false;
8459 }
8460 return true;
[email protected]8aec81ec2014-04-29 01:04:518461 }
8462 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8463 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8464 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8465 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8466 if (!IsValidPVRTCSize(level, width) ||
8467 !IsValidPVRTCSize(level, height)) {
8468 LOCAL_SET_GL_ERROR(
8469 GL_INVALID_OPERATION, function_name,
8470 "width or height invalid for level");
8471 return false;
8472 }
8473 return true;
8474 }
[email protected]ad84a3a2012-06-08 21:42:438475 default:
8476 return false;
8477 }
8478}
8479
8480bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
8481 const char* function_name,
8482 GLenum target, GLint level, GLint xoffset, GLint yoffset,
8483 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:358484 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:438485 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:518486 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438487 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
8488 return false;
8489 }
8490
8491 switch (format) {
8492 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8493 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8494 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8495 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8496 const int kBlockWidth = 4;
8497 const int kBlockHeight = 4;
8498 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:518499 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438500 GL_INVALID_OPERATION, function_name,
8501 "xoffset or yoffset not multiple of 4");
8502 return false;
8503 }
8504 GLsizei tex_width = 0;
8505 GLsizei tex_height = 0;
8506 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8507 width - xoffset > tex_width ||
8508 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:518509 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438510 GL_INVALID_OPERATION, function_name, "dimensions out of range");
8511 return false;
8512 }
8513 return ValidateCompressedTexDimensions(
8514 function_name, level, width, height, format);
8515 }
[email protected]8aec81ec2014-04-29 01:04:518516 case GL_ATC_RGB_AMD:
8517 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8518 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: {
8519 LOCAL_SET_GL_ERROR(
8520 GL_INVALID_OPERATION, function_name,
8521 "not supported for ATC textures");
8522 return false;
8523 }
[email protected]2d3765b2012-10-03 00:31:078524 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:518525 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078526 GL_INVALID_OPERATION, function_name,
[email protected]caa13ed2014-02-17 11:29:208527 "not supported for ECT1_RGB8_OES textures");
[email protected]2d3765b2012-10-03 00:31:078528 return false;
8529 }
[email protected]8aec81ec2014-04-29 01:04:518530 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8531 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8532 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8533 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8534 if ((xoffset != 0) || (yoffset != 0)) {
8535 LOCAL_SET_GL_ERROR(
8536 GL_INVALID_OPERATION, function_name,
8537 "xoffset and yoffset must be zero");
8538 return false;
8539 }
8540 GLsizei tex_width = 0;
8541 GLsizei tex_height = 0;
8542 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8543 width != tex_width ||
8544 height != tex_height) {
8545 LOCAL_SET_GL_ERROR(
8546 GL_INVALID_OPERATION, function_name,
8547 "dimensions must match existing texture level dimensions");
8548 return false;
8549 }
8550 return ValidateCompressedTexDimensions(
8551 function_name, level, width, height, format);
8552 }
[email protected]ad84a3a2012-06-08 21:42:438553 default:
8554 return false;
8555 }
8556}
8557
[email protected]a93bb842010-02-16 23:03:478558error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
8559 GLenum target,
8560 GLint level,
8561 GLenum internal_format,
8562 GLsizei width,
8563 GLsizei height,
8564 GLint border,
8565 GLsizei image_size,
8566 const void* data) {
[email protected]a93bb842010-02-16 23:03:478567 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:058568 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518569 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8570 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:298571 return error::kNoError;
8572 }
[email protected]9438b012010-06-15 22:55:058573 if (!validators_->compressed_texture_format.IsValid(
8574 internal_format)) {
[email protected]ab09b612013-03-11 22:11:518575 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538576 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:478577 return error::kNoError;
8578 }
[email protected]80eb6b52012-01-19 00:14:418579 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:478580 border != 0) {
[email protected]ab09b612013-03-11 22:11:518581 LOCAL_SET_GL_ERROR(
8582 GL_INVALID_VALUE,
8583 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:478584 return error::kNoError;
8585 }
[email protected]c986af502013-08-14 01:04:448586 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8587 &state_, target);
[email protected]370eaf12013-05-18 09:19:498588 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518589 LOCAL_SET_GL_ERROR(
8590 GL_INVALID_VALUE,
8591 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:478592 return error::kNoError;
8593 }
[email protected]370eaf12013-05-18 09:19:498594 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078595 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518596 LOCAL_SET_GL_ERROR(
8597 GL_INVALID_OPERATION,
8598 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:438599 return error::kNoError;
8600 }
8601
8602 if (!ValidateCompressedTexDimensions(
8603 "glCompressedTexImage2D", level, width, height, internal_format) ||
8604 !ValidateCompressedTexFuncData(
8605 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:178606 return error::kNoError;
8607 }
[email protected]968351b2011-12-20 08:26:518608
[email protected]7989c9e2013-01-23 06:39:268609 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:518610 LOCAL_SET_GL_ERROR(
8611 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:268612 return error::kNoError;
8613 }
8614
[email protected]02965c22013-03-09 02:40:078615 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448616 framebuffer_state_.clear_state_dirty = true;
[email protected]968351b2011-12-20 08:26:518617 }
8618
[email protected]40d90a22013-04-09 03:39:558619 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:478620 if (!data) {
8621 zero.reset(new int8[image_size]);
8622 memset(zero.get(), 0, image_size);
8623 data = zero.get();
8624 }
[email protected]ab09b612013-03-11 22:11:518625 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:478626 glCompressedTexImage2D(
8627 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:518628 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438629 if (error == GL_NO_ERROR) {
8630 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498631 texture_ref, target, level, internal_format,
8632 width, height, 1, border, 0, 0, true);
[email protected]cadde4a2010-07-31 17:10:438633 }
vmiura8266ca72014-09-09 21:37:008634
8635 // This may be a slow command. Exit command processing to allow for
8636 // context preemption and GPU watchdog checks.
8637 ExitCommandProcessingEarly();
[email protected]a93bb842010-02-16 23:03:478638 return error::kNoError;
8639}
8640
[email protected]f7a64ee2010-02-01 22:24:148641error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
vmiuracd108592014-09-08 14:36:348642 uint32 immediate_data_size,
8643 const void* cmd_data) {
8644 const gles2::cmds::CompressedTexImage2D& c =
8645 *static_cast<const gles2::cmds::CompressedTexImage2D*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:198646 GLenum target = static_cast<GLenum>(c.target);
8647 GLint level = static_cast<GLint>(c.level);
8648 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8649 GLsizei width = static_cast<GLsizei>(c.width);
8650 GLsizei height = static_cast<GLsizei>(c.height);
8651 GLint border = static_cast<GLint>(c.border);
8652 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
8653 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8654 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8655 const void* data = NULL;
8656 if (data_shm_id != 0 || data_shm_offset != 0) {
8657 data = GetSharedMemoryAs<const void*>(
8658 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:468659 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:148660 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198661 }
8662 }
[email protected]a93bb842010-02-16 23:03:478663 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:198664 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:198665}
8666
[email protected]b6140d02010-05-17 14:47:168667error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
vmiuracd108592014-09-08 14:36:348668 uint32 immediate_data_size,
8669 const void* cmd_data) {
8670 const gles2::cmds::CompressedTexImage2DBucket& c =
8671 *static_cast<const gles2::cmds::CompressedTexImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:168672 GLenum target = static_cast<GLenum>(c.target);
8673 GLint level = static_cast<GLint>(c.level);
8674 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8675 GLsizei width = static_cast<GLsizei>(c.width);
8676 GLsizei height = static_cast<GLsizei>(c.height);
8677 GLint border = static_cast<GLint>(c.border);
8678 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288679 if (!bucket) {
8680 return error::kInvalidArguments;
8681 }
8682 uint32 data_size = bucket->size();
8683 GLsizei imageSize = data_size;
8684 const void* data = bucket->GetData(0, data_size);
8685 if (!data) {
8686 return error::kInvalidArguments;
8687 }
[email protected]b6140d02010-05-17 14:47:168688 return DoCompressedTexImage2D(
8689 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:288690 imageSize, data);
[email protected]b6140d02010-05-17 14:47:168691}
8692
8693error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
8694 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:348695 const void* cmd_data) {
8696 const gles2::cmds::CompressedTexSubImage2DBucket& c =
8697 *static_cast<const gles2::cmds::CompressedTexSubImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:168698 GLenum target = static_cast<GLenum>(c.target);
8699 GLint level = static_cast<GLint>(c.level);
8700 GLint xoffset = static_cast<GLint>(c.xoffset);
8701 GLint yoffset = static_cast<GLint>(c.yoffset);
8702 GLsizei width = static_cast<GLsizei>(c.width);
8703 GLsizei height = static_cast<GLsizei>(c.height);
8704 GLenum format = static_cast<GLenum>(c.format);
8705 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288706 if (!bucket) {
8707 return error::kInvalidArguments;
8708 }
[email protected]b6140d02010-05-17 14:47:168709 uint32 data_size = bucket->size();
8710 GLsizei imageSize = data_size;
8711 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:288712 if (!data) {
8713 return error::kInvalidArguments;
8714 }
[email protected]9438b012010-06-15 22:55:058715 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518716 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:538717 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:168718 return error::kNoError;
8719 }
[email protected]9438b012010-06-15 22:55:058720 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518721 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8722 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:058723 return error::kNoError;
8724 }
[email protected]b6140d02010-05-17 14:47:168725 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518726 LOCAL_SET_GL_ERROR(
8727 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:168728 return error::kNoError;
8729 }
8730 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518731 LOCAL_SET_GL_ERROR(
8732 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:168733 return error::kNoError;
8734 }
8735 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:518736 LOCAL_SET_GL_ERROR(
8737 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:168738 return error::kNoError;
8739 }
[email protected]cadde4a2010-07-31 17:10:438740 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:168741 target, level, xoffset, yoffset, width, height, format, imageSize, data);
8742 return error::kNoError;
8743}
8744
vmiuracd108592014-09-08 14:36:348745error::Error GLES2DecoderImpl::HandleTexImage2D(uint32 immediate_data_size,
8746 const void* cmd_data) {
8747 const gles2::cmds::TexImage2D& c =
8748 *static_cast<const gles2::cmds::TexImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:138749 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D",
8750 "width", c.width, "height", c.height);
[email protected]c986af502013-08-14 01:04:448751 // Set as failed for now, but if it successed, this will be set to not failed.
8752 texture_state_.tex_image_2d_failed = true;
[email protected]b9849abf2009-11-25 19:13:198753 GLenum target = static_cast<GLenum>(c.target);
8754 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:448755 // TODO(kloveless): Change TexImage2D command to use unsigned integer
8756 // for internalformat.
8757 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:198758 GLsizei width = static_cast<GLsizei>(c.width);
8759 GLsizei height = static_cast<GLsizei>(c.height);
8760 GLint border = static_cast<GLint>(c.border);
8761 GLenum format = static_cast<GLenum>(c.format);
8762 GLenum type = static_cast<GLenum>(c.type);
8763 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
8764 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:188765 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:348766 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428767 width, height, 1, format, type, state_.unpack_alignment, &pixels_size,
8768 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:188769 return error::kOutOfBounds;
8770 }
[email protected]b9849abf2009-11-25 19:13:198771 const void* pixels = NULL;
8772 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
8773 pixels = GetSharedMemoryAs<const void*>(
8774 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:468775 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:148776 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198777 }
8778 }
[email protected]f598f422012-12-07 08:30:038779
[email protected]c986af502013-08-14 01:04:448780 TextureManager::DoTextImage2DArguments args = {
8781 target, level, internal_format, width, height, border, format, type,
8782 pixels, pixels_size};
8783 texture_manager()->ValidateAndDoTexImage2D(
8784 &texture_state_, &state_, &framebuffer_state_, args);
vmiura8266ca72014-09-09 21:37:008785
8786 // This may be a slow command. Exit command processing to allow for
8787 // context preemption and GPU watchdog checks.
8788 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:038789 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198790}
8791
zmobcadd6592015-01-08 20:13:428792error::Error GLES2DecoderImpl::HandleTexImage3D(uint32 immediate_data_size,
8793 const void* cmd_data) {
8794 // TODO(zmo): Unsafe ES3 API.
8795 if (!unsafe_es3_apis_enabled())
8796 return error::kUnknownCommand;
8797
8798 const gles2::cmds::TexImage3D& c =
8799 *static_cast<const gles2::cmds::TexImage3D*>(cmd_data);
8800 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage3D",
8801 "widthXheight", c.width * c.height, "depth", c.depth);
8802 GLenum target = static_cast<GLenum>(c.target);
8803 GLint level = static_cast<GLint>(c.level);
8804 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8805 GLsizei width = static_cast<GLsizei>(c.width);
8806 GLsizei height = static_cast<GLsizei>(c.height);
8807 GLsizei depth = static_cast<GLsizei>(c.depth);
8808 GLint border = static_cast<GLint>(c.border);
8809 GLenum format = static_cast<GLenum>(c.format);
8810 GLenum type = static_cast<GLenum>(c.type);
8811 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
8812 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
8813 uint32 pixels_size;
8814 if (!GLES2Util::ComputeImageDataSizes(
8815 width, height, depth, format, type, state_.unpack_alignment, &pixels_size,
8816 NULL, NULL)) {
8817 return error::kOutOfBounds;
8818 }
8819 const void* pixels = NULL;
8820 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
8821 pixels = GetSharedMemoryAs<const void*>(
8822 pixels_shm_id, pixels_shm_offset, pixels_size);
8823 if (!pixels) {
8824 return error::kOutOfBounds;
8825 }
8826 }
8827
8828 glTexImage3D(target, level, internal_format, width, height, depth, border,
8829 format, type, pixels);
8830
8831 // This may be a slow command. Exit command processing to allow for
8832 // context preemption and GPU watchdog checks.
8833 ExitCommandProcessingEarly();
8834 return error::kNoError;
8835}
8836
[email protected]cadde4a2010-07-31 17:10:438837void GLES2DecoderImpl::DoCompressedTexSubImage2D(
8838 GLenum target,
8839 GLint level,
8840 GLint xoffset,
8841 GLint yoffset,
8842 GLsizei width,
8843 GLsizei height,
8844 GLenum format,
8845 GLsizei image_size,
8846 const void * data) {
[email protected]c986af502013-08-14 01:04:448847 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8848 &state_, target);
[email protected]370eaf12013-05-18 09:19:498849 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518850 LOCAL_SET_GL_ERROR(
8851 GL_INVALID_OPERATION,
8852 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438853 return;
8854 }
[email protected]370eaf12013-05-18 09:19:498855 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438856 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:528857 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078858 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518859 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528860 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438861 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:528862 return;
8863 }
8864 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:518865 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528866 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438867 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:528868 return;
8869 }
[email protected]02965c22013-03-09 02:40:078870 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528871 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518872 LOCAL_SET_GL_ERROR(
8873 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438874 return;
8875 }
[email protected]ad84a3a2012-06-08 21:42:438876
8877 if (!ValidateCompressedTexFuncData(
8878 "glCompressedTexSubImage2D", width, height, format, image_size) ||
8879 !ValidateCompressedTexSubDimensions(
8880 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:078881 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:438882 return;
8883 }
8884
8885
[email protected]0d6bfdc2011-11-02 01:32:208886 // Note: There is no need to deal with texture cleared tracking here
8887 // because the validation above means you can only get here if the level
8888 // is already a matching compressed format and in that case
8889 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:438890 glCompressedTexSubImage2D(
8891 target, level, xoffset, yoffset, width, height, format, image_size, data);
vmiura8266ca72014-09-09 21:37:008892
8893 // This may be a slow command. Exit command processing to allow for
8894 // context preemption and GPU watchdog checks.
8895 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:438896}
8897
[email protected]6e288612010-12-21 20:45:038898static void Clip(
8899 GLint start, GLint range, GLint sourceRange,
8900 GLint* out_start, GLint* out_range) {
8901 DCHECK(out_start);
8902 DCHECK(out_range);
8903 if (start < 0) {
8904 range += start;
8905 start = 0;
8906 }
8907 GLint end = start + range;
8908 if (end > sourceRange) {
8909 range -= end - sourceRange;
8910 }
8911 *out_start = start;
8912 *out_range = range;
8913}
8914
[email protected]cadde4a2010-07-31 17:10:438915void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:448916 GLenum target,
8917 GLint level,
8918 GLenum internal_format,
8919 GLint x,
8920 GLint y,
8921 GLsizei width,
8922 GLsizei height,
8923 GLint border) {
[email protected]09e17272012-11-30 10:30:448924 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:448925 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8926 &state_, target);
[email protected]370eaf12013-05-18 09:19:498927 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518928 LOCAL_SET_GL_ERROR(
8929 GL_INVALID_OPERATION,
8930 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438931 return;
8932 }
[email protected]370eaf12013-05-18 09:19:498933 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078934 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518935 LOCAL_SET_GL_ERROR(
8936 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]cedee332014-05-23 07:07:538937 return;
[email protected]97dc7cbe2011-12-06 17:26:178938 }
[email protected]80eb6b52012-01-19 00:14:418939 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:188940 border != 0) {
[email protected]ab09b612013-03-11 22:11:518941 LOCAL_SET_GL_ERROR(
8942 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:188943 return;
8944 }
[email protected]17a961192014-02-14 15:20:528945 if (!texture_manager()->ValidateFormatAndTypeCombination(
8946 state_.GetErrorState(), "glCopyTexImage2D", internal_format,
8947 GL_UNSIGNED_BYTE)) {
[email protected]81375742012-06-08 00:04:008948 return;
8949 }
[email protected]f5719fb2010-08-04 18:27:188950
[email protected]9edc6b22010-12-23 02:00:268951 // Check we have compatible formats.
8952 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8953 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8954 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
8955
8956 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518957 LOCAL_SET_GL_ERROR(
8958 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268959 return;
8960 }
8961
[email protected]81375742012-06-08 00:04:008962 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518963 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008964 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:268965 "glCopyTexImage2D", "can not be used with depth or stencil textures");
8966 return;
8967 }
8968
8969 uint32 estimated_size = 0;
8970 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428971 width, height, 1, internal_format, GL_UNSIGNED_BYTE,
8972 state_.unpack_alignment, &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518973 LOCAL_SET_GL_ERROR(
8974 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:268975 return;
8976 }
8977
8978 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:518979 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:008980 return;
8981 }
8982
[email protected]2ea5950d2014-07-09 18:20:348983 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexImage2D")) {
8984 return;
8985 }
8986
zmo383512cf2014-10-14 00:11:008987 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
8988 LOCAL_SET_GL_ERROR(
8989 GL_INVALID_OPERATION,
8990 "glCopyTexImage2D", "source and destination textures are the same");
8991 return;
8992 }
8993
[email protected]a0b78dc2011-11-11 10:43:108994 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
8995 return;
8996 }
8997
[email protected]ab09b612013-03-11 22:11:518998 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:278999 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:039000 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:269001
[email protected]02965c22013-03-09 02:40:079002 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:449003 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:469004 }
9005
[email protected]9edc6b22010-12-23 02:00:269006 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:039007 GLint copyX = 0;
9008 GLint copyY = 0;
9009 GLint copyWidth = 0;
9010 GLint copyHeight = 0;
9011 Clip(x, width, size.width(), &copyX, &copyWidth);
9012 Clip(y, height, size.height(), &copyY, &copyHeight);
9013
9014 if (copyX != x ||
9015 copyY != y ||
9016 copyWidth != width ||
9017 copyHeight != height) {
9018 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:209019 if (!ClearLevel(
[email protected]02965c22013-03-09 02:40:079020 texture->service_id(), texture->target(),
[email protected]d8e6c9242014-02-20 16:56:259021 target, level, internal_format, internal_format, GL_UNSIGNED_BYTE,
9022 width, height, texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:519023 LOCAL_SET_GL_ERROR(
9024 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:039025 return;
9026 }
[email protected]6e288612010-12-21 20:45:039027 if (copyHeight > 0 && copyWidth > 0) {
9028 GLint dx = copyX - x;
9029 GLint dy = copyY - y;
9030 GLint destX = dx;
9031 GLint destY = dy;
[email protected]00c2cf92014-03-14 00:08:379032 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039033 glCopyTexSubImage2D(target, level,
9034 destX, destY, copyX, copyY,
9035 copyWidth, copyHeight);
9036 }
9037 } else {
[email protected]00c2cf92014-03-14 00:08:379038 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039039 glCopyTexImage2D(target, level, internal_format,
9040 copyX, copyY, copyWidth, copyHeight, border);
9041 }
[email protected]ab09b612013-03-11 22:11:519042 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:439043 if (error == GL_NO_ERROR) {
9044 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499045 texture_ref, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:209046 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:439047 }
vmiura8266ca72014-09-09 21:37:009048
9049 // This may be a slow command. Exit command processing to allow for
9050 // context preemption and GPU watchdog checks.
9051 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:439052}
9053
9054void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:449055 GLenum target,
9056 GLint level,
9057 GLint xoffset,
9058 GLint yoffset,
9059 GLint x,
9060 GLint y,
9061 GLsizei width,
9062 GLsizei height) {
[email protected]09e17272012-11-30 10:30:449063 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:449064 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9065 &state_, target);
[email protected]370eaf12013-05-18 09:19:499066 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519067 LOCAL_SET_GL_ERROR(
9068 GL_INVALID_OPERATION,
9069 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:439070 return;
9071 }
[email protected]370eaf12013-05-18 09:19:499072 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:439073 GLenum type = 0;
9074 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:079075 if (!texture->GetLevelType(target, level, &type, &format) ||
9076 !texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:529077 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:519078 LOCAL_SET_GL_ERROR(
9079 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:439080 return;
9081 }
[email protected]85a4ac22013-05-31 01:58:479082 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:519083 LOCAL_SET_GL_ERROR(
9084 GL_INVALID_OPERATION,
9085 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:599086 return;
9087 }
[email protected]9edc6b22010-12-23 02:00:269088
9089 // Check we have compatible formats.
9090 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
9091 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
9092 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
9093
[email protected]2d3765b2012-10-03 00:31:079094 if (!channels_needed ||
9095 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:519096 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439097 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:269098 return;
9099 }
9100
[email protected]81375742012-06-08 00:04:009101 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:519102 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:009103 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439104 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:009105 return;
9106 }
9107
[email protected]2ea5950d2014-07-09 18:20:349108 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexSubImage2D")) {
9109 return;
9110 }
9111
zmo383512cf2014-10-14 00:11:009112 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
9113 LOCAL_SET_GL_ERROR(
9114 GL_INVALID_OPERATION,
9115 "glCopyTexSubImage2D", "source and destination textures are the same");
9116 return;
9117 }
9118
[email protected]a0b78dc2011-11-11 10:43:109119 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
9120 return;
9121 }
9122
[email protected]de26b3c2011-08-03 21:54:279123 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:039124 gfx::Size size = GetBoundReadFrameBufferSize();
9125 GLint copyX = 0;
9126 GLint copyY = 0;
9127 GLint copyWidth = 0;
9128 GLint copyHeight = 0;
9129 Clip(x, width, size.width(), &copyX, &copyWidth);
9130 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:209131
dongseong.hwang351519f2015-01-21 14:33:599132 if (xoffset != 0 || yoffset != 0 || width != size.width() ||
9133 height != size.height()) {
9134 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target,
9135 level)) {
9136 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexSubImage2D",
9137 "dimensions too big");
9138 return;
9139 }
9140 } else {
9141 // Write all pixels in below.
9142 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
[email protected]0d6bfdc2011-11-02 01:32:209143 }
9144
[email protected]6e288612010-12-21 20:45:039145 if (copyX != x ||
9146 copyY != y ||
9147 copyWidth != width ||
9148 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:209149 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:039150 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:349151 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:429152 width, height, 1, format, type, state_.unpack_alignment, &pixels_size,
[email protected]e259eb412012-10-13 05:47:249153 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:519154 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439155 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:039156 return;
9157 }
[email protected]40d90a22013-04-09 03:39:559158 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:039159 memset(zero.get(), 0, pixels_size);
[email protected]00c2cf92014-03-14 00:08:379160 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039161 glTexSubImage2D(
9162 target, level, xoffset, yoffset, width, height,
9163 format, type, zero.get());
9164 }
[email protected]0d6bfdc2011-11-02 01:32:209165
[email protected]6e288612010-12-21 20:45:039166 if (copyHeight > 0 && copyWidth > 0) {
9167 GLint dx = copyX - x;
9168 GLint dy = copyY - y;
9169 GLint destX = xoffset + dx;
9170 GLint destY = yoffset + dy;
[email protected]00c2cf92014-03-14 00:08:379171 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039172 glCopyTexSubImage2D(target, level,
9173 destX, destY, copyX, copyY,
9174 copyWidth, copyHeight);
9175 }
vmiura8266ca72014-09-09 21:37:009176
9177 // This may be a slow command. Exit command processing to allow for
9178 // context preemption and GPU watchdog checks.
9179 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:439180}
9181
[email protected]f598f422012-12-07 08:30:039182bool GLES2DecoderImpl::ValidateTexSubImage2D(
9183 error::Error* error,
9184 const char* function_name,
9185 GLenum target,
9186 GLint level,
9187 GLint xoffset,
9188 GLint yoffset,
9189 GLsizei width,
9190 GLsizei height,
9191 GLenum format,
9192 GLenum type,
9193 const void * data) {
9194 (*error) = error::kNoError;
9195 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:519196 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:039197 return false;
9198 }
9199 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:519200 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:039201 return false;
9202 }
9203 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:519204 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:039205 return false;
9206 }
[email protected]c986af502013-08-14 01:04:449207 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9208 &state_, target);
[email protected]370eaf12013-05-18 09:19:499209 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519210 LOCAL_SET_GL_ERROR(
9211 GL_INVALID_OPERATION,
9212 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:039213 return false;
[email protected]cadde4a2010-07-31 17:10:439214 }
[email protected]370eaf12013-05-18 09:19:499215 Texture* texture = texture_ref->texture();
[email protected]df6cf1ad2011-01-29 01:20:529216 GLenum current_type = 0;
9217 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:079218 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:519219 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:039220 GL_INVALID_OPERATION, function_name, "level does not exist.");
9221 return false;
[email protected]df6cf1ad2011-01-29 01:20:529222 }
[email protected]17a961192014-02-14 15:20:529223 if (!texture_manager()->ValidateTextureParameters(state_.GetErrorState(),
9224 function_name, format, type, internal_format, level)) {
[email protected]f598f422012-12-07 08:30:039225 return false;
[email protected]df6cf1ad2011-01-29 01:20:529226 }
9227 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:519228 LOCAL_SET_GL_ERROR(
9229 GL_INVALID_OPERATION,
9230 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:039231 return false;
[email protected]df6cf1ad2011-01-29 01:20:529232 }
[email protected]85a4ac22013-05-31 01:58:479233 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:519234 LOCAL_SET_GL_ERROR(
9235 GL_INVALID_OPERATION,
9236 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:599237 return false;
9238 }
[email protected]02965c22013-03-09 02:40:079239 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:529240 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:519241 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:039242 return false;
[email protected]cadde4a2010-07-31 17:10:439243 }
[email protected]81375742012-06-08 00:04:009244 if ((GLES2Util::GetChannelsForFormat(format) &
9245 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:519246 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:009247 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:039248 function_name, "can not supply data for depth or stencil textures");
9249 return false;
[email protected]81375742012-06-08 00:04:009250 }
[email protected]f598f422012-12-07 08:30:039251 if (data == NULL) {
9252 (*error) = error::kOutOfBounds;
9253 return false;
9254 }
9255 return true;
9256}
[email protected]81375742012-06-08 00:04:009257
[email protected]f598f422012-12-07 08:30:039258error::Error GLES2DecoderImpl::DoTexSubImage2D(
9259 GLenum target,
9260 GLint level,
9261 GLint xoffset,
9262 GLint yoffset,
9263 GLsizei width,
9264 GLsizei height,
9265 GLenum format,
9266 GLenum type,
9267 const void * data) {
9268 error::Error error = error::kNoError;
9269 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
9270 xoffset, yoffset, width, height, format, type, data)) {
9271 return error;
9272 }
[email protected]c986af502013-08-14 01:04:449273 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9274 &state_, target);
[email protected]370eaf12013-05-18 09:19:499275 Texture* texture = texture_ref->texture();
[email protected]4502e6492011-12-14 19:39:159276 GLsizei tex_width = 0;
9277 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:079278 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:159279 DCHECK(ok);
9280 if (xoffset != 0 || yoffset != 0 ||
9281 width != tex_width || height != tex_height) {
[email protected]370eaf12013-05-18 09:19:499282 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
9283 target, level)) {
[email protected]ab09b612013-03-11 22:11:519284 LOCAL_SET_GL_ERROR(
9285 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:039286 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:309287 }
[email protected]c986af502013-08-14 01:04:449288 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:159289 glTexSubImage2D(
9290 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:039291 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:209292 }
[email protected]4502e6492011-12-14 19:39:159293
[email protected]345ba902013-11-14 21:39:009294 if (!texture_state_.texsubimage2d_faster_than_teximage2d &&
[email protected]c986af502013-08-14 01:04:449295 !texture->IsImmutable()) {
9296 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]d8e6c9242014-02-20 16:56:259297 GLenum internal_format;
9298 GLenum tex_type;
9299 texture->GetLevelType(target, level, &tex_type, &internal_format);
9300 // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need
9301 // to look it up.
[email protected]8f1d2aa2013-05-10 23:45:389302 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:259303 target, level, internal_format, width, height, 0, format, type, data);
[email protected]4502e6492011-12-14 19:39:159304 } else {
[email protected]c986af502013-08-14 01:04:449305 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:159306 glTexSubImage2D(
9307 target, level, xoffset, yoffset, width, height, format, type, data);
9308 }
[email protected]370eaf12013-05-18 09:19:499309 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
vmiura8266ca72014-09-09 21:37:009310
9311 // This may be a slow command. Exit command processing to allow for
9312 // context preemption and GPU watchdog checks.
9313 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:039314 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:439315}
9316
vmiuracd108592014-09-08 14:36:349317error::Error GLES2DecoderImpl::HandleTexSubImage2D(uint32 immediate_data_size,
9318 const void* cmd_data) {
9319 const gles2::cmds::TexSubImage2D& c =
9320 *static_cast<const gles2::cmds::TexSubImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:139321 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage2D",
9322 "width", c.width, "height", c.height);
[email protected]b493ee622011-04-13 23:52:009323 GLboolean internal = static_cast<GLboolean>(c.internal);
[email protected]c986af502013-08-14 01:04:449324 if (internal == GL_TRUE && texture_state_.tex_image_2d_failed)
[email protected]b493ee622011-04-13 23:52:009325 return error::kNoError;
9326
9327 GLenum target = static_cast<GLenum>(c.target);
9328 GLint level = static_cast<GLint>(c.level);
9329 GLint xoffset = static_cast<GLint>(c.xoffset);
9330 GLint yoffset = static_cast<GLint>(c.yoffset);
9331 GLsizei width = static_cast<GLsizei>(c.width);
9332 GLsizei height = static_cast<GLsizei>(c.height);
9333 GLenum format = static_cast<GLenum>(c.format);
9334 GLenum type = static_cast<GLenum>(c.type);
9335 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:349336 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:429337 width, height, 1, format, type, state_.unpack_alignment, &data_size,
[email protected]e259eb412012-10-13 05:47:249338 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:009339 return error::kOutOfBounds;
9340 }
9341 const void* pixels = GetSharedMemoryAs<const void*>(
9342 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:039343 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:009344 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:009345}
9346
zmobcadd6592015-01-08 20:13:429347// TODO(zmo): Remove the below stub once we add the real function binding.
9348// Currently it's missing due to a gmock limitation.
9349static void glTexSubImage3D(
9350 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
9351 GLsizei height, GLsizei width, GLsizei depth, GLenum format, GLenum type,
9352 const void* pixels) {
9353 NOTIMPLEMENTED();
9354}
9355
9356error::Error GLES2DecoderImpl::HandleTexSubImage3D(uint32 immediate_data_size,
9357 const void* cmd_data) {
9358 // TODO(zmo): Unsafe ES3 API.
9359 if (!unsafe_es3_apis_enabled())
9360 return error::kUnknownCommand;
9361
9362 const gles2::cmds::TexSubImage3D& c =
9363 *static_cast<const gles2::cmds::TexSubImage3D*>(cmd_data);
9364 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage3D",
9365 "widthXheight", c.width * c.height, "depth", c.depth);
9366 GLenum target = static_cast<GLenum>(c.target);
9367 GLint level = static_cast<GLint>(c.level);
9368 GLint xoffset = static_cast<GLint>(c.xoffset);
9369 GLint yoffset = static_cast<GLint>(c.yoffset);
9370 GLint zoffset = static_cast<GLint>(c.zoffset);
9371 GLsizei width = static_cast<GLsizei>(c.width);
9372 GLsizei height = static_cast<GLsizei>(c.height);
9373 GLsizei depth = static_cast<GLsizei>(c.depth);
9374 GLenum format = static_cast<GLenum>(c.format);
9375 GLenum type = static_cast<GLenum>(c.type);
9376 uint32 data_size;
9377 if (!GLES2Util::ComputeImageDataSizes(
9378 width, height, depth, format, type, state_.unpack_alignment, &data_size,
9379 NULL, NULL)) {
9380 return error::kOutOfBounds;
9381 }
9382 const void* pixels = GetSharedMemoryAs<const void*>(
9383 c.pixels_shm_id, c.pixels_shm_offset, data_size);
9384 glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height,
9385 depth, format, type, pixels);
9386 return error::kNoError;
9387}
9388
[email protected]f7a64ee2010-02-01 22:24:149389error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
vmiuracd108592014-09-08 14:36:349390 uint32 immediate_data_size,
9391 const void* cmd_data) {
9392 const gles2::cmds::GetVertexAttribPointerv& c =
9393 *static_cast<const gles2::cmds::GetVertexAttribPointerv*>(cmd_data);
[email protected]8bf5a3e2010-01-29 04:21:369394 GLuint index = static_cast<GLuint>(c.index);
9395 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:359396 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:259397 Result* result = GetSharedMemoryAs<Result*>(
9398 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:369399 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:149400 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:369401 }
[email protected]07d0cc82010-02-17 04:51:409402 // Check that the client initialized the result.
9403 if (result->size != 0) {
9404 return error::kInvalidArguments;
9405 }
[email protected]9438b012010-06-15 22:55:059406 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:519407 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9408 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:149409 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369410 }
[email protected]3916c97e2010-02-25 03:20:509411 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:519412 LOCAL_SET_GL_ERROR(
9413 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:149414 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369415 }
[email protected]0bfd9882010-02-05 23:02:259416 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:089417 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:359418 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:149419 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329420}
9421
[email protected]f7b85372010-02-03 01:11:379422bool GLES2DecoderImpl::GetUniformSetup(
[email protected]df37b9932013-03-08 05:21:429423 GLuint program_id, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:379424 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:129425 error::Error* error, GLint* real_location,
9426 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:109427 DCHECK(error);
9428 DCHECK(service_id);
9429 DCHECK(result_pointer);
9430 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:129431 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:379432 *error = error::kNoError;
9433 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:259434 SizedResult<GLint>* result;
9435 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9436 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
9437 if (!result) {
[email protected]f7b85372010-02-03 01:11:379438 *error = error::kOutOfBounds;
9439 return false;
9440 }
[email protected]0bfd9882010-02-05 23:02:259441 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:379442 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:259443 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:429444 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
9445 if (!program) {
[email protected]ae51d192010-04-27 00:48:039446 return false;
9447 }
[email protected]df37b9932013-03-08 05:21:429448 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:379449 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:519450 LOCAL_SET_GL_ERROR(
9451 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:379452 return false;
9453 }
[email protected]df37b9932013-03-08 05:21:429454 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:369455 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:359456 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:429457 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:129458 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:369459 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:379460 // No such location.
[email protected]ab09b612013-03-11 22:11:519461 LOCAL_SET_GL_ERROR(
9462 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:379463 return false;
9464 }
[email protected]43c2f1f2011-03-25 18:35:369465 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:509466 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:379467 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:519468 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:379469 return false;
9470 }
[email protected]0bfd9882010-02-05 23:02:259471 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9472 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
9473 if (!result) {
[email protected]f7b85372010-02-03 01:11:379474 *error = error::kOutOfBounds;
9475 return false;
9476 }
[email protected]0bfd9882010-02-05 23:02:259477 result->size = size;
[email protected]939e7362010-05-13 20:49:109478 *result_type = type;
[email protected]f7b85372010-02-03 01:11:379479 return true;
9480}
9481
vmiuracd108592014-09-08 14:36:349482error::Error GLES2DecoderImpl::HandleGetUniformiv(uint32 immediate_data_size,
9483 const void* cmd_data) {
9484 const gles2::cmds::GetUniformiv& c =
9485 *static_cast<const gles2::cmds::GetUniformiv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379486 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339487 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379488 GLuint service_id;
[email protected]939e7362010-05-13 20:49:109489 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:129490 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379491 Error error;
[email protected]0bfd9882010-02-05 23:02:259492 void* result;
[email protected]f7b85372010-02-03 01:11:379493 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:129494 program, fake_location, c.params_shm_id, c.params_shm_offset,
9495 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:259496 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:129497 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:359498 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:379499 }
9500 return error;
[email protected]96449d2c2009-11-25 00:01:329501}
9502
vmiuracd108592014-09-08 14:36:349503error::Error GLES2DecoderImpl::HandleGetUniformfv(uint32 immediate_data_size,
9504 const void* cmd_data) {
9505 const gles2::cmds::GetUniformfv& c =
9506 *static_cast<const gles2::cmds::GetUniformfv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379507 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339508 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379509 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:129510 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379511 Error error;
[email protected]ed9f9cd2013-02-27 21:12:359512 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:109513 Result* result;
9514 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:379515 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:129516 program, fake_location, c.params_shm_id, c.params_shm_offset,
9517 &error, &real_location, &service_id,
9518 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:109519 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
9520 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
9521 GLsizei num_values = result->GetNumResults();
[email protected]40d90a22013-04-09 03:39:559522 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:129523 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:109524 GLfloat* dst = result->GetData();
9525 for (GLsizei ii = 0; ii < num_values; ++ii) {
9526 dst[ii] = (temp[ii] != 0);
9527 }
9528 } else {
[email protected]1b0a6752012-02-22 03:44:129529 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:109530 }
[email protected]f7b85372010-02-03 01:11:379531 }
9532 return error;
[email protected]96449d2c2009-11-25 00:01:329533}
9534
[email protected]f7a64ee2010-02-01 22:24:149535error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
vmiuracd108592014-09-08 14:36:349536 uint32 immediate_data_size,
9537 const void* cmd_data) {
9538 const gles2::cmds::GetShaderPrecisionFormat& c =
9539 *static_cast<const gles2::cmds::GetShaderPrecisionFormat*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259540 GLenum shader_type = static_cast<GLenum>(c.shadertype);
9541 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:359542 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:259543 Result* result = GetSharedMemoryAs<Result*>(
9544 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9545 if (!result) {
9546 return error::kOutOfBounds;
9547 }
[email protected]07d0cc82010-02-17 04:51:409548 // Check that the client initialized the result.
9549 if (result->success != 0) {
9550 return error::kInvalidArguments;
9551 }
[email protected]9438b012010-06-15 22:55:059552 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:519553 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539554 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:299555 return error::kNoError;
9556 }
[email protected]9438b012010-06-15 22:55:059557 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:519558 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539559 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:299560 return error::kNoError;
9561 }
9562
9563 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:409564
[email protected]46c86752013-05-21 05:08:399565 GLint range[2] = { 0, 0 };
[email protected]d8bc3ec2013-03-07 06:28:409566 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:219567 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:409568
9569 result->min_range = range[0];
9570 result->max_range = range[1];
9571 result->precision = precision;
9572
[email protected]f7a64ee2010-02-01 22:24:149573 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329574}
9575
[email protected]f7a64ee2010-02-01 22:24:149576error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
vmiuracd108592014-09-08 14:36:349577 uint32 immediate_data_size,
9578 const void* cmd_data) {
9579 const gles2::cmds::GetAttachedShaders& c =
9580 *static_cast<const gles2::cmds::GetAttachedShaders*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259581 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:429582 GLuint program_id = static_cast<GLuint>(c.program);
9583 Program* program = GetProgramInfoNotShader(
9584 program_id, "glGetAttachedShaders");
9585 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259586 return error::kNoError;
9587 }
[email protected]ed9f9cd2013-02-27 21:12:359588 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:259589 uint32 max_count = Result::ComputeMaxResults(result_size);
9590 Result* result = GetSharedMemoryAs<Result*>(
9591 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
9592 if (!result) {
9593 return error::kOutOfBounds;
9594 }
[email protected]07d0cc82010-02-17 04:51:409595 // Check that the client initialized the result.
9596 if (result->size != 0) {
9597 return error::kInvalidArguments;
9598 }
[email protected]0bfd9882010-02-05 23:02:259599 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:039600 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:429601 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:259602 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:039603 if (!shader_manager()->GetClientId(result->GetData()[ii],
9604 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:259605 NOTREACHED();
9606 return error::kGenericError;
9607 }
9608 }
9609 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:149610 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329611}
9612
[email protected]f7a64ee2010-02-01 22:24:149613error::Error GLES2DecoderImpl::HandleGetActiveUniform(
vmiuracd108592014-09-08 14:36:349614 uint32 immediate_data_size,
9615 const void* cmd_data) {
9616 const gles2::cmds::GetActiveUniform& c =
9617 *static_cast<const gles2::cmds::GetActiveUniform*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429618 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:259619 GLuint index = c.index;
9620 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:359621 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:259622 Result* result = GetSharedMemoryAs<Result*>(
9623 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9624 if (!result) {
9625 return error::kOutOfBounds;
9626 }
[email protected]07d0cc82010-02-17 04:51:409627 // Check that the client initialized the result.
9628 if (result->success != 0) {
9629 return error::kInvalidArguments;
9630 }
[email protected]df37b9932013-03-08 05:21:429631 Program* program = GetProgramInfoNotShader(
9632 program_id, "glGetActiveUniform");
9633 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259634 return error::kNoError;
9635 }
[email protected]ed9f9cd2013-02-27 21:12:359636 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:429637 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:259638 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:519639 LOCAL_SET_GL_ERROR(
9640 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:259641 return error::kNoError;
9642 }
9643 result->success = 1; // true.
9644 result->size = uniform_info->size;
9645 result->type = uniform_info->type;
9646 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:299647 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:149648 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329649}
9650
vmiuracd108592014-09-08 14:36:349651error::Error GLES2DecoderImpl::HandleGetActiveAttrib(uint32 immediate_data_size,
9652 const void* cmd_data) {
9653 const gles2::cmds::GetActiveAttrib& c =
9654 *static_cast<const gles2::cmds::GetActiveAttrib*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429655 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:259656 GLuint index = c.index;
9657 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:359658 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:259659 Result* result = GetSharedMemoryAs<Result*>(
9660 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9661 if (!result) {
9662 return error::kOutOfBounds;
9663 }
[email protected]07d0cc82010-02-17 04:51:409664 // Check that the client initialized the result.
9665 if (result->success != 0) {
9666 return error::kInvalidArguments;
9667 }
[email protected]df37b9932013-03-08 05:21:429668 Program* program = GetProgramInfoNotShader(
9669 program_id, "glGetActiveAttrib");
9670 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259671 return error::kNoError;
9672 }
[email protected]ed9f9cd2013-02-27 21:12:359673 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:429674 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:259675 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:519676 LOCAL_SET_GL_ERROR(
9677 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:259678 return error::kNoError;
9679 }
9680 result->success = 1; // true.
9681 result->size = attrib_info->size;
9682 result->type = attrib_info->type;
9683 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:299684 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:149685 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329686}
9687
vmiuracd108592014-09-08 14:36:349688error::Error GLES2DecoderImpl::HandleShaderBinary(uint32 immediate_data_size,
9689 const void* cmd_data) {
[email protected]b273e432010-04-12 17:23:589690#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:519691 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:589692 return error::kNoError;
9693#else
9694 GLsizei n = static_cast<GLsizei>(c.n);
9695 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:519696 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:589697 return error::kNoError;
9698 }
9699 GLsizei length = static_cast<GLsizei>(c.length);
9700 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:519701 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:589702 return error::kNoError;
9703 }
9704 uint32 data_size;
9705 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
9706 return error::kOutOfBounds;
9707 }
9708 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
9709 c.shaders_shm_id, c.shaders_shm_offset, data_size);
9710 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
9711 const void* binary = GetSharedMemoryAs<const void*>(
9712 c.binary_shm_id, c.binary_shm_offset, length);
9713 if (shaders == NULL || binary == NULL) {
9714 return error::kOutOfBounds;
9715 }
[email protected]0782b14b2014-05-24 13:04:169716 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]b273e432010-04-12 17:23:589717 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:429718 Shader* shader = GetShader(shaders[ii]);
9719 if (!shader) {
[email protected]ab09b612013-03-11 22:11:519720 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:589721 return error::kNoError;
9722 }
[email protected]df37b9932013-03-08 05:21:429723 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:589724 }
9725 // TODO(gman): call glShaderBinary
9726 return error::kNoError;
9727#endif
9728}
9729
[email protected]6d792ee12013-05-15 00:40:569730void GLES2DecoderImpl::DoSwapBuffers() {
[email protected]64ace852011-05-19 21:49:499731 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:089732
[email protected]64ace852011-05-19 21:49:499733 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:429734 // TRACE_EVENT for gpu tests:
9735 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:429736 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:429737 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
9738 "width", (is_offscreen ? offscreen_size_.width() :
9739 surface_->GetSize().width()));
[email protected]6d792ee12013-05-15 00:40:569740 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
[email protected]64ace852011-05-19 21:49:499741 "offscreen", is_offscreen,
9742 "frame", this_frame_number);
[email protected]b2e92592014-01-10 15:47:159743 {
[email protected]a36ed4832014-04-24 16:40:279744 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
[email protected]b2e92592014-01-10 15:47:159745 }
9746
dyenb547eff62015-01-17 00:14:569747 ScopedGPUTrace scoped_gpu_trace(gpu_tracer_.get(), kTraceDecoder,
9748 "gpu_toplevel", "SwapBuffer");
9749
[email protected]8f9b8dd2013-09-12 18:05:139750 bool is_tracing;
9751 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
9752 &is_tracing);
9753 if (is_tracing) {
9754 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
9755 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
9756 is_offscreen ? offscreen_size_ : surface_->GetSize());
9757 }
9758
[email protected]6217d392010-03-25 22:08:359759 // If offscreen then don't actually SwapBuffers to the display. Just copy
9760 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:499761 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:319762 TRACE_EVENT2("gpu", "Offscreen",
9763 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:539764 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
9765 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
9766 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
9767 // fix this.
[email protected]62e155e2012-10-23 22:43:159768 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:539769 offscreen_saved_frame_buffer_->Create();
9770 glFinish();
9771 }
9772
9773 // Allocate the offscreen saved color texture.
9774 DCHECK(offscreen_saved_color_format_);
9775 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:099776 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:539777
9778 offscreen_saved_frame_buffer_->AttachRenderTexture(
9779 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:059780 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
9781 if (offscreen_saved_frame_buffer_->CheckStatus() !=
9782 GL_FRAMEBUFFER_COMPLETE) {
9783 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
9784 << "because offscreen saved FBO was incomplete.";
[email protected]6d792ee12013-05-15 00:40:569785 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
9786 return;
[email protected]f0cfe752013-01-14 01:09:059787 }
[email protected]1fb8c482011-08-31 01:01:539788
[email protected]f0cfe752013-01-14 01:09:059789 // Clear the offscreen color texture.
9790 // TODO(piman): Is this still necessary?
9791 {
9792 ScopedFrameBufferBinder binder(this,
9793 offscreen_saved_frame_buffer_->id());
9794 glClearColor(0, 0, 0, 0);
[email protected]454157e2014-05-03 02:49:459795 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
9796 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f0cfe752013-01-14 01:09:059797 glClear(GL_COLOR_BUFFER_BIT);
9798 RestoreClearState();
9799 }
[email protected]1fb8c482011-08-31 01:01:539800 }
9801
9802 UpdateParentTextureInfo();
9803 }
9804
[email protected]f0cfe752013-01-14 01:09:059805 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
[email protected]6d792ee12013-05-15 00:40:569806 return;
[email protected]ab09b612013-03-11 22:11:519807 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:309808 "GLES2DecoderImpl::DoSwapBuffers", GetErrorState());
[email protected]6217d392010-03-25 22:08:359809
[email protected]34ff8b0c2010-10-01 20:06:029810 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:139811 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:279812 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]b86b14982010-10-11 18:45:489813 } else {
[email protected]069944672012-04-25 20:52:239814 ScopedFrameBufferBinder binder(this,
9815 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:139816
[email protected]069944672012-04-25 20:52:239817 if (offscreen_target_buffer_preserved_) {
9818 // Copy the target frame buffer to the saved offscreen texture.
9819 offscreen_saved_color_texture_->Copy(
9820 offscreen_saved_color_texture_->size(),
9821 offscreen_saved_color_format_);
9822 } else {
9823 // Flip the textures in the parent context via the texture manager.
9824 if (!!offscreen_saved_color_texture_info_.get())
[email protected]370eaf12013-05-18 09:19:499825 offscreen_saved_color_texture_info_->texture()->
[email protected]069944672012-04-25 20:52:239826 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:569827
[email protected]069944672012-04-25 20:52:239828 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
9829 offscreen_target_frame_buffer_->AttachRenderTexture(
9830 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:489831 }
[email protected]069944672012-04-25 20:52:239832
9833 // Ensure the side effects of the copy are visible to the parent
9834 // context. There is no need to do this for ANGLE because it uses a
9835 // single D3D device for all contexts.
zmo68fcdc62014-12-05 21:51:499836 if (!feature_info_->gl_version_info().is_angle)
[email protected]069944672012-04-25 20:52:239837 glFlush();
[email protected]0c8c9d22010-06-25 17:36:399838 }
[email protected]6217d392010-03-25 22:08:359839 } else {
[email protected]f62a5ab2011-05-23 20:34:159840 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:019841 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]6d792ee12013-05-15 00:40:569842 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]d0498742010-09-20 20:27:019843 }
[email protected]6217d392010-03-25 22:08:359844 }
vmiura8266ca72014-09-09 21:37:009845
9846 // This may be a slow command. Exit command processing to allow for
9847 // context preemption and GPU watchdog checks.
9848 ExitCommandProcessingEarly();
[email protected]6217d392010-03-25 22:08:359849}
9850
bajones2345c1f2014-12-09 04:45:519851void GLES2DecoderImpl::DoSwapInterval(int interval)
9852{
9853 context_->SetSwapInterval(interval);
9854}
9855
[email protected]d4239852011-08-12 04:51:229856error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
vmiuracd108592014-09-08 14:36:349857 uint32 immediate_data_size,
9858 const void* cmd_data) {
9859 const gles2::cmds::EnableFeatureCHROMIUM& c =
9860 *static_cast<const gles2::cmds::EnableFeatureCHROMIUM*>(cmd_data);
[email protected]b1d2dcb2010-05-17 19:24:189861 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289862 if (!bucket || bucket->size() == 0) {
9863 return error::kInvalidArguments;
9864 }
[email protected]ed9f9cd2013-02-27 21:12:359865 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:189866 Result* result = GetSharedMemoryAs<Result*>(
9867 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9868 if (!result) {
9869 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:109870 }
[email protected]b1d2dcb2010-05-17 19:24:189871 // Check that the client initialized the result.
9872 if (*result != 0) {
9873 return error::kInvalidArguments;
9874 }
9875 std::string feature_str;
9876 if (!bucket->GetAsString(&feature_str)) {
9877 return error::kInvalidArguments;
9878 }
9879
9880 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:229881 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:189882 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:229883 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
penghuang0140c182015-01-12 23:20:129884 buffer_manager()->set_allow_fixed_attribs(true);
[email protected]8fbedc02010-11-18 18:43:409885 // TODO(gman): decide how to remove the need for this const_cast.
9886 // I could make validators_ non const but that seems bad as this is the only
9887 // place it is needed. I could make some special friend class of validators
9888 // just to allow this to set them. That seems silly. I could refactor this
9889 // code to use the extension mechanism or the initialization attributes to
9890 // turn this feature on. Given that the only real point of this is to make
9891 // the conformance tests pass and given that there is lots of real work that
9892 // needs to be done it seems like refactoring for one to one of those
9893 // methods is a very low priority.
9894 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:049895 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
9896 force_webgl_glsl_validation_ = true;
9897 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:189898 } else {
9899 return error::kNoError;
9900 }
9901
9902 *result = 1; // true.
9903 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:109904}
9905
[email protected]c2f8c8402010-12-06 18:07:249906error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
9907 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:349908 const void* cmd_data) {
9909 const gles2::cmds::GetRequestableExtensionsCHROMIUM& c =
9910 *static_cast<const gles2::cmds::GetRequestableExtensionsCHROMIUM*>(
9911 cmd_data);
[email protected]c2f8c8402010-12-06 18:07:249912 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:359913 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]956aec52013-09-05 15:41:199914 info->Initialize(disallowed_features_);
[email protected]c2f8c8402010-12-06 18:07:249915 bucket->SetFromString(info->extensions().c_str());
9916 return error::kNoError;
9917}
9918
9919error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
vmiuracd108592014-09-08 14:36:349920 uint32 immediate_data_size,
9921 const void* cmd_data) {
9922 const gles2::cmds::RequestExtensionCHROMIUM& c =
9923 *static_cast<const gles2::cmds::RequestExtensionCHROMIUM*>(cmd_data);
[email protected]c2f8c8402010-12-06 18:07:249924 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289925 if (!bucket || bucket->size() == 0) {
9926 return error::kInvalidArguments;
9927 }
[email protected]c2f8c8402010-12-06 18:07:249928 std::string feature_str;
9929 if (!bucket->GetAsString(&feature_str)) {
9930 return error::kInvalidArguments;
9931 }
9932
[email protected]4b7eba92013-01-08 02:23:569933 bool desire_webgl_glsl_validation =
9934 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
9935 bool desire_standard_derivatives = false;
[email protected]70dc60932013-06-04 03:33:499936 bool desire_frag_depth = false;
[email protected]aff39ac82013-06-08 04:53:139937 bool desire_draw_buffers = false;
[email protected]93c2fd82014-04-16 02:46:069938 bool desire_shader_texture_lod = false;
[email protected]4b7eba92013-01-08 02:23:569939 if (force_webgl_glsl_validation_) {
9940 desire_standard_derivatives =
9941 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]70dc60932013-06-04 03:33:499942 desire_frag_depth =
9943 feature_str.find("GL_EXT_frag_depth") != std::string::npos;
[email protected]aff39ac82013-06-08 04:53:139944 desire_draw_buffers =
9945 feature_str.find("GL_EXT_draw_buffers") != std::string::npos;
[email protected]93c2fd82014-04-16 02:46:069946 desire_shader_texture_lod =
9947 feature_str.find("GL_EXT_shader_texture_lod") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:049948 }
9949
[email protected]4b7eba92013-01-08 02:23:569950 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
[email protected]70dc60932013-06-04 03:33:499951 desire_standard_derivatives != derivatives_explicitly_enabled_ ||
[email protected]aff39ac82013-06-08 04:53:139952 desire_frag_depth != frag_depth_explicitly_enabled_ ||
9953 desire_draw_buffers != draw_buffers_explicitly_enabled_) {
[email protected]70dc60932013-06-04 03:33:499954 force_webgl_glsl_validation_ |= desire_webgl_glsl_validation;
9955 derivatives_explicitly_enabled_ |= desire_standard_derivatives;
9956 frag_depth_explicitly_enabled_ |= desire_frag_depth;
[email protected]aff39ac82013-06-08 04:53:139957 draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
[email protected]93c2fd82014-04-16 02:46:069958 shader_texture_lod_explicitly_enabled_ |= desire_shader_texture_lod;
[email protected]c2f8c8402010-12-06 18:07:249959 InitializeShaderTranslator();
9960 }
9961
[email protected]302ce6d2011-07-07 23:28:119962 UpdateCapabilities();
9963
[email protected]c2f8c8402010-12-06 18:07:249964 return error::kNoError;
9965}
9966
[email protected]2318d342011-07-11 22:27:429967error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
vmiuracd108592014-09-08 14:36:349968 uint32 immediate_data_size,
9969 const void* cmd_data) {
9970 const gles2::cmds::GetProgramInfoCHROMIUM& c =
9971 *static_cast<const gles2::cmds::GetProgramInfoCHROMIUM*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429972 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:429973 uint32 bucket_id = c.bucket_id;
9974 Bucket* bucket = CreateBucket(bucket_id);
9975 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:429976 Program* program = NULL;
9977 program = GetProgram(program_id);
9978 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:469979 return error::kNoError;
[email protected]2318d342011-07-11 22:27:429980 }
[email protected]df37b9932013-03-08 05:21:429981 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:429982 return error::kNoError;
9983}
9984
[email protected]38d139d2011-07-14 00:38:439985error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
9986 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:439987 case GL_NO_ERROR:
9988 // TODO(kbr): improve the precision of the error code in this case.
9989 // Consider delegating to context for error code if MakeCurrent fails.
9990 return error::kUnknown;
9991 case GL_GUILTY_CONTEXT_RESET_ARB:
9992 return error::kGuilty;
9993 case GL_INNOCENT_CONTEXT_RESET_ARB:
9994 return error::kInnocent;
9995 case GL_UNKNOWN_CONTEXT_RESET_ARB:
9996 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:439997 }
9998
9999 NOTREACHED();
10000 return error::kUnknown;
10001}
10002
jbauman7a059312014-10-16 19:30:5410003void GLES2DecoderImpl::MaybeExitOnContextLost() {
10004 // Some D3D drivers cannot recover from device lost in the GPU process
10005 // sandbox. Allow a new GPU process to launch.
10006 if (workarounds().exit_on_context_lost) {
10007 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
10008 << " a D3D device in the Chrome GPU process sandbox.";
10009#if defined(OS_WIN)
10010 base::win::SetShouldCrashOnProcessDetach(false);
10011#endif
10012 exit(0);
10013 }
10014}
10015
[email protected]38d139d2011-07-14 00:38:4310016bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:0910017 if (reset_status_ != GL_NO_ERROR) {
jbauman7a059312014-10-16 19:30:5410018 MaybeExitOnContextLost();
[email protected]c4485aad62012-12-17 10:19:0910019 return true;
10020 }
[email protected]706b69f2012-07-27 04:59:3010021 if (context_->WasAllocatedUsingRobustnessExtension()) {
10022 GLenum status = GL_NO_ERROR;
10023 if (has_robustness_extension_)
10024 status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:4310025 if (status != GL_NO_ERROR) {
10026 // The graphics card was reset. Signal a lost context to the application.
10027 reset_status_ = status;
[email protected]93a7d98f2013-07-11 00:04:2210028 reset_by_robustness_extension_ = true;
[email protected]38d139d2011-07-14 00:38:4310029 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:0910030 << " context lost via ARB/EXT_robustness. Reset status = "
10031 << GLES2Util::GetStringEnum(status);
jbauman7a059312014-10-16 19:30:5410032 MaybeExitOnContextLost();
[email protected]38d139d2011-07-14 00:38:4310033 return true;
10034 }
10035 }
10036 return false;
10037}
10038
[email protected]93a7d98f2013-07-11 00:04:2210039bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() {
10040 return WasContextLost() && reset_by_robustness_extension_;
10041}
10042
[email protected]c4485aad62012-12-17 10:19:0910043void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
10044 // Only loses the context once.
10045 if (reset_status_ != GL_NO_ERROR) {
10046 return;
10047 }
10048
oetuaho37cc50e2014-10-31 11:19:2010049 if (workarounds().use_virtualized_gl_contexts) {
10050 // If the context is virtual, the real context being guilty does not ensure
10051 // that the virtual context is guilty.
10052 if (reset_status == GL_GUILTY_CONTEXT_RESET_ARB) {
10053 reset_status = GL_UNKNOWN_CONTEXT_RESET_ARB;
10054 }
10055 } else if (reset_status == GL_UNKNOWN_CONTEXT_RESET_ARB &&
10056 has_robustness_extension_) {
10057 // If the reason for the call was a GL error, we can try to determine the
10058 // reset status more accurately.
10059 GLenum driver_status = glGetGraphicsResetStatusARB();
10060 if (driver_status == GL_GUILTY_CONTEXT_RESET_ARB ||
10061 driver_status == GL_INNOCENT_CONTEXT_RESET_ARB) {
10062 reset_status = driver_status;
10063 }
10064 }
10065
[email protected]c4485aad62012-12-17 10:19:0910066 // Marks this context as lost.
10067 reset_status_ = reset_status;
10068 current_decoder_error_ = error::kLostContext;
[email protected]c4485aad62012-12-17 10:19:0910069}
10070
[email protected]b096d032013-03-08 03:08:0110071error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:3410072 uint32 immediate_data_size,
10073 const void* cmd_data) {
[email protected]b096d032013-03-08 03:08:0110074 return error::kUnknownCommand;
10075}
10076
[email protected]840a7e462013-02-27 01:29:5110077error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:3410078 uint32 immediate_data_size,
10079 const void* cmd_data) {
10080 const gles2::cmds::WaitSyncPointCHROMIUM& c =
10081 *static_cast<const gles2::cmds::WaitSyncPointCHROMIUM*>(cmd_data);
sievers173a20d2014-10-22 18:19:3210082 uint32 sync_point = c.sync_point;
[email protected]840a7e462013-02-27 01:29:5110083 if (wait_sync_point_callback_.is_null())
10084 return error::kNoError;
10085
sievers173a20d2014-10-22 18:19:3210086 return wait_sync_point_callback_.Run(sync_point) ?
[email protected]840a7e462013-02-27 01:29:5110087 error::kNoError : error::kDeferCommandUntilLater;
10088}
10089
[email protected]5dfc457b2013-12-13 11:13:0710090error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM(
vmiuracd108592014-09-08 14:36:3410091 uint32 immediate_data_size,
10092 const void* cmd_data) {
[email protected]5dfc457b2013-12-13 11:13:0710093 if (surface_->DeferDraws())
10094 return error::kDeferCommandUntilLater;
10095 if (!surface_->SetBackbufferAllocation(false))
10096 return error::kLostContext;
10097 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
10098 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
10099 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
10100 return error::kNoError;
10101}
10102
[email protected]882ba1e22012-03-08 19:02:5310103bool GLES2DecoderImpl::GenQueriesEXTHelper(
10104 GLsizei n, const GLuint* client_ids) {
10105 for (GLsizei ii = 0; ii < n; ++ii) {
10106 if (query_manager_->GetQuery(client_ids[ii])) {
10107 return false;
10108 }
10109 }
[email protected]4eea7e62014-04-22 21:14:4310110 query_manager_->GenQueries(n, client_ids);
[email protected]882ba1e22012-03-08 19:02:5310111 return true;
10112}
10113
10114void GLES2DecoderImpl::DeleteQueriesEXTHelper(
10115 GLsizei n, const GLuint* client_ids) {
10116 for (GLsizei ii = 0; ii < n; ++ii) {
10117 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
10118 if (query && !query->IsDeleted()) {
[email protected]8ebd46c2014-01-08 12:06:1310119 ContextState::QueryMap::iterator it =
10120 state_.current_queries.find(query->target());
10121 if (it != state_.current_queries.end())
10122 state_.current_queries.erase(it);
10123
[email protected]c45f1972012-03-14 07:27:3610124 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:5310125 }
[email protected]4eea7e62014-04-22 21:14:4310126 query_manager_->RemoveQuery(client_ids[ii]);
[email protected]882ba1e22012-03-08 19:02:5310127 }
10128}
10129
revemancc241eb2014-11-11 03:30:3710130bool GLES2DecoderImpl::ProcessPendingQueries(bool did_finish) {
[email protected]22e3f552012-03-13 01:54:1910131 if (query_manager_.get() == NULL) {
10132 return false;
10133 }
revemancc241eb2014-11-11 03:30:3710134 if (!query_manager_->ProcessPendingQueries(did_finish)) {
[email protected]22e3f552012-03-13 01:54:1910135 current_decoder_error_ = error::kOutOfBounds;
10136 }
10137 return query_manager_->HavePendingQueries();
10138}
10139
[email protected]5a36dc132013-07-23 23:17:5510140// Note that if there are no pending readpixels right now,
10141// this function will call the callback immediately.
10142void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) {
10143 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) {
10144 pending_readpixel_fences_.back()->callbacks.push_back(callback);
10145 } else {
10146 callback.Run();
10147 }
10148}
10149
10150void GLES2DecoderImpl::ProcessPendingReadPixels() {
10151 while (!pending_readpixel_fences_.empty() &&
10152 pending_readpixel_fences_.front()->fence->HasCompleted()) {
10153 std::vector<base::Closure> callbacks =
10154 pending_readpixel_fences_.front()->callbacks;
10155 pending_readpixel_fences_.pop();
10156 for (size_t i = 0; i < callbacks.size(); i++) {
10157 callbacks[i].Run();
10158 }
10159 }
10160}
10161
[email protected]2b1767cf2013-03-16 09:25:0510162bool GLES2DecoderImpl::HasMoreIdleWork() {
[email protected]5a36dc132013-07-23 23:17:5510163 return !pending_readpixel_fences_.empty() ||
10164 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:0510165}
10166
10167void GLES2DecoderImpl::PerformIdleWork() {
[email protected]5a36dc132013-07-23 23:17:5510168 ProcessPendingReadPixels();
[email protected]b68b100752013-06-05 08:34:4810169 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
[email protected]2b1767cf2013-03-16 09:25:0510170 return;
[email protected]b68b100752013-06-05 08:34:4810171 async_pixel_transfer_manager_->ProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:0510172 ProcessFinishedAsyncTransfers();
10173}
10174
vmiuracd108592014-09-08 14:36:3410175error::Error GLES2DecoderImpl::HandleBeginQueryEXT(uint32 immediate_data_size,
10176 const void* cmd_data) {
10177 const gles2::cmds::BeginQueryEXT& c =
10178 *static_cast<const gles2::cmds::BeginQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:5310179 GLenum target = static_cast<GLenum>(c.target);
10180 GLuint client_id = static_cast<GLuint>(c.id);
10181 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
10182 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
10183
[email protected]c45f1972012-03-14 07:27:3610184 switch (target) {
10185 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:5510186 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]5537605d2013-08-27 05:22:3110187 case GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM:
10188 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:0010189 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:3610190 break;
[email protected]6a25ae422014-04-17 23:48:2710191 case GL_COMMANDS_COMPLETED_CHROMIUM:
10192 if (!features().chromium_sync_query) {
10193 LOCAL_SET_GL_ERROR(
10194 GL_INVALID_OPERATION, "glBeginQueryEXT",
10195 "not enabled for commands completed queries");
10196 return error::kNoError;
10197 }
10198 break;
[email protected]c45f1972012-03-14 07:27:3610199 default:
[email protected]62e155e2012-10-23 22:43:1510200 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:5110201 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:0010202 GL_INVALID_OPERATION, "glBeginQueryEXT",
10203 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:3610204 return error::kNoError;
10205 }
10206 break;
[email protected]882ba1e22012-03-08 19:02:5310207 }
10208
[email protected]8ebd46c2014-01-08 12:06:1310209 if (state_.current_queries.find(target) != state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:5110210 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310211 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:5310212 return error::kNoError;
10213 }
10214
10215 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:5110216 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:5310217 return error::kNoError;
10218 }
10219
10220 QueryManager::Query* query = query_manager_->GetQuery(client_id);
10221 if (!query) {
[email protected]4eea7e62014-04-22 21:14:4310222 if (!query_manager_->IsValidQuery(client_id)) {
10223 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10224 "glBeginQueryEXT",
10225 "id not made by glGenQueriesEXT");
10226 return error::kNoError;
10227 }
[email protected]c45f1972012-03-14 07:27:3610228 query = query_manager_->CreateQuery(
10229 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:5310230 }
10231
[email protected]c45f1972012-03-14 07:27:3610232 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:5110233 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310234 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:5310235 return error::kNoError;
10236 } else if (query->shm_id() != sync_shm_id ||
10237 query->shm_offset() != sync_shm_offset) {
10238 DLOG(ERROR) << "Shared memory used by query not the same as before";
10239 return error::kInvalidArguments;
10240 }
10241
[email protected]c45f1972012-03-14 07:27:3610242 if (!query_manager_->BeginQuery(query)) {
10243 return error::kOutOfBounds;
10244 }
[email protected]882ba1e22012-03-08 19:02:5310245
[email protected]8ebd46c2014-01-08 12:06:1310246 state_.current_queries[target] = query;
[email protected]882ba1e22012-03-08 19:02:5310247 return error::kNoError;
10248}
10249
vmiuracd108592014-09-08 14:36:3410250error::Error GLES2DecoderImpl::HandleEndQueryEXT(uint32 immediate_data_size,
10251 const void* cmd_data) {
10252 const gles2::cmds::EndQueryEXT& c =
10253 *static_cast<const gles2::cmds::EndQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:5310254 GLenum target = static_cast<GLenum>(c.target);
10255 uint32 submit_count = static_cast<GLuint>(c.submit_count);
[email protected]8ebd46c2014-01-08 12:06:1310256 ContextState::QueryMap::iterator it = state_.current_queries.find(target);
[email protected]882ba1e22012-03-08 19:02:5310257
[email protected]8ebd46c2014-01-08 12:06:1310258 if (it == state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:5110259 LOCAL_SET_GL_ERROR(
10260 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:5310261 return error::kNoError;
10262 }
[email protected]882ba1e22012-03-08 19:02:5310263
[email protected]8ebd46c2014-01-08 12:06:1310264 QueryManager::Query* query = it->second.get();
10265 if (!query_manager_->EndQuery(query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:3610266 return error::kOutOfBounds;
10267 }
10268
[email protected]fe8d73c2013-02-16 22:37:3210269 query_manager_->ProcessPendingTransferQueries();
10270
[email protected]8ebd46c2014-01-08 12:06:1310271 state_.current_queries.erase(it);
[email protected]882ba1e22012-03-08 19:02:5310272 return error::kNoError;
10273}
10274
[email protected]944b62f32012-09-27 02:20:4610275bool GLES2DecoderImpl::GenVertexArraysOESHelper(
10276 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:4610277 for (GLsizei ii = 0; ii < n; ++ii) {
10278 if (GetVertexAttribManager(client_ids[ii])) {
10279 return false;
10280 }
10281 }
[email protected]ab4fd7282012-10-12 16:25:5710282
[email protected]62e155e2012-10-23 22:43:1510283 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:5710284 // Emulated VAO
10285 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:4810286 CreateVertexAttribManager(client_ids[ii], 0, true);
[email protected]ab4fd7282012-10-12 16:25:5710287 }
10288 } else {
[email protected]40d90a22013-04-09 03:39:5510289 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:5710290
10291 glGenVertexArraysOES(n, service_ids.get());
10292 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:4810293 CreateVertexAttribManager(client_ids[ii], service_ids[ii], true);
[email protected]ab4fd7282012-10-12 16:25:5710294 }
[email protected]944b62f32012-09-27 02:20:4610295 }
[email protected]ab4fd7282012-10-12 16:25:5710296
[email protected]944b62f32012-09-27 02:20:4610297 return true;
10298}
10299
10300void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
10301 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:4610302 for (GLsizei ii = 0; ii < n; ++ii) {
10303 VertexAttribManager* vao =
10304 GetVertexAttribManager(client_ids[ii]);
10305 if (vao && !vao->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:1110306 if (state_.vertex_attrib_manager.get() == vao) {
[email protected]242c9822014-04-15 21:36:1110307 DoBindVertexArrayOES(0);
[email protected]944b62f32012-09-27 02:20:4610308 }
10309 RemoveVertexAttribManager(client_ids[ii]);
10310 }
10311 }
10312}
10313
10314void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:4610315 VertexAttribManager* vao = NULL;
[email protected]944b62f32012-09-27 02:20:4610316 if (client_id != 0) {
10317 vao = GetVertexAttribManager(client_id);
10318 if (!vao) {
10319 // Unlike most Bind* methods, the spec explicitly states that VertexArray
10320 // only allows names that have been previously generated. As such, we do
10321 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:5110322 LOCAL_SET_GL_ERROR(
10323 GL_INVALID_OPERATION,
10324 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:4610325 current_decoder_error_ = error::kNoError;
10326 return;
[email protected]944b62f32012-09-27 02:20:4610327 }
[email protected]944b62f32012-09-27 02:20:4610328 } else {
[email protected]81f20a622014-04-18 01:54:5210329 vao = state_.default_vertex_attrib_manager.get();
[email protected]944b62f32012-09-27 02:20:4610330 }
10331
[email protected]ab4fd7282012-10-12 16:25:5710332 // Only set the VAO state if it's changed
[email protected]7cd76fd2013-06-02 21:11:1110333 if (state_.vertex_attrib_manager.get() != vao) {
[email protected]e259eb412012-10-13 05:47:2410334 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:1510335 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:5710336 EmulateVertexArrayState();
10337 } else {
[email protected]da364812014-05-09 21:39:4810338 GLuint service_id = vao->service_id();
[email protected]ab4fd7282012-10-12 16:25:5710339 glBindVertexArrayOES(service_id);
10340 }
10341 }
10342}
10343
10344// Used when OES_vertex_array_object isn't natively supported
10345void GLES2DecoderImpl::EmulateVertexArrayState() {
10346 // Setup the Vertex attribute state
10347 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
[email protected]3fc38e22014-05-30 00:13:2310348 RestoreStateForAttrib(vv, true);
[email protected]ab4fd7282012-10-12 16:25:5710349 }
10350
10351 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:2110352 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:2410353 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:5710354 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
10355 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:4610356}
10357
10358bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:4610359 const VertexAttribManager* vao =
10360 GetVertexAttribManager(client_id);
10361 return vao && vao->IsValid() && !vao->IsDeleted();
10362}
10363
[email protected]e51bdf32011-11-23 22:21:4610364#if defined(OS_MACOSX)
10365void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
10366 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
10367 texture_id);
10368 if (it != texture_to_io_surface_map_.end()) {
10369 // Found a previous IOSurface bound to this texture; release it.
[email protected]c3a6b4a2014-06-04 09:25:5310370 IOSurfaceRef surface = it->second;
[email protected]e51bdf32011-11-23 22:21:4610371 CFRelease(surface);
10372 texture_to_io_surface_map_.erase(it);
10373 }
10374}
10375#endif
10376
10377void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
10378 GLenum target, GLsizei width, GLsizei height,
10379 GLuint io_surface_id, GLuint plane) {
10380#if defined(OS_MACOSX)
10381 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:5110382 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310383 GL_INVALID_OPERATION,
10384 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:4610385 return;
10386 }
10387
[email protected]e51bdf32011-11-23 22:21:4610388 if (target != GL_TEXTURE_RECTANGLE_ARB) {
10389 // This might be supported in the future, and if we could require
10390 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
10391 // could delete a lot of code. For now, perform strict validation so we
10392 // know what's going on.
[email protected]ab09b612013-03-11 22:11:5110393 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4610394 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310395 "glTexImageIOSurface2DCHROMIUM",
10396 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:4610397 return;
10398 }
10399
[email protected]09d50362012-10-18 20:54:3710400 // Default target might be conceptually valid, but disallow it to avoid
10401 // accidents.
[email protected]c986af502013-08-14 01:04:4410402 TextureRef* texture_ref =
10403 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910404 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110405 LOCAL_SET_GL_ERROR(
10406 GL_INVALID_OPERATION,
10407 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:4610408 return;
10409 }
[email protected]e51bdf32011-11-23 22:21:4610410
10411 // Look up the new IOSurface. Note that because of asynchrony
10412 // between processes this might fail; during live resizing the
10413 // plugin process might allocate and release an IOSurface before
10414 // this process gets a chance to look it up. Hold on to any old
10415 // IOSurface in this case.
[email protected]c3a6b4a2014-06-04 09:25:5310416 IOSurfaceRef surface = IOSurfaceLookup(io_surface_id);
[email protected]e51bdf32011-11-23 22:21:4610417 if (!surface) {
[email protected]ab09b612013-03-11 22:11:5110418 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310419 GL_INVALID_OPERATION,
10420 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:4610421 return;
10422 }
10423
10424 // Release any IOSurface previously bound to this texture.
[email protected]370eaf12013-05-18 09:19:4910425 ReleaseIOSurfaceForTexture(texture_ref->service_id());
[email protected]e51bdf32011-11-23 22:21:4610426
10427 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
10428 texture_to_io_surface_map_.insert(
[email protected]370eaf12013-05-18 09:19:4910429 std::make_pair(texture_ref->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:4610430
10431 CGLContextObj context =
10432 static_cast<CGLContextObj>(context_->GetHandle());
10433
[email protected]c3a6b4a2014-06-04 09:25:5310434 CGLError err = CGLTexImageIOSurface2D(
[email protected]e51bdf32011-11-23 22:21:4610435 context,
10436 target,
10437 GL_RGBA,
10438 width,
10439 height,
10440 GL_BGRA,
10441 GL_UNSIGNED_INT_8_8_8_8_REV,
10442 surface,
10443 plane);
10444
10445 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:5110446 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4610447 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310448 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:4610449 return;
10450 }
10451
10452 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910453 texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:4610454 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
10455
10456#else
[email protected]ab09b612013-03-11 22:11:5110457 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310458 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:4610459#endif
10460}
10461
[email protected]97dc7cbe2011-12-06 17:26:1710462static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
10463 switch (internalformat) {
10464 case GL_RGB565:
10465 return GL_RGB;
10466 case GL_RGBA4:
10467 return GL_RGBA;
10468 case GL_RGB5_A1:
10469 return GL_RGBA;
10470 case GL_RGB8_OES:
10471 return GL_RGB;
10472 case GL_RGBA8_OES:
10473 return GL_RGBA;
10474 case GL_LUMINANCE8_ALPHA8_EXT:
10475 return GL_LUMINANCE_ALPHA;
10476 case GL_LUMINANCE8_EXT:
10477 return GL_LUMINANCE;
10478 case GL_ALPHA8_EXT:
10479 return GL_ALPHA;
10480 case GL_RGBA32F_EXT:
10481 return GL_RGBA;
10482 case GL_RGB32F_EXT:
10483 return GL_RGB;
10484 case GL_ALPHA32F_EXT:
10485 return GL_ALPHA;
10486 case GL_LUMINANCE32F_EXT:
10487 return GL_LUMINANCE;
10488 case GL_LUMINANCE_ALPHA32F_EXT:
10489 return GL_LUMINANCE_ALPHA;
10490 case GL_RGBA16F_EXT:
10491 return GL_RGBA;
10492 case GL_RGB16F_EXT:
10493 return GL_RGB;
10494 case GL_ALPHA16F_EXT:
10495 return GL_ALPHA;
10496 case GL_LUMINANCE16F_EXT:
10497 return GL_LUMINANCE;
10498 case GL_LUMINANCE_ALPHA16F_EXT:
10499 return GL_LUMINANCE_ALPHA;
10500 case GL_BGRA8_EXT:
10501 return GL_BGRA_EXT;
bajones2a2ea232014-10-13 21:38:5910502 case GL_SRGB8_ALPHA8_EXT:
10503 return GL_SRGB_ALPHA_EXT;
[email protected]97dc7cbe2011-12-06 17:26:1710504 default:
10505 return GL_NONE;
10506 }
10507}
10508
[email protected]43410e92012-04-20 17:06:2810509void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:0310510 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
[email protected]a4a6bdd12013-04-19 20:46:5410511 GLenum internal_format, GLenum dest_type) {
[email protected]1e24dc7f2014-04-14 02:40:0810512 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM");
10513
[email protected]370eaf12013-05-18 09:19:4910514 TextureRef* dest_texture_ref = GetTexture(dest_id);
10515 TextureRef* source_texture_ref = GetTexture(source_id);
[email protected]43410e92012-04-20 17:06:2810516
[email protected]370eaf12013-05-18 09:19:4910517 if (!source_texture_ref || !dest_texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110518 LOCAL_SET_GL_ERROR(
10519 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:2810520 return;
10521 }
10522
10523 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110524 LOCAL_SET_GL_ERROR(
10525 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:2810526 return;
10527 }
10528
[email protected]370eaf12013-05-18 09:19:4910529 Texture* source_texture = source_texture_ref->texture();
10530 Texture* dest_texture = dest_texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0710531 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:2510532 (source_texture->target() != GL_TEXTURE_2D &&
[email protected]041d463f2014-04-30 05:38:3410533 source_texture->target() != GL_TEXTURE_RECTANGLE_ARB &&
10534 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
[email protected]3ecc1052013-09-26 08:59:0010535 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
10536 "glCopyTextureCHROMIUM",
10537 "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:0310538 return;
10539 }
10540
[email protected]43410e92012-04-20 17:06:2810541 int source_width, source_height, dest_width, dest_height;
[email protected]43410e92012-04-20 17:06:2810542
[email protected]3e0dfd72014-02-21 06:28:4110543 gfx::GLImage* image =
10544 source_texture->GetLevelImage(source_texture->target(), 0);
10545 if (image) {
[email protected]7bffe9e12014-01-27 23:02:5510546 gfx::Size size = image->GetSize();
[email protected]377976552013-05-14 23:32:5610547 source_width = size.width();
10548 source_height = size.height();
10549 if (source_width <= 0 || source_height <= 0) {
10550 LOCAL_SET_GL_ERROR(
10551 GL_INVALID_VALUE,
[email protected]7bffe9e12014-01-27 23:02:5510552 "glCopyTextureChromium", "invalid image size");
[email protected]377976552013-05-14 23:32:5610553 return;
10554 }
[email protected]3ecc1052013-09-26 08:59:0010555 } else {
10556 if (!source_texture->GetLevelSize(
10557 source_texture->target(), 0, &source_width, &source_height)) {
10558 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
10559 "glCopyTextureChromium",
10560 "source texture has no level 0");
10561 return;
10562 }
10563
10564 // Check that this type of texture is allowed.
10565 if (!texture_manager()->ValidForTarget(
10566 source_texture->target(), level, source_width, source_height, 1)) {
10567 LOCAL_SET_GL_ERROR(
10568 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions");
10569 return;
10570 }
[email protected]377976552013-05-14 23:32:5610571 }
10572
[email protected]04b5b37d2014-02-07 02:11:5110573 // Clear the source texture if necessary.
10574 if (!texture_manager()->ClearTextureLevel(
10575 this, source_texture_ref, source_texture->target(), 0)) {
10576 LOCAL_SET_GL_ERROR(
10577 GL_OUT_OF_MEMORY, "glCopyTextureCHROMIUM", "dimensions too big");
10578 return;
10579 }
10580
[email protected]a6e3d282014-08-22 22:20:4410581 GLenum source_type = 0;
10582 GLenum source_internal_format = 0;
10583 source_texture->GetLevelType(
10584 source_texture->target(), 0, &source_type, &source_internal_format);
10585
10586 // The destination format should be GL_RGB, or GL_RGBA. GL_ALPHA,
10587 // GL_LUMINANCE, and GL_LUMINANCE_ALPHA are not supported because they are not
10588 // renderable on some platforms.
reveman6b0fbe42014-09-04 00:55:0310589 bool valid_dest_format = internal_format == GL_RGB ||
10590 internal_format == GL_RGBA ||
10591 internal_format == GL_BGRA_EXT;
[email protected]a6e3d282014-08-22 22:20:4410592 bool valid_source_format = source_internal_format == GL_ALPHA ||
10593 source_internal_format == GL_RGB ||
10594 source_internal_format == GL_RGBA ||
10595 source_internal_format == GL_LUMINANCE ||
10596 source_internal_format == GL_LUMINANCE_ALPHA ||
10597 source_internal_format == GL_BGRA_EXT;
10598 if (!valid_source_format || !valid_dest_format) {
10599 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10600 "glCopyTextureCHROMIUM",
10601 "invalid internal format");
10602 return;
10603 }
10604
[email protected]cf6b8f62012-05-25 21:43:3710605 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
10606 // needed because it takes 10s of milliseconds to initialize.
10607 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:5110608 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:3710609 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:2710610 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:3710611 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:5110612 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:3710613 return;
10614 }
10615
[email protected]efc87712014-07-09 00:22:4710616 GLenum dest_type_previous = dest_type;
10617 GLenum dest_internal_format = internal_format;
[email protected]02965c22013-03-09 02:40:0710618 bool dest_level_defined = dest_texture->GetLevelSize(
10619 GL_TEXTURE_2D, level, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:2810620
[email protected]0a1e9ad2012-05-04 21:13:0310621 if (dest_level_defined) {
[email protected]a4a6bdd12013-04-19 20:46:5410622 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous,
[email protected]02965c22013-03-09 02:40:0710623 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:0310624 }
10625
10626 // Resize the destination texture to the dimensions of the source texture.
10627 if (!dest_level_defined || dest_width != source_width ||
10628 dest_height != source_height ||
[email protected]a4a6bdd12013-04-19 20:46:5410629 dest_internal_format != internal_format ||
10630 dest_type_previous != dest_type) {
[email protected]43410e92012-04-20 17:06:2810631 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:5110632 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:0710633 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
[email protected]8f1d2aa2013-05-10 23:45:3810634 glTexImage2D(
[email protected]43410e92012-04-20 17:06:2810635 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:0310636 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:5110637 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:0310638 if (error != GL_NO_ERROR) {
[email protected]2b10c02d2014-01-29 16:43:0210639 RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D);
[email protected]43410e92012-04-20 17:06:2810640 return;
[email protected]0a1e9ad2012-05-04 21:13:0310641 }
[email protected]43410e92012-04-20 17:06:2810642
10643 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910644 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:0310645 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:2510646 } else {
[email protected]02965c22013-03-09 02:40:0710647 texture_manager()->SetLevelCleared(
[email protected]370eaf12013-05-18 09:19:4910648 dest_texture_ref, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:2810649 }
10650
[email protected]00c2cf92014-03-14 00:08:3710651 ScopedModifyPixels modify(dest_texture_ref);
[email protected]91c94eb2013-10-22 10:32:5410652
revemance8fbe82014-09-05 02:19:5210653 // Try using GLImage::CopyTexImage when possible.
10654 bool unpack_premultiply_alpha_change =
10655 unpack_premultiply_alpha_ ^ unpack_unpremultiply_alpha_;
10656 if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change && !level) {
10657 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
10658 if (image->CopyTexImage(GL_TEXTURE_2D))
10659 return;
10660 }
10661
10662 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
10663
[email protected]5394a4102013-04-18 05:41:3710664 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
10665 // before presenting.
10666 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
10667 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
10668 // instead of using default matrix crbug.com/226218.
10669 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
10670 0.0f, 1.0f, 0.0f, 0.0f,
10671 0.0f, 0.0f, 1.0f, 0.0f,
10672 0.0f, 0.0f, 0.0f, 1.0f};
10673 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
10674 this,
10675 source_texture->target(),
[email protected]5394a4102013-04-18 05:41:3710676 source_texture->service_id(),
[email protected]90f7d30d2014-08-13 02:51:5710677 dest_texture->service_id(),
10678 level,
10679 source_width,
10680 source_height,
[email protected]5394a4102013-04-18 05:41:3710681 unpack_flip_y_,
10682 unpack_premultiply_alpha_,
10683 unpack_unpremultiply_alpha_,
10684 default_matrix);
10685 } else {
[email protected]90f7d30d2014-08-13 02:51:5710686 copy_texture_CHROMIUM_->DoCopyTexture(this,
10687 source_texture->target(),
10688 source_texture->service_id(),
10689 source_internal_format,
10690 dest_texture->service_id(),
10691 level,
10692 internal_format,
10693 source_width,
10694 source_height,
10695 unpack_flip_y_,
10696 unpack_premultiply_alpha_,
10697 unpack_unpremultiply_alpha_);
[email protected]5394a4102013-04-18 05:41:3710698 }
[email protected]91c94eb2013-10-22 10:32:5410699
10700 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
[email protected]43410e92012-04-20 17:06:2810701}
10702
[email protected]97dc7cbe2011-12-06 17:26:1710703static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
10704 switch (internalformat) {
10705 case GL_RGB565:
10706 return GL_UNSIGNED_SHORT_5_6_5;
10707 case GL_RGBA4:
10708 return GL_UNSIGNED_SHORT_4_4_4_4;
10709 case GL_RGB5_A1:
10710 return GL_UNSIGNED_SHORT_5_5_5_1;
10711 case GL_RGB8_OES:
10712 return GL_UNSIGNED_BYTE;
10713 case GL_RGBA8_OES:
10714 return GL_UNSIGNED_BYTE;
10715 case GL_LUMINANCE8_ALPHA8_EXT:
10716 return GL_UNSIGNED_BYTE;
10717 case GL_LUMINANCE8_EXT:
10718 return GL_UNSIGNED_BYTE;
10719 case GL_ALPHA8_EXT:
10720 return GL_UNSIGNED_BYTE;
10721 case GL_RGBA32F_EXT:
10722 return GL_FLOAT;
10723 case GL_RGB32F_EXT:
10724 return GL_FLOAT;
10725 case GL_ALPHA32F_EXT:
10726 return GL_FLOAT;
10727 case GL_LUMINANCE32F_EXT:
10728 return GL_FLOAT;
10729 case GL_LUMINANCE_ALPHA32F_EXT:
10730 return GL_FLOAT;
10731 case GL_RGBA16F_EXT:
10732 return GL_HALF_FLOAT_OES;
10733 case GL_RGB16F_EXT:
10734 return GL_HALF_FLOAT_OES;
10735 case GL_ALPHA16F_EXT:
10736 return GL_HALF_FLOAT_OES;
10737 case GL_LUMINANCE16F_EXT:
10738 return GL_HALF_FLOAT_OES;
10739 case GL_LUMINANCE_ALPHA16F_EXT:
10740 return GL_HALF_FLOAT_OES;
10741 case GL_BGRA8_EXT:
10742 return GL_UNSIGNED_BYTE;
10743 default:
10744 return GL_NONE;
10745 }
10746}
10747
10748void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:4410749 GLenum target,
10750 GLint levels,
10751 GLenum internal_format,
10752 GLsizei width,
10753 GLsizei height) {
[email protected]67f929422014-05-17 15:33:1310754 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT",
10755 "width", width, "height", height);
[email protected]80eb6b52012-01-19 00:14:4110756 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]3ecc1052013-09-26 08:59:0010757 TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:5110758 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310759 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:1710760 return;
10761 }
[email protected]c986af502013-08-14 01:04:4410762 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10763 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910764 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110765 LOCAL_SET_GL_ERROR(
10766 GL_INVALID_OPERATION,
10767 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:1710768 return;
10769 }
[email protected]370eaf12013-05-18 09:19:4910770 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0710771 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:4410772 framebuffer_state_.clear_state_dirty = true;
[email protected]97dc7cbe2011-12-06 17:26:1710773 }
[email protected]02965c22013-03-09 02:40:0710774 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:5110775 LOCAL_SET_GL_ERROR(
10776 GL_INVALID_OPERATION,
10777 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:1710778 return;
10779 }
[email protected]7989c9e2013-01-23 06:39:2610780
10781 GLenum format = ExtractFormatFromStorageFormat(internal_format);
10782 GLenum type = ExtractTypeFromStorageFormat(internal_format);
10783
10784 {
10785 GLsizei level_width = width;
10786 GLsizei level_height = height;
10787 uint32 estimated_size = 0;
10788 for (int ii = 0; ii < levels; ++ii) {
10789 uint32 level_size = 0;
10790 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4210791 level_width, level_height, 1, format, type, state_.unpack_alignment,
[email protected]7989c9e2013-01-23 06:39:2610792 &estimated_size, NULL, NULL) ||
10793 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5110794 LOCAL_SET_GL_ERROR(
10795 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:2610796 return;
10797 }
10798 level_width = std::max(1, level_width >> 1);
10799 level_height = std::max(1, level_height >> 1);
10800 }
10801 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5110802 LOCAL_SET_GL_ERROR(
10803 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2610804 return;
10805 }
10806 }
10807
[email protected]ab09b612013-03-11 22:11:5110808 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]8f1d2aa2013-05-10 23:45:3810809 glTexStorage2DEXT(target, levels, internal_format, width, height);
[email protected]ab09b612013-03-11 22:11:5110810 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:1710811 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:1510812 GLsizei level_width = width;
10813 GLsizei level_height = height;
10814 for (int ii = 0; ii < levels; ++ii) {
10815 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910816 texture_ref, target, ii, format,
10817 level_width, level_height, 1, 0, format, type, false);
[email protected]4502e6492011-12-14 19:39:1510818 level_width = std::max(1, level_width >> 1);
10819 level_height = std::max(1, level_height >> 1);
10820 }
[email protected]02965c22013-03-09 02:40:0710821 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:1710822 }
[email protected]97dc7cbe2011-12-06 17:26:1710823}
[email protected]e51bdf32011-11-23 22:21:4610824
[email protected]78b514b2012-05-01 21:50:5910825error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
vmiuracd108592014-09-08 14:36:3410826 uint32 immediate_data_size,
10827 const void* cmd_data) {
[email protected]baed42c2013-10-01 05:06:3510828 return error::kUnknownCommand;
[email protected]78b514b2012-05-01 21:50:5910829}
10830
10831void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3710832 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0210833 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3210834 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3710835 "mailbox[0]", static_cast<unsigned char>(data[0]));
10836
[email protected]43f253da2014-06-10 17:51:2210837 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10838 &state_, target);
10839 ProduceTextureRef("glProduceTextureCHROMIUM", texture_ref, target, data);
10840}
10841
10842void GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM(GLuint client_id,
10843 GLenum target, const GLbyte* data) {
10844 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM",
10845 "context", logger_.GetLogPrefix(),
10846 "mailbox[0]", static_cast<unsigned char>(data[0]));
10847
10848 ProduceTextureRef("glProduceTextureDirectCHROMIUM", GetTexture(client_id),
10849 target, data);
10850}
10851
10852void GLES2DecoderImpl::ProduceTextureRef(std::string func_name,
10853 TextureRef* texture_ref, GLenum target, const GLbyte* data) {
[email protected]64ba52f2014-02-15 14:22:3710854 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
[email protected]43f253da2014-06-10 17:51:2210855 DLOG_IF(ERROR, !mailbox.Verify()) << func_name << " was passed a "
[email protected]64ba52f2014-02-15 14:22:3710856 "mailbox that was not generated by "
10857 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0210858
[email protected]370eaf12013-05-18 09:19:4910859 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110860 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2210861 GL_INVALID_OPERATION, func_name.c_str(), "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5910862 return;
10863 }
10864
[email protected]62e65f02013-05-29 22:28:1010865 Texture* produced = texture_manager()->Produce(texture_ref);
10866 if (!produced) {
[email protected]ab09b612013-03-11 22:11:5110867 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2210868 GL_INVALID_OPERATION, func_name.c_str(), "invalid texture");
10869 return;
10870 }
10871
10872 if (produced->target() != target) {
10873 LOCAL_SET_GL_ERROR(
10874 GL_INVALID_OPERATION, func_name.c_str(), "invalid target");
[email protected]78b514b2012-05-01 21:50:5910875 return;
10876 }
10877
sievers8b373ec52014-10-24 23:04:0610878 group_->mailbox_manager()->ProduceTexture(mailbox, produced);
[email protected]78b514b2012-05-01 21:50:5910879}
10880
10881void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3710882 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0210883 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3210884 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3710885 "mailbox[0]", static_cast<unsigned char>(data[0]));
10886 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
10887 DLOG_IF(ERROR, !mailbox.Verify()) << "ConsumeTextureCHROMIUM was passed a "
10888 "mailbox that was not generated by "
10889 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0210890
[email protected]62e65f02013-05-29 22:28:1010891 scoped_refptr<TextureRef> texture_ref =
[email protected]c986af502013-08-14 01:04:4410892 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]7cd76fd2013-06-02 21:11:1110893 if (!texture_ref.get()) {
10894 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10895 "glConsumeTextureCHROMIUM",
10896 "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5910897 return;
10898 }
[email protected]62e65f02013-05-29 22:28:1010899 GLuint client_id = texture_ref->client_id();
10900 if (!client_id) {
10901 LOCAL_SET_GL_ERROR(
10902 GL_INVALID_OPERATION,
10903 "glConsumeTextureCHROMIUM", "unknown texture for target");
10904 return;
10905 }
sievers8b373ec52014-10-24 23:04:0610906 Texture* texture = group_->mailbox_manager()->ConsumeTexture(mailbox);
[email protected]62e65f02013-05-29 22:28:1010907 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5110908 LOCAL_SET_GL_ERROR(
10909 GL_INVALID_OPERATION,
10910 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:5910911 return;
10912 }
[email protected]62e65f02013-05-29 22:28:1010913 if (texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:5110914 LOCAL_SET_GL_ERROR(
10915 GL_INVALID_OPERATION,
[email protected]62e65f02013-05-29 22:28:1010916 "glConsumeTextureCHROMIUM", "invalid target");
[email protected]78b514b2012-05-01 21:50:5910917 return;
10918 }
[email protected]62e65f02013-05-29 22:28:1010919
10920 DeleteTexturesHelper(1, &client_id);
10921 texture_ref = texture_manager()->Consume(client_id, texture);
10922 glBindTexture(target, texture_ref->service_id());
10923
10924 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
10925 unit.bind_target = target;
10926 switch (target) {
10927 case GL_TEXTURE_2D:
10928 unit.bound_texture_2d = texture_ref;
10929 break;
10930 case GL_TEXTURE_CUBE_MAP:
10931 unit.bound_texture_cube_map = texture_ref;
10932 break;
10933 case GL_TEXTURE_EXTERNAL_OES:
10934 unit.bound_texture_external_oes = texture_ref;
10935 break;
10936 case GL_TEXTURE_RECTANGLE_ARB:
10937 unit.bound_texture_rectangle_arb = texture_ref;
10938 break;
10939 default:
10940 NOTREACHED(); // Validation should prevent us getting here.
10941 break;
10942 }
[email protected]78b514b2012-05-01 21:50:5910943}
10944
[email protected]43f253da2014-06-10 17:51:2210945error::Error GLES2DecoderImpl::HandleCreateAndConsumeTextureCHROMIUMImmediate(
10946 uint32_t immediate_data_size,
vmiuracd108592014-09-08 14:36:3410947 const void* cmd_data) {
10948 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate& c =
10949 *static_cast<
10950 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate*>(
10951 cmd_data);
[email protected]43f253da2014-06-10 17:51:2210952 GLenum target = static_cast<GLenum>(c.target);
10953 uint32_t data_size;
10954 if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
10955 return error::kOutOfBounds;
10956 }
10957 if (data_size > immediate_data_size) {
10958 return error::kOutOfBounds;
10959 }
10960 const GLbyte* mailbox =
10961 GetImmediateDataAs<const GLbyte*>(c, data_size, immediate_data_size);
10962 if (!validators_->texture_bind_target.IsValid(target)) {
10963 LOCAL_SET_GL_ERROR_INVALID_ENUM(
10964 "glCreateAndConsumeTextureCHROMIUM", target, "target");
10965 return error::kNoError;
10966 }
10967 if (mailbox == NULL) {
10968 return error::kOutOfBounds;
10969 }
10970 uint32_t client_id = c.client_id;
10971 DoCreateAndConsumeTextureCHROMIUM(target, mailbox, client_id);
10972 return error::kNoError;
10973}
10974
10975void GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM(GLenum target,
10976 const GLbyte* data, GLuint client_id) {
10977 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM",
10978 "context", logger_.GetLogPrefix(),
10979 "mailbox[0]", static_cast<unsigned char>(data[0]));
10980 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
10981 DLOG_IF(ERROR, !mailbox.Verify()) << "CreateAndConsumeTextureCHROMIUM was "
10982 "passed a mailbox that was not "
10983 "generated by GenMailboxCHROMIUM.";
10984
10985 TextureRef* texture_ref = GetTexture(client_id);
10986 if (texture_ref) {
10987 LOCAL_SET_GL_ERROR(
10988 GL_INVALID_OPERATION,
10989 "glCreateAndConsumeTextureCHROMIUM", "client id already in use");
10990 return;
10991 }
sievers8b373ec52014-10-24 23:04:0610992 Texture* texture = group_->mailbox_manager()->ConsumeTexture(mailbox);
[email protected]43f253da2014-06-10 17:51:2210993 if (!texture) {
10994 LOCAL_SET_GL_ERROR(
10995 GL_INVALID_OPERATION,
10996 "glCreateAndConsumeTextureCHROMIUM", "invalid mailbox name");
10997 return;
10998 }
10999 if (texture->target() != target) {
11000 LOCAL_SET_GL_ERROR(
11001 GL_INVALID_OPERATION,
11002 "glCreateAndConsumeTextureCHROMIUM", "invalid target");
11003 return;
11004 }
11005
[email protected]43f253da2014-06-10 17:51:2211006 texture_ref = texture_manager()->Consume(client_id, texture);
11007}
11008
orglofchcad5a6742014-11-07 19:51:1211009bool GLES2DecoderImpl::DoIsValuebufferCHROMIUM(GLuint client_id) {
11010 const Valuebuffer* valuebuffer = GetValuebuffer(client_id);
11011 return valuebuffer && valuebuffer->IsValid();
11012}
11013
11014void GLES2DecoderImpl::DoBindValueBufferCHROMIUM(GLenum target,
11015 GLuint client_id) {
11016 Valuebuffer* valuebuffer = NULL;
11017 if (client_id != 0) {
11018 valuebuffer = GetValuebuffer(client_id);
11019 if (!valuebuffer) {
11020 if (!group_->bind_generates_resource()) {
11021 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBindValuebufferCHROMIUM",
11022 "id not generated by glBindValuebufferCHROMIUM");
11023 return;
11024 }
11025
11026 // It's a new id so make a valuebuffer for it.
11027 CreateValuebuffer(client_id);
11028 valuebuffer = GetValuebuffer(client_id);
11029 }
11030 valuebuffer->MarkAsValid();
11031 }
11032 state_.bound_valuebuffer = valuebuffer;
11033}
11034
11035void GLES2DecoderImpl::DoSubscribeValueCHROMIUM(GLenum target,
11036 GLenum subscription) {
11037 if (!CheckCurrentValuebuffer("glSubscribeValueCHROMIUM")) {
11038 return;
11039 }
11040 state_.bound_valuebuffer.get()->AddSubscription(subscription);
11041}
11042
11043void GLES2DecoderImpl::DoPopulateSubscribedValuesCHROMIUM(GLenum target) {
11044 if (!CheckCurrentValuebuffer("glPopulateSubscribedValuesCHROMIUM")) {
11045 return;
11046 }
11047 valuebuffer_manager()->UpdateValuebufferState(state_.bound_valuebuffer.get());
11048}
11049
11050void GLES2DecoderImpl::DoUniformValueBufferCHROMIUM(GLint location,
11051 GLenum target,
11052 GLenum subscription) {
11053 if (!CheckCurrentValuebufferForSubscription(
11054 subscription, "glPopulateSubscribedValuesCHROMIUM")) {
11055 return;
11056 }
11057 if (!CheckSubscriptionTarget(location, subscription,
11058 "glPopulateSubscribedValuesCHROMIUM")) {
11059 return;
11060 }
11061 const ValueState* state =
11062 state_.bound_valuebuffer.get()->GetState(subscription);
11063 if (state) {
11064 switch (subscription) {
11065 case GL_MOUSE_POSITION_CHROMIUM:
11066 DoUniform2iv(location, 1, state->int_value);
11067 break;
11068 default:
11069 NOTREACHED() << "Unhandled uniform subscription target "
11070 << subscription;
11071 break;
11072 }
11073 }
11074}
11075
[email protected]d2a0e1a2012-08-12 02:25:0111076void GLES2DecoderImpl::DoInsertEventMarkerEXT(
11077 GLsizei length, const GLchar* marker) {
11078 if (!marker) {
11079 marker = "";
11080 }
11081 debug_marker_manager_.SetMarker(
11082 length ? std::string(marker, length) : std::string(marker));
11083}
11084
11085void GLES2DecoderImpl::DoPushGroupMarkerEXT(
11086 GLsizei length, const GLchar* marker) {
11087 if (!marker) {
11088 marker = "";
11089 }
[email protected]cac16542014-01-15 17:53:5111090 std::string name = length ? std::string(marker, length) : std::string(marker);
11091 debug_marker_manager_.PushGroup(name);
dyen4bb43282015-01-08 01:09:5611092 gpu_tracer_->Begin(TRACE_DISABLED_BY_DEFAULT("gpu_group_marker"), name,
11093 kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0111094}
11095
11096void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
11097 debug_marker_manager_.PopGroup();
dyen4bb43282015-01-08 01:09:5611098 gpu_tracer_->End(kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0111099}
11100
[email protected]09d50362012-10-18 20:54:3711101void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
11102 GLenum target, GLint image_id) {
11103 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3711104
[email protected]bc26e8d2014-01-29 00:40:3011105 if (target == GL_TEXTURE_CUBE_MAP) {
11106 LOCAL_SET_GL_ERROR(
11107 GL_INVALID_ENUM,
11108 "glBindTexImage2DCHROMIUM", "invalid target");
11109 return;
11110 }
11111
[email protected]09d50362012-10-18 20:54:3711112 // Default target might be conceptually valid, but disallow it to avoid
11113 // accidents.
[email protected]c986af502013-08-14 01:04:4411114 TextureRef* texture_ref =
11115 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4911116 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111117 LOCAL_SET_GL_ERROR(
11118 GL_INVALID_OPERATION,
11119 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3711120 return;
11121 }
11122
11123 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
11124 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5111125 LOCAL_SET_GL_ERROR(
11126 GL_INVALID_OPERATION,
11127 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3711128 return;
11129 }
11130
[email protected]b8160812013-04-09 00:41:0411131 {
11132 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3011133 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2611134 if (!gl_image->BindTexImage(target)) {
[email protected]b8160812013-04-09 00:41:0411135 LOCAL_SET_GL_ERROR(
11136 GL_INVALID_OPERATION,
11137 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
11138 return;
11139 }
[email protected]09d50362012-10-18 20:54:3711140 }
11141
11142 gfx::Size size = gl_image->GetSize();
11143 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4911144 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:3711145 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]370eaf12013-05-18 09:19:4911146 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:3711147}
11148
11149void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
11150 GLenum target, GLint image_id) {
11151 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3711152
11153 // Default target might be conceptually valid, but disallow it to avoid
11154 // accidents.
[email protected]c986af502013-08-14 01:04:4411155 TextureRef* texture_ref =
11156 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4911157 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111158 LOCAL_SET_GL_ERROR(
11159 GL_INVALID_OPERATION,
11160 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3711161 return;
11162 }
11163
11164 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
11165 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5111166 LOCAL_SET_GL_ERROR(
11167 GL_INVALID_OPERATION,
11168 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3711169 return;
11170 }
11171
11172 // Do nothing when image is not currently bound.
[email protected]370eaf12013-05-18 09:19:4911173 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3711174 return;
11175
[email protected]b8160812013-04-09 00:41:0411176 {
11177 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3011178 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2611179 gl_image->ReleaseTexImage(target);
[email protected]b8160812013-04-09 00:41:0411180 }
[email protected]09d50362012-10-18 20:54:3711181
11182 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4911183 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:3711184 GL_RGBA, GL_UNSIGNED_BYTE, false);
11185}
[email protected]d2a0e1a2012-08-12 02:25:0111186
[email protected]94307712012-11-16 23:26:1111187error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
vmiuracd108592014-09-08 14:36:3411188 uint32 immediate_data_size,
11189 const void* cmd_data) {
11190 const gles2::cmds::TraceBeginCHROMIUM& c =
11191 *static_cast<const gles2::cmds::TraceBeginCHROMIUM*>(cmd_data);
dyencb86f2f2014-12-09 18:35:4111192 Bucket* category_bucket = GetBucket(c.category_bucket_id);
11193 Bucket* name_bucket = GetBucket(c.name_bucket_id);
11194 if (!category_bucket || category_bucket->size() == 0 ||
11195 !name_bucket || name_bucket->size() == 0) {
[email protected]94307712012-11-16 23:26:1111196 return error::kInvalidArguments;
11197 }
dyencb86f2f2014-12-09 18:35:4111198
11199 std::string category_name;
11200 std::string trace_name;
11201 if (!category_bucket->GetAsString(&category_name) ||
11202 !name_bucket->GetAsString(&trace_name)) {
[email protected]94307712012-11-16 23:26:1111203 return error::kInvalidArguments;
11204 }
dyencb86f2f2014-12-09 18:35:4111205
dyencb86f2f2014-12-09 18:35:4111206 if (!gpu_tracer_->Begin(category_name, trace_name, kTraceCHROMIUM)) {
[email protected]ab09b612013-03-11 22:11:5111207 LOCAL_SET_GL_ERROR(
11208 GL_INVALID_OPERATION,
11209 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1411210 return error::kNoError;
11211 }
[email protected]94307712012-11-16 23:26:1111212 return error::kNoError;
11213}
11214
11215void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
dyen4bb43282015-01-08 01:09:5611216 if (!gpu_tracer_->End(kTraceCHROMIUM)) {
11217 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11218 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1111219 return;
11220 }
[email protected]94307712012-11-16 23:26:1111221}
11222
[email protected]2f143d482013-03-14 18:04:4911223void GLES2DecoderImpl::DoDrawBuffersEXT(
11224 GLsizei count, const GLenum* bufs) {
11225 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
11226 LOCAL_SET_GL_ERROR(
11227 GL_INVALID_VALUE,
11228 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
11229 return;
11230 }
11231
11232 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
11233 if (framebuffer) {
11234 for (GLsizei i = 0; i < count; ++i) {
11235 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
11236 bufs[i] != GL_NONE) {
11237 LOCAL_SET_GL_ERROR(
11238 GL_INVALID_OPERATION,
11239 "glDrawBuffersEXT",
11240 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
11241 return;
11242 }
11243 }
11244 glDrawBuffersARB(count, bufs);
11245 framebuffer->SetDrawBuffers(count, bufs);
11246 } else { // backbuffer
11247 if (count > 1 ||
11248 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
11249 LOCAL_SET_GL_ERROR(
11250 GL_INVALID_OPERATION,
11251 "glDrawBuffersEXT",
11252 "more than one buffer or bufs not GL_NONE or GL_BACK");
11253 return;
11254 }
11255 GLenum mapped_buf = bufs[0];
11256 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
11257 bufs[0] == GL_BACK) {
11258 mapped_buf = GL_COLOR_ATTACHMENT0;
11259 }
11260 glDrawBuffersARB(count, &mapped_buf);
11261 group_->set_draw_buffer(bufs[0]);
11262 }
11263}
11264
[email protected]a6a09f852014-05-23 13:05:0311265void GLES2DecoderImpl::DoLoseContextCHROMIUM(GLenum current, GLenum other) {
11266 group_->LoseContexts(other);
11267 reset_status_ = current;
11268 current_decoder_error_ = error::kLostContext;
11269}
11270
kkinnunen337d59632014-08-26 10:19:5711271void GLES2DecoderImpl::DoMatrixLoadfCHROMIUM(GLenum matrix_mode,
11272 const GLfloat* matrix) {
11273 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
11274 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
11275 if (!features().chromium_path_rendering) {
11276 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11277 "glMatrixLoadfCHROMIUM",
11278 "function not available");
11279 return;
11280 }
11281
11282 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
11283 ? state_.projection_matrix
11284 : state_.modelview_matrix;
11285 memcpy(target_matrix, matrix, sizeof(GLfloat) * 16);
11286 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
11287 // since the values of the _NV and _CHROMIUM tokens match.
11288 glMatrixLoadfEXT(matrix_mode, matrix);
11289}
11290
11291void GLES2DecoderImpl::DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode) {
11292 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
11293 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
11294
11295 if (!features().chromium_path_rendering) {
11296 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11297 "glMatrixLoadIdentityCHROMIUM",
11298 "function not available");
11299 return;
11300 }
11301
11302 static GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
11303 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
11304 0.0f, 0.0f, 0.0f, 1.0f};
11305
11306 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
11307 ? state_.projection_matrix
11308 : state_.modelview_matrix;
11309 memcpy(target_matrix, kIdentityMatrix, sizeof(kIdentityMatrix));
11310 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
11311 // since the values of the _NV and _CHROMIUM tokens match.
11312 glMatrixLoadIdentityEXT(matrix_mode);
11313}
11314
[email protected]32145a92012-12-17 09:01:5911315bool GLES2DecoderImpl::ValidateAsyncTransfer(
11316 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:4711317 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:5911318 GLenum target,
11319 GLint level,
11320 const void * data) {
11321 // We only support async uploads to 2D textures for now.
11322 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5111323 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5911324 return false;
11325 }
11326 // We only support uploads to level zero for now.
11327 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5111328 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5911329 return false;
11330 }
11331 // A transfer buffer must be bound, even for asyncTexImage2D.
11332 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5111333 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5911334 return false;
11335 }
11336 // We only support one async transfer in progress.
[email protected]85a4ac22013-05-31 01:58:4711337 if (!texture_ref ||
11338 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5111339 LOCAL_SET_GL_ERROR(
11340 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5911341 function_name, "transfer already in progress");
11342 return false;
11343 }
11344 return true;
11345}
11346
[email protected]e3c4a9ab2014-03-31 09:07:0211347base::Closure GLES2DecoderImpl::AsyncUploadTokenCompletionClosure(
11348 uint32 async_upload_token,
11349 uint32 sync_data_shm_id,
11350 uint32 sync_data_shm_offset) {
11351 scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_data_shm_id);
Daniel Cheng3d7ce9f2014-08-26 00:26:2511352 if (!buffer.get() ||
11353 !buffer->GetDataAddress(sync_data_shm_offset, sizeof(AsyncUploadSync)))
[email protected]e3c4a9ab2014-03-31 09:07:0211354 return base::Closure();
11355
11356 AsyncMemoryParams mem_params(buffer,
11357 sync_data_shm_offset,
11358 sizeof(AsyncUploadSync));
11359
11360 scoped_refptr<AsyncUploadTokenCompletionObserver> observer(
11361 new AsyncUploadTokenCompletionObserver(async_upload_token));
11362
11363 return base::Bind(
11364 &AsyncPixelTransferManager::AsyncNotifyCompletion,
11365 base::Unretained(GetAsyncPixelTransferManager()),
11366 mem_params,
11367 observer);
11368}
11369
[email protected]69023942012-11-30 19:57:1611370error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411371 uint32 immediate_data_size,
11372 const void* cmd_data) {
11373 const gles2::cmds::AsyncTexImage2DCHROMIUM& c =
11374 *static_cast<const gles2::cmds::AsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1611375 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1611376 GLenum target = static_cast<GLenum>(c.target);
11377 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:4411378 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]69023942012-11-30 19:57:1611379 GLsizei width = static_cast<GLsizei>(c.width);
11380 GLsizei height = static_cast<GLsizei>(c.height);
11381 GLint border = static_cast<GLint>(c.border);
11382 GLenum format = static_cast<GLenum>(c.format);
11383 GLenum type = static_cast<GLenum>(c.type);
11384 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
11385 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
11386 uint32 pixels_size;
[email protected]e3c4a9ab2014-03-31 09:07:0211387 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
11388 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
11389 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
11390
11391 base::ScopedClosureRunner scoped_completion_callback;
11392 if (async_upload_token) {
11393 base::Closure completion_closure =
11394 AsyncUploadTokenCompletionClosure(async_upload_token,
11395 sync_data_shm_id,
11396 sync_data_shm_offset);
11397 if (completion_closure.is_null())
11398 return error::kInvalidArguments;
11399
11400 scoped_completion_callback.Reset(completion_closure);
11401 }
[email protected]32145a92012-12-17 09:01:5911402
11403 // TODO(epenner): Move this and copies of this memory validation
11404 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1611405 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4211406 width, height, 1, format, type, state_.unpack_alignment, &pixels_size,
11407 NULL, NULL)) {
[email protected]69023942012-11-30 19:57:1611408 return error::kOutOfBounds;
11409 }
11410 const void* pixels = NULL;
11411 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
11412 pixels = GetSharedMemoryAs<const void*>(
11413 pixels_shm_id, pixels_shm_offset, pixels_size);
11414 if (!pixels) {
11415 return error::kOutOfBounds;
11416 }
11417 }
11418
[email protected]c986af502013-08-14 01:04:4411419 TextureManager::DoTextImage2DArguments args = {
11420 target, level, internal_format, width, height, border, format, type,
11421 pixels, pixels_size};
11422 TextureRef* texture_ref;
[email protected]32145a92012-12-17 09:01:5911423 // All the normal glTexSubImage2D validation.
[email protected]c986af502013-08-14 01:04:4411424 if (!texture_manager()->ValidateTexImage2D(
11425 &state_, "glAsyncTexImage2DCHROMIUM", args, &texture_ref)) {
[email protected]32145a92012-12-17 09:01:5911426 return error::kNoError;
11427 }
11428
11429 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4911430 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5911431 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4711432 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5911433 return error::kNoError;
11434
11435 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0711436 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5111437 LOCAL_SET_GL_ERROR(
11438 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5911439 "glAsyncTexImage2DCHROMIUM", "already defined");
11440 return error::kNoError;
11441 }
11442
[email protected]7989c9e2013-01-23 06:39:2611443 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5111444 LOCAL_SET_GL_ERROR(
11445 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2611446 return error::kNoError;
11447 }
11448
[email protected]5b3a8e02013-03-13 05:36:4411449 // Setup the parameters.
[email protected]8f1d2aa2013-05-10 23:45:3811450 AsyncTexImage2DParams tex_params = {
11451 target, level, static_cast<GLenum>(internal_format),
11452 width, height, border, format, type};
[email protected]c8021e02014-03-27 06:10:1211453 AsyncMemoryParams mem_params(
11454 GetSharedMemoryBuffer(c.pixels_shm_id), c.pixels_shm_offset, pixels_size);
[email protected]32145a92012-12-17 09:01:5911455
[email protected]5b3a8e02013-03-13 05:36:4411456 // Set up the async state if needed, and make the texture
11457 // immutable so the async state stays valid. The level info
11458 // is set up lazily when the transfer completes.
[email protected]896425e2013-06-12 17:27:1811459 AsyncPixelTransferDelegate* delegate =
11460 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref,
11461 tex_params);
[email protected]5b3a8e02013-03-13 05:36:4411462 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5911463
[email protected]896425e2013-06-12 17:27:1811464 delegate->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4411465 tex_params,
11466 mem_params,
11467 base::Bind(&TextureManager::SetLevelInfoFromParams,
[email protected]370eaf12013-05-18 09:19:4911468 // The callback is only invoked if the transfer delegate still
11469 // exists, which implies through manager->texture_ref->state
[email protected]5b3a8e02013-03-13 05:36:4411470 // ownership that both of these pointers are valid.
11471 base::Unretained(texture_manager()),
[email protected]370eaf12013-05-18 09:19:4911472 base::Unretained(texture_ref),
[email protected]5b3a8e02013-03-13 05:36:4411473 tex_params));
[email protected]f598f422012-12-07 08:30:0311474 return error::kNoError;
[email protected]69023942012-11-30 19:57:1611475}
11476
11477error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411478 uint32 immediate_data_size,
11479 const void* cmd_data) {
11480 const gles2::cmds::AsyncTexSubImage2DCHROMIUM& c =
11481 *static_cast<const gles2::cmds::AsyncTexSubImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1611482 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1611483 GLenum target = static_cast<GLenum>(c.target);
11484 GLint level = static_cast<GLint>(c.level);
11485 GLint xoffset = static_cast<GLint>(c.xoffset);
11486 GLint yoffset = static_cast<GLint>(c.yoffset);
11487 GLsizei width = static_cast<GLsizei>(c.width);
11488 GLsizei height = static_cast<GLsizei>(c.height);
11489 GLenum format = static_cast<GLenum>(c.format);
11490 GLenum type = static_cast<GLenum>(c.type);
[email protected]e3c4a9ab2014-03-31 09:07:0211491 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
11492 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
11493 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
11494
11495 base::ScopedClosureRunner scoped_completion_callback;
11496 if (async_upload_token) {
11497 base::Closure completion_closure =
11498 AsyncUploadTokenCompletionClosure(async_upload_token,
11499 sync_data_shm_id,
11500 sync_data_shm_offset);
11501 if (completion_closure.is_null())
11502 return error::kInvalidArguments;
11503
11504 scoped_completion_callback.Reset(completion_closure);
11505 }
[email protected]32145a92012-12-17 09:01:5911506
11507 // TODO(epenner): Move this and copies of this memory validation
11508 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1611509 uint32 data_size;
11510 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4211511 width, height, 1, format, type, state_.unpack_alignment, &data_size,
[email protected]69023942012-11-30 19:57:1611512 NULL, NULL)) {
11513 return error::kOutOfBounds;
11514 }
11515 const void* pixels = GetSharedMemoryAs<const void*>(
11516 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5911517
11518 // All the normal glTexSubImage2D validation.
11519 error::Error error = error::kNoError;
11520 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
11521 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
11522 return error;
[email protected]69023942012-11-30 19:57:1611523 }
11524
[email protected]32145a92012-12-17 09:01:5911525 // Extra async validation.
[email protected]c986af502013-08-14 01:04:4411526 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11527 &state_, target);
[email protected]370eaf12013-05-18 09:19:4911528 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5911529 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4711530 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5911531 return error::kNoError;
11532
11533 // Guarantee async textures are always 'cleared' as follows:
11534 // - AsyncTexImage2D can not redefine an existing texture
11535 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
11536 // - AsyncTexSubImage2D clears synchronously if not already cleared.
11537 // - Textures become immutable after an async call.
11538 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0711539 if (!texture->SafeToRenderFrom()) {
[email protected]370eaf12013-05-18 09:19:4911540 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
11541 target, level)) {
[email protected]ab09b612013-03-11 22:11:5111542 LOCAL_SET_GL_ERROR(
11543 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2511544 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5911545 return error::kNoError;
11546 }
11547 }
11548
[email protected]5b3a8e02013-03-13 05:36:4411549 // Setup the parameters.
[email protected]2a7568a2013-05-09 23:12:0311550 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
[email protected]32145a92012-12-17 09:01:5911551 width, height, format, type};
[email protected]c8021e02014-03-27 06:10:1211552 AsyncMemoryParams mem_params(
11553 GetSharedMemoryBuffer(c.data_shm_id), c.data_shm_offset, data_size);
[email protected]896425e2013-06-12 17:27:1811554 AsyncPixelTransferDelegate* delegate =
11555 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
11556 if (!delegate) {
[email protected]5b3a8e02013-03-13 05:36:4411557 // TODO(epenner): We may want to enforce exclusive use
11558 // of async APIs in which case this should become an error,
11559 // (the texture should have been async defined).
[email protected]2a7568a2013-05-09 23:12:0311560 AsyncTexImage2DParams define_params = {target, level,
[email protected]5b3a8e02013-03-13 05:36:4411561 0, 0, 0, 0, 0, 0};
11562 texture->GetLevelSize(target, level, &define_params.width,
11563 &define_params.height);
11564 texture->GetLevelType(target, level, &define_params.type,
11565 &define_params.internal_format);
11566 // Set up the async state if needed, and make the texture
11567 // immutable so the async state stays valid.
[email protected]896425e2013-06-12 17:27:1811568 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate(
[email protected]85a4ac22013-05-31 01:58:4711569 texture_ref, define_params);
[email protected]5b3a8e02013-03-13 05:36:4411570 texture->SetImmutable(true);
11571 }
11572
[email protected]896425e2013-06-12 17:27:1811573 delegate->AsyncTexSubImage2D(tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5911574 return error::kNoError;
[email protected]69023942012-11-30 19:57:1611575}
11576
[email protected]a00c1f742013-03-05 17:02:1611577error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411578 uint32 immediate_data_size,
11579 const void* cmd_data) {
11580 const gles2::cmds::WaitAsyncTexImage2DCHROMIUM& c =
11581 *static_cast<const gles2::cmds::WaitAsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]a00c1f742013-03-05 17:02:1611582 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
11583 GLenum target = static_cast<GLenum>(c.target);
11584
11585 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5111586 LOCAL_SET_GL_ERROR(
11587 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1611588 return error::kNoError;
11589 }
[email protected]c986af502013-08-14 01:04:4411590 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11591 &state_, target);
[email protected]370eaf12013-05-18 09:19:4911592 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111593 LOCAL_SET_GL_ERROR(
11594 GL_INVALID_OPERATION,
11595 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1611596 return error::kNoError;
11597 }
[email protected]896425e2013-06-12 17:27:1811598 AsyncPixelTransferDelegate* delegate =
11599 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
11600 if (!delegate) {
[email protected]370eaf12013-05-18 09:19:4911601 LOCAL_SET_GL_ERROR(
11602 GL_INVALID_OPERATION,
11603 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
11604 return error::kNoError;
11605 }
[email protected]896425e2013-06-12 17:27:1811606 delegate->WaitForTransferCompletion();
[email protected]69a8701e2013-03-07 21:31:0911607 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1611608 return error::kNoError;
11609}
11610
[email protected]e3c4a9ab2014-03-31 09:07:0211611error::Error GLES2DecoderImpl::HandleWaitAllAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411612 uint32 immediate_data_size,
11613 const void* data) {
[email protected]e3c4a9ab2014-03-31 09:07:0211614 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
11615
11616 GetAsyncPixelTransferManager()->WaitAllAsyncTexImage2D();
11617 ProcessFinishedAsyncTransfers();
11618 return error::kNoError;
11619}
11620
[email protected]91c94eb2013-10-22 10:32:5411621void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer(
11622 TextureRef* texture_ref) {
11623 Texture* texture = texture_ref->texture();
11624 DoDidUseTexImageIfNeeded(texture, texture->target());
11625}
11626
oetuaho37cc50e2014-10-31 11:19:2011627void GLES2DecoderImpl::OnContextLostError() {
11628 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB);
11629}
11630
[email protected]828a3932014-04-02 14:43:1311631void GLES2DecoderImpl::OnOutOfMemoryError() {
11632 if (lose_context_when_out_of_memory_) {
11633 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]828a3932014-04-02 14:43:1311634 }
11635}
11636
[email protected]96449d2c2009-11-25 00:01:3211637// Include the auto-generated part of this file. We split this because it means
11638// we can easily edit the non-auto generated parts right here in this file
11639// instead of having to edit some template or the code generator.
11640#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
11641
11642} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2511643} // namespace gpu