blob: 0e99bb9b030b5920a4fa0b81d7be50bdb28f3360 [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"
[email protected]43410e92012-04-20 17:06:2844#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
[email protected]ba3176a2009-12-16 18:19:4645#include "gpu/command_buffer/service/gles2_cmd_validation.h"
[email protected]8f9b8dd2013-09-12 18:05:1346#include "gpu/command_buffer/service/gpu_state_tracer.h"
[email protected]e844ae22012-01-14 03:36:2647#include "gpu/command_buffer/service/gpu_switches.h"
[email protected]fb97b662013-02-20 23:02:1448#include "gpu/command_buffer/service/gpu_tracer.h"
[email protected]09d50362012-10-18 20:54:3749#include "gpu/command_buffer/service/image_manager.h"
[email protected]78b514b2012-05-01 21:50:5950#include "gpu/command_buffer/service/mailbox_manager.h"
[email protected]ff6493f2012-07-31 19:52:2551#include "gpu/command_buffer/service/memory_tracking.h"
[email protected]a93bb842010-02-16 23:03:4752#include "gpu/command_buffer/service/program_manager.h"
[email protected]882ba1e22012-03-08 19:02:5353#include "gpu/command_buffer/service/query_manager.h"
[email protected]a25fa872010-03-25 02:57:5854#include "gpu/command_buffer/service/renderbuffer_manager.h"
[email protected]a93bb842010-02-16 23:03:4755#include "gpu/command_buffer/service/shader_manager.h"
[email protected]a550584e2010-09-17 18:01:4556#include "gpu/command_buffer/service/shader_translator.h"
[email protected]87fb6ab2012-06-13 22:28:0457#include "gpu/command_buffer/service/shader_translator_cache.h"
[email protected]a93bb842010-02-16 23:03:4758#include "gpu/command_buffer/service/texture_manager.h"
[email protected]944b62f32012-09-27 02:20:4659#include "gpu/command_buffer/service/vertex_array_manager.h"
[email protected]f4390962013-06-11 07:29:2260#include "gpu/command_buffer/service/vertex_attrib_manager.h"
[email protected]6896d7f2014-04-28 20:24:1561#include "third_party/smhasher/src/City.h"
[email protected]5a36dc132013-07-23 23:17:5562#include "ui/gl/gl_fence.h"
[email protected]09d50362012-10-18 20:54:3763#include "ui/gl/gl_image.h"
[email protected]c9e2cbbb2012-05-12 21:17:2764#include "ui/gl/gl_implementation.h"
65#include "ui/gl/gl_surface.h"
[email protected]423e644f2013-06-19 00:48:2766
[email protected]e51bdf32011-11-23 22:21:4667#if defined(OS_MACOSX)
[email protected]c3a6b4a2014-06-04 09:25:5368#include <IOSurface/IOSurfaceAPI.h>
69// Note that this must be included after gl_bindings.h to avoid conflicts.
70#include <OpenGL/CGLIOSurface.h>
[email protected]e51bdf32011-11-23 22:21:4671#endif
[email protected]de17df392010-04-23 21:09:4172
[email protected]6eb775352013-08-27 05:57:1673#if defined(OS_WIN)
74#include "base/win/win_util.h"
75#endif
76
[email protected]a7a27ace2009-12-12 00:11:2577namespace gpu {
[email protected]96449d2c2009-11-25 00:01:3278namespace gles2 {
79
[email protected]f0d74742011-10-03 16:31:0480namespace {
[email protected]693ca512012-11-13 18:09:1381
[email protected]f0d74742011-10-03 16:31:0482static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
[email protected]70dc60932013-06-04 03:33:4983static const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
[email protected]aff39ac82013-06-08 04:53:1384static const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
[email protected]93c2fd82014-04-16 02:46:0685static const char kEXTShaderTextureLodExtension[] = "GL_EXT_shader_texture_lod";
[email protected]693ca512012-11-13 18:09:1386
[email protected]448e459e2013-06-12 17:00:4187static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
88 GLint rangeMax,
89 GLint precision) {
90 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
91}
92
[email protected]8dc1bf92013-03-12 03:58:2193static void GetShaderPrecisionFormatImpl(GLenum shader_type,
94 GLenum precision_type,
95 GLint *range, GLint *precision) {
96 switch (precision_type) {
97 case GL_LOW_INT:
98 case GL_MEDIUM_INT:
99 case GL_HIGH_INT:
100 // These values are for a 32-bit twos-complement integer format.
101 range[0] = 31;
102 range[1] = 30;
103 *precision = 0;
104 break;
105 case GL_LOW_FLOAT:
106 case GL_MEDIUM_FLOAT:
107 case GL_HIGH_FLOAT:
108 // These values are for an IEEE single-precision floating-point format.
109 range[0] = 127;
110 range[1] = 127;
111 *precision = 23;
112 break;
113 default:
114 NOTREACHED();
115 break;
116 }
117
[email protected]8af4d5e2013-03-15 23:55:33118 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
119 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) {
[email protected]8dc1bf92013-03-12 03:58:21120 // This function is sometimes defined even though it's really just
121 // a stub, so we need to set range and precision as if it weren't
122 // defined before calling it.
[email protected]501b57402013-03-14 22:21:44123 // On Mac OS with some GPUs, calling this generates a
124 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
125 // platforms.
[email protected]8dc1bf92013-03-12 03:58:21126 glGetShaderPrecisionFormat(shader_type, precision_type,
127 range, precision);
[email protected]448e459e2013-06-12 17:00:41128
129 // TODO(brianderson): Make the following official workarounds.
130
131 // Some drivers have bugs where they report the ranges as a negative number.
132 // Taking the absolute value here shouldn't hurt because negative numbers
133 // aren't expected anyway.
134 range[0] = abs(range[0]);
135 range[1] = abs(range[1]);
136
137 // If the driver reports a precision for highp float that isn't actually
138 // highp, don't pretend like it's supported because shader compilation will
139 // fail anyway.
140 if (precision_type == GL_HIGH_FLOAT &&
141 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
142 range[0] = 0;
143 range[1] = 0;
144 *precision = 0;
145 }
[email protected]8dc1bf92013-03-12 03:58:21146 }
147}
148
[email protected]d286ebbc2014-07-03 17:19:10149static gfx::OverlayTransform GetGFXOverlayTransform(GLenum plane_transform) {
150 switch (plane_transform) {
151 case GL_OVERLAY_TRANSFORM_NONE_CHROMIUM:
152 return gfx::OVERLAY_TRANSFORM_NONE;
153 case GL_OVERLAY_TRANSFORM_FLIP_HORIZONTAL_CHROMIUM:
154 return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL;
155 case GL_OVERLAY_TRANSFORM_FLIP_VERTICAL_CHROMIUM:
156 return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL;
157 case GL_OVERLAY_TRANSFORM_ROTATE_90_CHROMIUM:
158 return gfx::OVERLAY_TRANSFORM_ROTATE_90;
159 case GL_OVERLAY_TRANSFORM_ROTATE_180_CHROMIUM:
160 return gfx::OVERLAY_TRANSFORM_ROTATE_180;
161 case GL_OVERLAY_TRANSFORM_ROTATE_270_CHROMIUM:
162 return gfx::OVERLAY_TRANSFORM_ROTATE_270;
163 default:
164 return gfx::OVERLAY_TRANSFORM_INVALID;
165 }
166}
167
[email protected]b04e24c2013-01-08 18:35:25168} // namespace
[email protected]f0d74742011-10-03 16:31:04169
[email protected]6217d392010-03-25 22:08:35170class GLES2DecoderImpl;
171
[email protected]ab09b612013-03-11 22:11:51172// Local versions of the SET_GL_ERROR macros
173#define LOCAL_SET_GL_ERROR(error, function_name, msg) \
[email protected]d3eba342013-04-18 21:11:50174 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
[email protected]ab09b612013-03-11 22:11:51175#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
[email protected]d3eba342013-04-18 21:11:50176 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
177 function_name, value, label)
[email protected]ab09b612013-03-11 22:11:51178#define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \
[email protected]d3eba342013-04-18 21:11:50179 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \
180 function_name, pname)
[email protected]ab09b612013-03-11 22:11:51181#define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
[email protected]d3eba342013-04-18 21:11:50182 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \
183 function_name)
[email protected]ab09b612013-03-11 22:11:51184#define LOCAL_PEEK_GL_ERROR(function_name) \
[email protected]d3eba342013-04-18 21:11:50185 ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51186#define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
[email protected]d3eba342013-04-18 21:11:50187 ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51188#define LOCAL_PERFORMANCE_WARNING(msg) \
189 PerformanceWarning(__FILE__, __LINE__, msg)
190#define LOCAL_RENDER_WARNING(msg) \
191 RenderWarning(__FILE__, __LINE__, msg)
192
[email protected]07f54fcc2009-12-22 02:46:30193// Check that certain assumptions the code makes are true. There are places in
194// the code where shared memory is passed direclty to GL. Example, glUniformiv,
195// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
196// a few others) are 32bits. If they are not 32bits the code will have to change
197// to call those GL functions with service side memory and then copy the results
198// to shared memory, converting the sizes.
199COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT
200 GLint_not_same_size_as_uint32);
201COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT
202 GLint_not_same_size_as_uint32);
[email protected]f7b85372010-02-03 01:11:37203COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT
204 GLfloat_not_same_size_as_float);
[email protected]07f54fcc2009-12-22 02:46:30205
[email protected]43f28f832010-02-03 02:28:48206// TODO(kbr): the use of this anonymous namespace core dumps the
207// linker on Mac OS X 10.6 when the symbol ordering file is used
208// namespace {
[email protected]96449d2c2009-11-25 00:01:32209
210// Returns the address of the first byte after a struct.
211template <typename T>
212const void* AddressAfterStruct(const T& pod) {
213 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
214}
215
[email protected]07f54fcc2009-12-22 02:46:30216// Returns the address of the frst byte after the struct or NULL if size >
217// immediate_data_size.
[email protected]96449d2c2009-11-25 00:01:32218template <typename RETURN_TYPE, typename COMMAND_TYPE>
[email protected]07f54fcc2009-12-22 02:46:30219RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
220 uint32 size,
221 uint32 immediate_data_size) {
222 return (size <= immediate_data_size) ?
223 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
224 NULL;
[email protected]96449d2c2009-11-25 00:01:32225}
226
[email protected]07f54fcc2009-12-22 02:46:30227// Computes the data size for certain gl commands like glUniform.
[email protected]a76b0052010-03-05 00:33:18228bool ComputeDataSize(
[email protected]96449d2c2009-11-25 00:01:32229 GLuint count,
230 size_t size,
[email protected]a76b0052010-03-05 00:33:18231 unsigned int elements_per_unit,
232 uint32* dst) {
233 uint32 value;
234 if (!SafeMultiplyUint32(count, size, &value)) {
235 return false;
236 }
237 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
238 return false;
239 }
240 *dst = value;
241 return true;
[email protected]96449d2c2009-11-25 00:01:32242}
243
[email protected]258a3313f2011-10-18 20:13:57244// Return true if a character belongs to the ASCII subset as defined in
245// GLSL ES 1.0 spec section 3.1.
246static bool CharacterIsValidForGLES(unsigned char c) {
247 // Printing characters are valid except " $ ` @ \ ' DEL.
248 if (c >= 32 && c <= 126 &&
249 c != '"' &&
250 c != '$' &&
251 c != '`' &&
252 c != '@' &&
253 c != '\\' &&
254 c != '\'') {
255 return true;
256 }
257 // Horizontal tab, line feed, vertical tab, form feed, carriage return
258 // are also valid.
259 if (c >= 9 && c <= 13) {
260 return true;
261 }
262
263 return false;
264}
265
266static bool StringIsValidForGLES(const char* str) {
267 for (; *str; ++str) {
268 if (!CharacterIsValidForGLES(*str)) {
269 return false;
270 }
271 }
272 return true;
273}
274
[email protected]6217d392010-03-25 22:08:35275// This class prevents any GL errors that occur when it is in scope from
276// being reported to the client.
277class ScopedGLErrorSuppressor {
278 public:
[email protected]ab09b612013-03-11 22:11:51279 explicit ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:30280 const char* function_name, ErrorState* error_state);
[email protected]6217d392010-03-25 22:08:35281 ~ScopedGLErrorSuppressor();
282 private:
[email protected]ab09b612013-03-11 22:11:51283 const char* function_name_;
[email protected]40621eb52013-10-08 15:40:30284 ErrorState* error_state_;
[email protected]6217d392010-03-25 22:08:35285 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
286};
287
[email protected]2b10c02d2014-01-29 16:43:02288// Temporarily changes a decoder's bound texture and restore it when this
[email protected]6217d392010-03-25 22:08:35289// object goes out of scope. Also temporarily switches to using active texture
290// unit zero in case the client has changed that to something invalid.
[email protected]2b10c02d2014-01-29 16:43:02291class ScopedTextureBinder {
[email protected]6217d392010-03-25 22:08:35292 public:
[email protected]00c2cf92014-03-14 00:08:37293 explicit ScopedTextureBinder(ContextState* state, GLuint id, GLenum target);
[email protected]2b10c02d2014-01-29 16:43:02294 ~ScopedTextureBinder();
[email protected]6217d392010-03-25 22:08:35295
296 private:
[email protected]ce296892013-10-24 22:04:36297 ContextState* state_;
[email protected]2b10c02d2014-01-29 16:43:02298 GLenum target_;
299 DISALLOW_COPY_AND_ASSIGN(ScopedTextureBinder);
[email protected]6217d392010-03-25 22:08:35300};
301
302// Temporarily changes a decoder's bound render buffer and restore it when this
303// object goes out of scope.
304class ScopedRenderBufferBinder {
305 public:
[email protected]00c2cf92014-03-14 00:08:37306 explicit ScopedRenderBufferBinder(ContextState* state, GLuint id);
[email protected]6217d392010-03-25 22:08:35307 ~ScopedRenderBufferBinder();
308
309 private:
[email protected]18e785a2013-10-09 03:29:41310 ContextState* state_;
[email protected]6217d392010-03-25 22:08:35311 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
312};
313
314// Temporarily changes a decoder's bound frame buffer and restore it when this
315// object goes out of scope.
316class ScopedFrameBufferBinder {
317 public:
[email protected]00c2cf92014-03-14 00:08:37318 explicit ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
[email protected]6217d392010-03-25 22:08:35319 ~ScopedFrameBufferBinder();
320
321 private:
322 GLES2DecoderImpl* decoder_;
323 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
324};
325
[email protected]34ff8b0c2010-10-01 20:06:02326// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52327// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27328// if it is bound or enforce_internal_framebuffer is true. If internal is
329// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02330class ScopedResolvedFrameBufferBinder {
331 public:
[email protected]00c2cf92014-03-14 00:08:37332 explicit ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
333 bool enforce_internal_framebuffer,
334 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02335 ~ScopedResolvedFrameBufferBinder();
336
337 private:
338 GLES2DecoderImpl* decoder_;
339 bool resolve_and_bind_;
340 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
341};
342
[email protected]00c2cf92014-03-14 00:08:37343class ScopedModifyPixels {
344 public:
345 explicit ScopedModifyPixels(TextureRef* ref);
346 ~ScopedModifyPixels();
347
348 private:
349 TextureRef* ref_;
350};
351
352ScopedModifyPixels::ScopedModifyPixels(TextureRef* ref) : ref_(ref) {
353 if (ref_)
354 ref_->texture()->OnWillModifyPixels();
355}
356
357ScopedModifyPixels::~ScopedModifyPixels() {
358 if (ref_)
359 ref_->texture()->OnDidModifyPixels();
360}
361
362class ScopedRenderTo {
363 public:
364 explicit ScopedRenderTo(Framebuffer* framebuffer);
365 ~ScopedRenderTo();
366
367 private:
368 const Framebuffer* framebuffer_;
369};
370
371ScopedRenderTo::ScopedRenderTo(Framebuffer* framebuffer)
372 : framebuffer_(framebuffer) {
373 if (framebuffer)
374 framebuffer_->OnWillRenderTo();
375}
376
377ScopedRenderTo::~ScopedRenderTo() {
378 if (framebuffer_)
379 framebuffer_->OnDidRenderTo();
380}
381
[email protected]6217d392010-03-25 22:08:35382// Encapsulates an OpenGL texture.
[email protected]ed9f9cd2013-02-27 21:12:35383class BackTexture {
[email protected]6217d392010-03-25 22:08:35384 public:
[email protected]ce296892013-10-24 22:04:36385 explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35386 ~BackTexture();
[email protected]6217d392010-03-25 22:08:35387
388 // Create a new render texture.
389 void Create();
390
391 // Set the initial size and format of a render texture or resize it.
[email protected]678a73f2012-12-19 19:22:09392 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
[email protected]6217d392010-03-25 22:08:35393
394 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58395 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35396
397 // Destroy the render texture. This must be explicitly called before
398 // destroying this object.
399 void Destroy();
400
[email protected]97872062010-11-03 19:07:05401 // Invalidate the texture. This can be used when a context is lost and it is
402 // not possible to make it current in order to free the resource.
403 void Invalidate();
404
[email protected]6217d392010-03-25 22:08:35405 GLuint id() const {
406 return id_;
407 }
408
[email protected]d37231fa2010-04-09 21:16:02409 gfx::Size size() const {
410 return size_;
411 }
412
[email protected]6217d392010-03-25 22:08:35413 private:
[email protected]ff6493f2012-07-31 19:52:25414 MemoryTypeTracker memory_tracker_;
[email protected]ce296892013-10-24 22:04:36415 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48416 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35417 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02418 gfx::Size size_;
[email protected]ed9f9cd2013-02-27 21:12:35419 DISALLOW_COPY_AND_ASSIGN(BackTexture);
[email protected]6217d392010-03-25 22:08:35420};
421
422// Encapsulates an OpenGL render buffer of any format.
[email protected]ed9f9cd2013-02-27 21:12:35423class BackRenderbuffer {
[email protected]6217d392010-03-25 22:08:35424 public:
[email protected]d5a28e452013-10-10 01:01:40425 explicit BackRenderbuffer(
426 RenderbufferManager* renderbuffer_manager,
427 MemoryTracker* memory_tracker,
428 ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35429 ~BackRenderbuffer();
[email protected]6217d392010-03-25 22:08:35430
431 // Create a new render buffer.
432 void Create();
433
434 // Set the initial size and format of a render buffer or resize it.
[email protected]f42f05b2013-11-15 21:46:18435 bool AllocateStorage(const FeatureInfo* feature_info,
436 const gfx::Size& size,
437 GLenum format,
438 GLsizei samples);
[email protected]6217d392010-03-25 22:08:35439
440 // Destroy the render buffer. This must be explicitly called before destroying
441 // this object.
442 void Destroy();
443
[email protected]97872062010-11-03 19:07:05444 // Invalidate the render buffer. This can be used when a context is lost and
445 // it is not possible to make it current in order to free the resource.
446 void Invalidate();
447
[email protected]6217d392010-03-25 22:08:35448 GLuint id() const {
449 return id_;
450 }
451
452 private:
[email protected]d5a28e452013-10-10 01:01:40453 RenderbufferManager* renderbuffer_manager_;
[email protected]ff6493f2012-07-31 19:52:25454 MemoryTypeTracker memory_tracker_;
[email protected]d5a28e452013-10-10 01:01:40455 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48456 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35457 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35458 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
[email protected]6217d392010-03-25 22:08:35459};
460
461// Encapsulates an OpenGL frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35462class BackFramebuffer {
[email protected]6217d392010-03-25 22:08:35463 public:
[email protected]ed9f9cd2013-02-27 21:12:35464 explicit BackFramebuffer(GLES2DecoderImpl* decoder);
465 ~BackFramebuffer();
[email protected]6217d392010-03-25 22:08:35466
467 // Create a new frame buffer.
468 void Create();
469
470 // Attach a color render buffer to a frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35471 void AttachRenderTexture(BackTexture* texture);
[email protected]6217d392010-03-25 22:08:35472
[email protected]b9363b22010-06-09 22:06:15473 // Attach a render buffer to a frame buffer. Note that this unbinds any
474 // currently bound frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35475 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35476
[email protected]6217d392010-03-25 22:08:35477 // Destroy the frame buffer. This must be explicitly called before destroying
478 // this object.
479 void Destroy();
480
[email protected]97872062010-11-03 19:07:05481 // Invalidate the frame buffer. This can be used when a context is lost and it
482 // is not possible to make it current in order to free the resource.
483 void Invalidate();
484
[email protected]6217d392010-03-25 22:08:35485 // See glCheckFramebufferStatusEXT.
486 GLenum CheckStatus();
487
488 GLuint id() const {
489 return id_;
490 }
491
492 private:
493 GLES2DecoderImpl* decoder_;
494 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35495 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
[email protected]6217d392010-03-25 22:08:35496};
[email protected]34ff8b0c2010-10-01 20:06:02497
[email protected]5a36dc132013-07-23 23:17:55498struct FenceCallback {
499 explicit FenceCallback()
500 : fence(gfx::GLFence::Create()) {
501 DCHECK(fence);
502 }
[email protected]5a36dc132013-07-23 23:17:55503 std::vector<base::Closure> callbacks;
504 scoped_ptr<gfx::GLFence> fence;
505};
506
[email protected]e3c4a9ab2014-03-31 09:07:02507class AsyncUploadTokenCompletionObserver
508 : public AsyncPixelTransferCompletionObserver {
509 public:
510 explicit AsyncUploadTokenCompletionObserver(uint32 async_upload_token)
511 : async_upload_token_(async_upload_token) {
512 }
513
514 virtual void DidComplete(const AsyncMemoryParams& mem_params) OVERRIDE {
dcheng6ef3c5552014-08-30 05:34:19515 DCHECK(mem_params.buffer().get());
[email protected]e3c4a9ab2014-03-31 09:07:02516 void* data = mem_params.GetDataAddress();
517 AsyncUploadSync* sync = static_cast<AsyncUploadSync*>(data);
518 sync->SetAsyncUploadToken(async_upload_token_);
519 }
520
521 private:
522 virtual ~AsyncUploadTokenCompletionObserver() {
523 }
524
525 uint32 async_upload_token_;
526
527 DISALLOW_COPY_AND_ASSIGN(AsyncUploadTokenCompletionObserver);
528};
529
[email protected]43f28f832010-02-03 02:28:48530// } // anonymous namespace.
[email protected]96449d2c2009-11-25 00:01:32531
[email protected]efc87712014-07-09 00:22:47532// static
533const unsigned int GLES2Decoder::kDefaultStencilMask =
534 static_cast<unsigned int>(-1);
535
[email protected]ddb1e5a2010-12-13 20:10:45536bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
537 uint32* service_texture_id) {
538 return false;
539}
540
[email protected]a3ded6d2010-10-19 06:44:39541GLES2Decoder::GLES2Decoder()
[email protected]55e136f2013-04-03 18:50:06542 : initialized_(false),
543 debug_(false),
[email protected]1d82e822013-04-10 21:32:32544 log_commands_(false) {
[email protected]96449d2c2009-11-25 00:01:32545}
546
[email protected]3916c97e2010-02-25 03:20:50547GLES2Decoder::~GLES2Decoder() {
548}
549
[email protected]cac16542014-01-15 17:53:51550void GLES2Decoder::BeginDecoding() {}
551
552void GLES2Decoder::EndDecoding() {}
553
[email protected]f39f4b3f2010-05-12 17:04:08554// This class implements GLES2Decoder so we don't have to expose all the GLES2
555// cmd stuff to outside this class.
[email protected]91c94eb2013-10-22 10:32:54556class GLES2DecoderImpl : public GLES2Decoder,
[email protected]828a3932014-04-02 14:43:13557 public FramebufferManager::TextureDetachObserver,
558 public ErrorStateClient {
[email protected]f39f4b3f2010-05-12 17:04:08559 public:
[email protected]aa7666122011-09-02 19:45:52560 explicit GLES2DecoderImpl(ContextGroup* group);
[email protected]b8e97b62012-09-30 15:09:00561 virtual ~GLES2DecoderImpl();
[email protected]f39f4b3f2010-05-12 17:04:08562
[email protected]96449d2c2009-11-25 00:01:32563 // Overridden from AsyncAPIInterface.
[email protected]f7a64ee2010-02-01 22:24:14564 virtual Error DoCommand(unsigned int command,
[email protected]3916c97e2010-02-25 03:20:50565 unsigned int arg_count,
[email protected]b8e97b62012-09-30 15:09:00566 const void* args) OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32567
vmiura8266ca72014-09-09 21:37:00568 virtual error::Error DoCommands(unsigned int num_commands,
569 const void* buffer,
570 int num_entries,
571 int* entries_processed) OVERRIDE;
572
vmiura1c2b1de2014-09-19 19:03:24573 template <bool DebugImpl>
574 error::Error DoCommandsImpl(unsigned int num_commands,
575 const void* buffer,
576 int num_entries,
577 int* entries_processed);
578
[email protected]96449d2c2009-11-25 00:01:32579 // Overridden from AsyncAPIInterface.
[email protected]b8e97b62012-09-30 15:09:00580 virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32581
582 // Overridden from GLES2Decoder.
[email protected]fbe20372011-06-01 01:46:38583 virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
584 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:23585 bool offscreen,
[email protected]6217d392010-03-25 22:08:35586 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:29587 const DisallowedFeatures& disallowed_features,
[email protected]b8e97b62012-09-30 15:09:00588 const std::vector<int32>& attribs) OVERRIDE;
589 virtual void Destroy(bool have_context) OVERRIDE;
[email protected]63c9b052012-05-17 18:27:38590 virtual void SetSurface(
591 const scoped_refptr<gfx::GLSurface>& surface) OVERRIDE;
[email protected]aba551b2014-02-08 03:38:32592 virtual void ProduceFrontBuffer(const Mailbox& mailbox) OVERRIDE;
[email protected]b8e97b62012-09-30 15:09:00593 virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) OVERRIDE;
[email protected]9a5afa432011-07-22 18:16:39594 void UpdateParentTextureInfo();
[email protected]b8e97b62012-09-30 15:09:00595 virtual bool MakeCurrent() OVERRIDE;
[email protected]b8e97b62012-09-30 15:09:00596 virtual GLES2Util* GetGLES2Util() OVERRIDE { return &util_; }
597 virtual gfx::GLContext* GetGLContext() OVERRIDE { return context_.get(); }
598 virtual ContextGroup* GetContextGroup() OVERRIDE { return group_.get(); }
[email protected]6d668892013-12-04 21:37:12599 virtual Capabilities GetCapabilities() OVERRIDE;
[email protected]8875a5f2014-06-27 08:33:47600 virtual void RestoreState(const ContextState* prev_state) OVERRIDE;
[email protected]29a4d902013-02-26 20:18:06601
602 virtual void RestoreActiveTexture() const OVERRIDE {
603 state_.RestoreActiveTexture();
604 }
[email protected]5baa86bc2014-01-16 04:33:16605 virtual void RestoreAllTextureUnitBindings(
606 const ContextState* prev_state) const OVERRIDE {
607 state_.RestoreAllTextureUnitBindings(prev_state);
[email protected]217004512013-05-10 21:25:55608 }
[email protected]4b2d2b262014-03-21 22:05:27609 virtual void RestoreActiveTextureUnitBinding(
610 unsigned int target) const OVERRIDE {
611 state_.RestoreActiveTextureUnitBinding(target);
612 }
[email protected]29a4d902013-02-26 20:18:06613 virtual void RestoreBufferBindings() const OVERRIDE {
614 state_.RestoreBufferBindings();
615 }
616 virtual void RestoreGlobalState() const OVERRIDE {
[email protected]88ba52f2014-04-09 12:39:34617 state_.RestoreGlobalState(NULL);
[email protected]29a4d902013-02-26 20:18:06618 }
619 virtual void RestoreProgramBindings() const OVERRIDE {
620 state_.RestoreProgramBindings();
621 }
[email protected]29a4d902013-02-26 20:18:06622 virtual void RestoreTextureUnitBindings(unsigned unit) const OVERRIDE {
[email protected]5baa86bc2014-01-16 04:33:16623 state_.RestoreTextureUnitBindings(unit, NULL);
[email protected]29a4d902013-02-26 20:18:06624 }
625 virtual void RestoreFramebufferBindings() const OVERRIDE;
[email protected]8875a5f2014-06-27 08:33:47626 virtual void RestoreRenderbufferBindings() OVERRIDE;
[email protected]29a4d902013-02-26 20:18:06627 virtual void RestoreTextureState(unsigned service_id) const OVERRIDE;
628
[email protected]cd2ef752014-02-12 23:16:03629 virtual void ClearAllAttributes() const OVERRIDE;
630 virtual void RestoreAllAttributes() const OVERRIDE;
631
[email protected]b8e97b62012-09-30 15:09:00632 virtual QueryManager* GetQueryManager() OVERRIDE {
633 return query_manager_.get();
634 }
635 virtual VertexArrayManager* GetVertexArrayManager() OVERRIDE {
[email protected]944b62f32012-09-27 02:20:46636 return vertex_array_manager_.get();
637 }
[email protected]b63f1d62014-07-18 15:40:59638 virtual ImageManager* GetImageManager() OVERRIDE {
639 return image_manager_.get();
640 }
[email protected]b8e97b62012-09-30 15:09:00641 virtual bool ProcessPendingQueries() OVERRIDE;
[email protected]2b1767cf2013-03-16 09:25:05642 virtual bool HasMoreIdleWork() OVERRIDE;
643 virtual void PerformIdleWork() OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48644
[email protected]5a36dc132013-07-23 23:17:55645 virtual void WaitForReadPixels(base::Closure callback) OVERRIDE;
646
[email protected]9d37f062011-11-22 01:24:52647 virtual void SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:07648 const base::Callback<void(gfx::Size, float)>& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00649
[email protected]1d82e822013-04-10 21:32:32650 virtual Logger* GetLogger() OVERRIDE;
[email protected]cac16542014-01-15 17:53:51651
652 virtual void BeginDecoding() OVERRIDE;
653 virtual void EndDecoding() OVERRIDE;
654
[email protected]d3eba342013-04-18 21:11:50655 virtual ErrorState* GetErrorState() OVERRIDE;
[email protected]5baa86bc2014-01-16 04:33:16656 virtual const ContextState* GetContextState() OVERRIDE { return &state_; }
[email protected]1d82e822013-04-10 21:32:32657
[email protected]e3932abb2013-03-13 00:01:37658 virtual void SetShaderCacheCallback(
659 const ShaderCacheCallback& callback) OVERRIDE;
[email protected]840a7e462013-02-27 01:29:51660 virtual void SetWaitSyncPointCallback(
661 const WaitSyncPointCallback& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00662
[email protected]85a4ac22013-05-31 01:58:47663 virtual AsyncPixelTransferManager*
664 GetAsyncPixelTransferManager() OVERRIDE;
665 virtual void ResetAsyncPixelTransferManagerForTest() OVERRIDE;
[email protected]498b5c072013-06-04 19:30:07666 virtual void SetAsyncPixelTransferManagerForTest(
667 AsyncPixelTransferManager* manager) OVERRIDE;
[email protected]454157e2014-05-03 02:49:45668 virtual void SetIgnoreCachedStateForTest(bool ignore) OVERRIDE;
[email protected]69a8701e2013-03-07 21:31:09669 void ProcessFinishedAsyncTransfers();
[email protected]32145a92012-12-17 09:01:59670
[email protected]1318e922010-09-17 22:03:16671 virtual bool GetServiceTextureId(uint32 client_texture_id,
[email protected]b8e97b62012-09-30 15:09:00672 uint32* service_texture_id) OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48673
[email protected]63b465922012-09-06 02:04:52674 virtual uint32 GetTextureUploadCount() OVERRIDE;
675 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE;
676 virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE;
[email protected]dc25dda2012-09-27 21:36:30677 virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE;
[email protected]63b465922012-09-06 02:04:52678
[email protected]8e3e0662010-08-23 18:46:30679 // Restores the current state to the user's settings.
680 void RestoreCurrentFramebufferBindings();
[email protected]8e3e0662010-08-23 18:46:30681
[email protected]297ca1c2011-06-20 23:08:46682 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
683 void ApplyDirtyState();
684
685 // These check the state of the currently bound framebuffer or the
686 // backbuffer if no framebuffer is bound.
[email protected]f3b191b2013-06-19 03:43:54687 // If all_draw_buffers is false, only check with COLOR_ATTACHMENT0, otherwise
688 // check with all attached and enabled color attachments.
689 bool BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers);
[email protected]297ca1c2011-06-20 23:08:46690 bool BoundFramebufferHasDepthAttachment();
691 bool BoundFramebufferHasStencilAttachment();
692
[email protected]b8e97b62012-09-30 15:09:00693 virtual error::ContextLostReason GetContextLostReason() OVERRIDE;
[email protected]38d139d2011-07-14 00:38:43694
[email protected]91c94eb2013-10-22 10:32:54695 // Overridden from FramebufferManager::TextureDetachObserver:
696 virtual void OnTextureRefDetachedFromFramebuffer(
697 TextureRef* texture) OVERRIDE;
698
[email protected]828a3932014-04-02 14:43:13699 // Overriden from ErrorStateClient.
700 virtual void OnOutOfMemoryError() OVERRIDE;
701
[email protected]8875a5f2014-06-27 08:33:47702 // Ensure Renderbuffer corresponding to last DoBindRenderbuffer() is bound.
703 void EnsureRenderbufferBound();
704
[email protected]f42f05b2013-11-15 21:46:18705 // Helpers to facilitate calling into compatible extensions.
706 static void RenderbufferStorageMultisampleHelper(
707 const FeatureInfo* feature_info,
708 GLenum target,
709 GLsizei samples,
710 GLenum internal_format,
711 GLsizei width,
712 GLsizei height);
713
714 void BlitFramebufferHelper(GLint srcX0,
715 GLint srcY0,
716 GLint srcX1,
717 GLint srcY1,
718 GLint dstX0,
719 GLint dstY0,
720 GLint dstX1,
721 GLint dstY1,
722 GLbitfield mask,
723 GLenum filter);
[email protected]345ba902013-11-14 21:39:00724
[email protected]96449d2c2009-11-25 00:01:32725 private:
[email protected]70d34263c2013-01-09 00:27:45726 friend class ScopedFrameBufferBinder;
[email protected]34ff8b0c2010-10-01 20:06:02727 friend class ScopedResolvedFrameBufferBinder;
[email protected]ed9f9cd2013-02-27 21:12:35728 friend class BackFramebuffer;
[email protected]6217d392010-03-25 22:08:35729
[email protected]c2f8c8402010-12-06 18:07:24730 // Initialize or re-initialize the shader translator.
731 bool InitializeShaderTranslator();
732
[email protected]302ce6d2011-07-07 23:28:11733 void UpdateCapabilities();
734
[email protected]ae51d192010-04-27 00:48:03735 // Helpers for the glGen and glDelete functions.
736 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
737 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
738 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
739 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
740 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
741 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
742 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
743 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53744 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
745 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46746 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
747 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47748
[email protected]e3c4a9ab2014-03-31 09:07:02749 // Helper for async upload token completion notification callback.
750 base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token,
751 uint32 sync_data_shm_id,
752 uint32 sync_data_shm_offset);
753
754
755
[email protected]70d34263c2013-01-09 00:27:45756 // Workarounds
757 void OnFboChanged() const;
[email protected]28718a92013-04-04 12:12:51758 void OnUseFramebuffer() const;
[email protected]70d34263c2013-01-09 00:27:45759
[email protected]3916c97e2010-02-25 03:20:50760 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50761 BufferManager* buffer_manager() {
762 return group_->buffer_manager();
763 }
764
[email protected]a25fa872010-03-25 02:57:58765 RenderbufferManager* renderbuffer_manager() {
766 return group_->renderbuffer_manager();
767 }
768
769 FramebufferManager* framebuffer_manager() {
770 return group_->framebuffer_manager();
771 }
772
[email protected]3916c97e2010-02-25 03:20:50773 ProgramManager* program_manager() {
774 return group_->program_manager();
775 }
776
777 ShaderManager* shader_manager() {
778 return group_->shader_manager();
779 }
780
[email protected]03cef9b2014-04-03 15:58:14781 ShaderTranslatorCache* shader_translator_cache() {
782 return group_->shader_translator_cache();
783 }
784
[email protected]29a4d902013-02-26 20:18:06785 const TextureManager* texture_manager() const {
786 return group_->texture_manager();
787 }
788
[email protected]3916c97e2010-02-25 03:20:50789 TextureManager* texture_manager() {
790 return group_->texture_manager();
791 }
792
[email protected]78b514b2012-05-01 21:50:59793 MailboxManager* mailbox_manager() {
794 return group_->mailbox_manager();
795 }
796
[email protected]b63f1d62014-07-18 15:40:59797 ImageManager* image_manager() { return image_manager_.get(); }
[email protected]09d50362012-10-18 20:54:37798
[email protected]944b62f32012-09-27 02:20:46799 VertexArrayManager* vertex_array_manager() {
800 return vertex_array_manager_.get();
801 }
802
[email protected]7989c9e2013-01-23 06:39:26803 MemoryTracker* memory_tracker() {
804 return group_->memory_tracker();
805 }
806
807 bool EnsureGPUMemoryAvailable(size_t estimated_size) {
808 MemoryTracker* tracker = memory_tracker();
809 if (tracker) {
810 return tracker->EnsureGPUMemoryAvailable(estimated_size);
811 }
812 return true;
813 }
814
[email protected]34ff8b0c2010-10-01 20:06:02815 bool IsOffscreenBufferMultisampled() const {
816 return offscreen_target_samples_ > 1;
817 }
818
[email protected]ed9f9cd2013-02-27 21:12:35819 // Creates a Texture for the given texture.
[email protected]370eaf12013-05-18 09:19:49820 TextureRef* CreateTexture(
[email protected]ae51d192010-04-27 00:48:03821 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35822 return texture_manager()->CreateTexture(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47823 }
824
825 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]370eaf12013-05-18 09:19:49826 TextureRef* GetTexture(GLuint client_id) const {
[email protected]02965c22013-03-09 02:40:07827 return texture_manager()->GetTexture(client_id);
[email protected]a93bb842010-02-16 23:03:47828 }
829
830 // Deletes the texture info for the given texture.
[email protected]ed9f9cd2013-02-27 21:12:35831 void RemoveTexture(GLuint client_id) {
832 texture_manager()->RemoveTexture(client_id);
[email protected]3916c97e2010-02-25 03:20:50833 }
[email protected]a93bb842010-02-16 23:03:47834
[email protected]d37231fa2010-04-09 21:16:02835 // Get the size (in pixels) of the currently bound frame buffer (either FBO
836 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30837 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02838
[email protected]9edc6b22010-12-23 02:00:26839 // Get the format of the currently bound frame buffer (either FBO or regular
840 // back buffer)
[email protected]68586372013-12-11 01:27:59841 GLenum GetBoundReadFrameBufferTextureType();
[email protected]9edc6b22010-12-23 02:00:26842 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46843 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26844
[email protected]a93bb842010-02-16 23:03:47845 // Wrapper for CompressedTexImage2D commands.
846 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37847 GLenum target,
848 GLint level,
849 GLenum internal_format,
850 GLsizei width,
851 GLsizei height,
852 GLint border,
853 GLsizei image_size,
854 const void* data);
[email protected]a93bb842010-02-16 23:03:47855
[email protected]cadde4a2010-07-31 17:10:43856 // Wrapper for CompressedTexSubImage2D.
857 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37858 GLenum target,
859 GLint level,
860 GLint xoffset,
861 GLint yoffset,
862 GLsizei width,
863 GLsizei height,
864 GLenum format,
865 GLsizei imageSize,
866 const void * data);
[email protected]cadde4a2010-07-31 17:10:43867
868 // Wrapper for CopyTexImage2D.
869 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37870 GLenum target,
871 GLint level,
872 GLenum internal_format,
873 GLint x,
874 GLint y,
875 GLsizei width,
876 GLsizei height,
877 GLint border);
[email protected]cadde4a2010-07-31 17:10:43878
[email protected]6d792ee12013-05-15 00:40:56879 // Wrapper for SwapBuffers.
880 void DoSwapBuffers();
881
[email protected]cadde4a2010-07-31 17:10:43882 // Wrapper for CopyTexSubImage2D.
883 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37884 GLenum target,
885 GLint level,
886 GLint xoffset,
887 GLint yoffset,
888 GLint x,
889 GLint y,
890 GLsizei width,
891 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43892
[email protected]f598f422012-12-07 08:30:03893 // Validation for TexSubImage2D.
894 bool ValidateTexSubImage2D(
895 error::Error* error,
896 const char* function_name,
897 GLenum target,
898 GLint level,
899 GLint xoffset,
900 GLint yoffset,
901 GLsizei width,
902 GLsizei height,
903 GLenum format,
904 GLenum type,
905 const void * data);
906
[email protected]cadde4a2010-07-31 17:10:43907 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03908 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37909 GLenum target,
910 GLint level,
911 GLint xoffset,
912 GLint yoffset,
913 GLsizei width,
914 GLsizei height,
915 GLenum format,
916 GLenum type,
917 const void * data);
[email protected]cadde4a2010-07-31 17:10:43918
[email protected]32145a92012-12-17 09:01:59919 // Extra validation for async tex(Sub)Image2D.
920 bool ValidateAsyncTransfer(
921 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:47922 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:59923 GLenum target,
924 GLint level,
925 const void * data);
926
[email protected]e51bdf32011-11-23 22:21:46927 // Wrapper for TexImageIOSurface2DCHROMIUM.
928 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37929 GLenum target,
930 GLsizei width,
931 GLsizei height,
932 GLuint io_surface_id,
933 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46934
[email protected]43410e92012-04-20 17:06:28935 void DoCopyTextureCHROMIUM(
[email protected]09d50362012-10-18 20:54:37936 GLenum target,
937 GLuint source_id,
938 GLuint target_id,
939 GLint level,
[email protected]a4a6bdd12013-04-19 20:46:54940 GLenum internal_format,
941 GLenum dest_type);
[email protected]43410e92012-04-20 17:06:28942
[email protected]97dc7cbe2011-12-06 17:26:17943 // Wrapper for TexStorage2DEXT.
944 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37945 GLenum target,
946 GLint levels,
947 GLenum internal_format,
948 GLsizei width,
949 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17950
[email protected]78b514b2012-05-01 21:50:59951 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
[email protected]43f253da2014-06-10 17:51:22952 void DoProduceTextureDirectCHROMIUM(GLuint texture, GLenum target,
953 const GLbyte* key);
954 void ProduceTextureRef(std::string func_name, TextureRef* texture_ref,
955 GLenum target, const GLbyte* data);
956
[email protected]78b514b2012-05-01 21:50:59957 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
[email protected]43f253da2014-06-10 17:51:22958 void DoCreateAndConsumeTextureCHROMIUM(GLenum target, const GLbyte* key,
959 GLuint client_id);
[email protected]78b514b2012-05-01 21:50:59960
[email protected]09d50362012-10-18 20:54:37961 void DoBindTexImage2DCHROMIUM(
962 GLenum target,
963 GLint image_id);
964 void DoReleaseTexImage2DCHROMIUM(
965 GLenum target,
966 GLint image_id);
967
[email protected]94307712012-11-16 23:26:11968 void DoTraceEndCHROMIUM(void);
969
[email protected]2f143d482013-03-14 18:04:49970 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
971
[email protected]a6a09f852014-05-23 13:05:03972 void DoLoseContextCHROMIUM(GLenum current, GLenum other);
973
kkinnunen337d59632014-08-26 10:19:57974 void DoMatrixLoadfCHROMIUM(GLenum matrix_mode, const GLfloat* matrix);
975 void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode);
976
[email protected]ed9f9cd2013-02-27 21:12:35977 // Creates a Program for the given program.
978 Program* CreateProgram(
[email protected]d685a682011-04-29 16:19:57979 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35980 return program_manager()->CreateProgram(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47981 }
982
[email protected]07f54fcc2009-12-22 02:46:30983 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35984 Program* GetProgram(GLuint client_id) {
985 return program_manager()->GetProgram(client_id);
[email protected]1d32bc82010-01-13 22:06:46986 }
[email protected]07f54fcc2009-12-22 02:46:30987
[email protected]cae20172012-12-07 00:06:19988#if defined(NDEBUG)
989 void LogClientServiceMapping(
990 const char* /* function_name */,
991 GLuint /* client_id */,
992 GLuint /* service_id */) {
993 }
994 template<typename T>
995 void LogClientServiceForInfo(
996 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
997 }
998#else
999 void LogClientServiceMapping(
1000 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:261001 if (service_logging_) {
[email protected]65f7efe2013-11-28 03:11:471002 VLOG(1) << "[" << logger_.GetLogPrefix() << "] " << function_name
1003 << ": client_id = " << client_id
1004 << ", service_id = " << service_id;
[email protected]2a22fe72012-12-07 04:21:261005 }
[email protected]cae20172012-12-07 00:06:191006 }
1007 template<typename T>
1008 void LogClientServiceForInfo(
1009 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:261010 if (info) {
[email protected]cae20172012-12-07 00:06:191011 LogClientServiceMapping(function_name, client_id, info->service_id());
1012 }
1013 }
1014#endif
1015
[email protected]6b8cf1a2010-05-06 16:13:581016 // Gets the program info for the given program. If it's not a program
1017 // generates a GL error. Returns NULL if not program.
[email protected]ed9f9cd2013-02-27 21:12:351018 Program* GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:581019 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421020 Program* program = GetProgram(client_id);
1021 if (!program) {
[email protected]ed9f9cd2013-02-27 21:12:351022 if (GetShader(client_id)) {
[email protected]ab09b612013-03-11 22:11:511023 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431024 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:581025 } else {
[email protected]ab09b612013-03-11 22:11:511026 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:581027 }
1028 }
[email protected]df37b9932013-03-08 05:21:421029 LogClientServiceForInfo(program, client_id, function_name);
1030 return program;
[email protected]6b8cf1a2010-05-06 16:13:581031 }
1032
1033
[email protected]ed9f9cd2013-02-27 21:12:351034 // Creates a Shader for the given shader.
1035 Shader* CreateShader(
[email protected]d685a682011-04-29 16:19:571036 GLuint client_id,
1037 GLuint service_id,
1038 GLenum shader_type) {
[email protected]ed9f9cd2013-02-27 21:12:351039 return shader_manager()->CreateShader(
[email protected]d685a682011-04-29 16:19:571040 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:311041 }
1042
1043 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:351044 Shader* GetShader(GLuint client_id) {
1045 return shader_manager()->GetShader(client_id);
[email protected]45bf5152010-02-12 00:11:311046 }
1047
[email protected]6b8cf1a2010-05-06 16:13:581048 // Gets the shader info for the given shader. If it's not a shader generates a
1049 // GL error. Returns NULL if not shader.
[email protected]ed9f9cd2013-02-27 21:12:351050 Shader* GetShaderInfoNotProgram(
[email protected]6b8cf1a2010-05-06 16:13:581051 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421052 Shader* shader = GetShader(client_id);
1053 if (!shader) {
[email protected]ed9f9cd2013-02-27 21:12:351054 if (GetProgram(client_id)) {
[email protected]ab09b612013-03-11 22:11:511055 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431056 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:581057 } else {
[email protected]ab09b612013-03-11 22:11:511058 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431059 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:581060 }
1061 }
[email protected]df37b9932013-03-08 05:21:421062 LogClientServiceForInfo(shader, client_id, function_name);
1063 return shader;
[email protected]6b8cf1a2010-05-06 16:13:581064 }
1065
[email protected]a93bb842010-02-16 23:03:471066 // Creates a buffer info for the given buffer.
[email protected]ed9f9cd2013-02-27 21:12:351067 void CreateBuffer(GLuint client_id, GLuint service_id) {
1068 return buffer_manager()->CreateBuffer(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:471069 }
1070
[email protected]07f54fcc2009-12-22 02:46:301071 // Gets the buffer info for the given buffer.
[email protected]16ccec12013-02-28 03:40:211072 Buffer* GetBuffer(GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:071073 Buffer* buffer = buffer_manager()->GetBuffer(client_id);
1074 return buffer;
[email protected]1d32bc82010-01-13 22:06:461075 }
[email protected]07f54fcc2009-12-22 02:46:301076
[email protected]a93bb842010-02-16 23:03:471077 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
1078 // on glDeleteBuffers so we can make sure the user does not try to render
1079 // with deleted buffers.
[email protected]ed9f9cd2013-02-27 21:12:351080 void RemoveBuffer(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:471081
[email protected]a25fa872010-03-25 02:57:581082 // Creates a framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351083 void CreateFramebuffer(GLuint client_id, GLuint service_id) {
1084 return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581085 }
1086
1087 // Gets the framebuffer info for the given framebuffer.
[email protected]4d8f0dd2013-03-09 14:37:061088 Framebuffer* GetFramebuffer(GLuint client_id) {
1089 return framebuffer_manager()->GetFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581090 }
1091
1092 // Removes the framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351093 void RemoveFramebuffer(GLuint client_id) {
1094 framebuffer_manager()->RemoveFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581095 }
1096
1097 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351098 void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
1099 return renderbuffer_manager()->CreateRenderbuffer(
[email protected]ae51d192010-04-27 00:48:031100 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581101 }
1102
1103 // Gets the renderbuffer info for the given renderbuffer.
[email protected]ee2a79c32013-03-10 03:50:271104 Renderbuffer* GetRenderbuffer(GLuint client_id) {
1105 return renderbuffer_manager()->GetRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581106 }
1107
1108 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351109 void RemoveRenderbuffer(GLuint client_id) {
1110 renderbuffer_manager()->RemoveRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581111 }
1112
[email protected]944b62f32012-09-27 02:20:461113 // Gets the vertex attrib manager for the given vertex array.
1114 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1115 VertexAttribManager* info =
1116 vertex_array_manager()->GetVertexAttribManager(client_id);
1117 return info;
1118 }
1119
1120 // Removes the vertex attrib manager for the given vertex array.
1121 void RemoveVertexAttribManager(GLuint client_id) {
1122 vertex_array_manager()->RemoveVertexAttribManager(client_id);
1123 }
1124
1125 // Creates a vertex attrib manager for the given vertex array.
[email protected]da364812014-05-09 21:39:481126 scoped_refptr<VertexAttribManager> CreateVertexAttribManager(
1127 GLuint client_id,
1128 GLuint service_id,
1129 bool client_visible) {
1130 return vertex_array_manager()->CreateVertexAttribManager(
1131 client_id, service_id, group_->max_vertex_attribs(), client_visible);
[email protected]944b62f32012-09-27 02:20:461132 }
1133
[email protected]258a3313f2011-10-18 20:13:571134 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:331135 void DoBindUniformLocationCHROMIUM(
1136 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571137
[email protected]558847a2010-03-24 07:02:541138 error::Error GetAttribLocationHelper(
1139 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1140 const std::string& name_str);
1141
1142 error::Error GetUniformLocationHelper(
1143 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1144 const std::string& name_str);
1145
[email protected]3916c97e2010-02-25 03:20:501146 // Helper for glShaderSource.
1147 error::Error ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:031148 GLuint client_id, const char* data, uint32 data_size);
[email protected]07f54fcc2009-12-22 02:46:301149
[email protected]0d6bfdc2011-11-02 01:32:201150 // Clear any textures used by the current program.
1151 bool ClearUnclearedTextures();
1152
[email protected]0d6bfdc2011-11-02 01:32:201153 // Clears any uncleared attachments attached to the given frame buffer.
1154 // Returns false if there was a generated GL error.
[email protected]4d8f0dd2013-03-09 14:37:061155 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
[email protected]3a2e7c7b2010-08-06 01:12:281156
[email protected]0d6bfdc2011-11-02 01:32:201157 // overridden from GLES2Decoder
[email protected]b8e97b62012-09-30 15:09:001158 virtual bool ClearLevel(unsigned service_id,
1159 unsigned bind_target,
1160 unsigned target,
1161 int level,
[email protected]d8e6c9242014-02-20 16:56:251162 unsigned internal_format,
[email protected]b8e97b62012-09-30 15:09:001163 unsigned format,
1164 unsigned type,
1165 int width,
1166 int height,
1167 bool is_texture_immutable) OVERRIDE;
[email protected]0d6bfdc2011-11-02 01:32:201168
[email protected]c007aa02010-09-02 22:22:401169 // Restore all GL state that affects clearing.
1170 void RestoreClearState();
1171
[email protected]3a2e7c7b2010-08-06 01:12:281172 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461173 // Returns: true if glEnable/glDisable should actually be called.
1174 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281175
[email protected]0d6bfdc2011-11-02 01:32:201176 // Check that the currently bound framebuffers are valid.
1177 // Generates GL error if not.
1178 bool CheckBoundFramebuffersValid(const char* func_name);
1179
[email protected]2ea5950d2014-07-09 18:20:341180 // Check that the currently bound read framebuffer has a color image
1181 // attached. Generates GL error if not.
1182 bool CheckBoundReadFramebufferColorAttachment(const char* func_name);
1183
[email protected]0d6bfdc2011-11-02 01:32:201184 // Check if a framebuffer meets our requirements.
1185 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351186 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201187 GLenum target,
1188 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271189
[email protected]939e7362010-05-13 20:49:101190 // Checks if the current program exists and is valid. If not generates the
1191 // appropriate GL error. Returns true if the current program is in a usable
1192 // state.
1193 bool CheckCurrentProgram(const char* function_name);
1194
1195 // Checks if the current program exists and is valid and that location is not
1196 // -1. If the current program is not valid generates the appropriate GL
1197 // error. Returns true if the current program is in a usable state and
1198 // location is not -1.
1199 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1200
1201 // Gets the type of a uniform for a location in the current program. Sets GL
1202 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361203 // program is valid and the location exists. Adjusts count so it
1204 // does not overflow the uniform.
[email protected]9b1f1b52014-03-12 10:40:131205 bool PrepForSetUniformByLocation(GLint fake_location,
1206 const char* function_name,
1207 Program::UniformApiType api_type,
1208 GLint* real_location,
1209 GLenum* type,
1210 GLsizei* count);
[email protected]939e7362010-05-13 20:49:101211
[email protected]b177ae22011-11-01 03:29:111212 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021213 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111214
[email protected]b273e432010-04-12 17:23:581215 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1216 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1217
[email protected]ac77603c72013-03-08 13:52:061218 // Helper for glGetVertexAttrib
1219 void GetVertexAttribHelper(
1220 const VertexAttrib* attrib, GLenum pname, GLint* param);
1221
[email protected]96449d2c2009-11-25 00:01:321222 // Wrapper for glCreateProgram
[email protected]ae51d192010-04-27 00:48:031223 bool CreateProgramHelper(GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321224
1225 // Wrapper for glCreateShader
[email protected]ae51d192010-04-27 00:48:031226 bool CreateShaderHelper(GLenum type, GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321227
[email protected]3916c97e2010-02-25 03:20:501228 // Wrapper for glActiveTexture
1229 void DoActiveTexture(GLenum texture_unit);
1230
[email protected]ae51d192010-04-27 00:48:031231 // Wrapper for glAttachShader
1232 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1233
[email protected]96449d2c2009-11-25 00:01:321234 // Wrapper for glBindBuffer since we need to track the current targets.
1235 void DoBindBuffer(GLenum target, GLuint buffer);
1236
[email protected]86093972010-03-11 00:13:561237 // Wrapper for glBindFramebuffer since we need to track the current targets.
1238 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1239
1240 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1241 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1242
[email protected]a93bb842010-02-16 23:03:471243 // Wrapper for glBindTexture since we need to track the current targets.
1244 void DoBindTexture(GLenum target, GLuint texture);
1245
[email protected]944b62f32012-09-27 02:20:461246 // Wrapper for glBindVertexArrayOES
1247 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571248 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461249
[email protected]49cabed2013-11-13 18:15:181250 // Wrapper for glBlitFramebufferCHROMIUM.
1251 void DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301252 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1253 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1254 GLbitfield mask, GLenum filter);
1255
[email protected]36cef8ce2010-03-16 07:34:451256 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111257 void DoBufferSubData(
1258 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1259
[email protected]36cef8ce2010-03-16 07:34:451260 // Wrapper for glCheckFramebufferStatus
1261 GLenum DoCheckFramebufferStatus(GLenum target);
1262
[email protected]3a03a8f2011-03-19 00:51:271263 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081264 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271265
[email protected]88a61bf2012-10-27 13:00:421266 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421267 void DoDepthRangef(GLclampf znear, GLclampf zfar);
[email protected]b04e24c2013-01-08 18:35:251268 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281269
[email protected]45bf5152010-02-12 00:11:311270 // Wrapper for glCompileShader.
1271 void DoCompileShader(GLuint shader);
1272
[email protected]269200b12010-11-18 22:53:061273 // Helper for DeleteSharedIdsCHROMIUM commands.
1274 void DoDeleteSharedIdsCHROMIUM(
1275 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101276
[email protected]ae51d192010-04-27 00:48:031277 // Wrapper for glDetachShader
1278 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1279
[email protected]3a2e7c7b2010-08-06 01:12:281280 // Wrapper for glDisable
1281 void DoDisable(GLenum cap);
1282
[email protected]07f54fcc2009-12-22 02:46:301283 // Wrapper for glDisableVertexAttribArray.
1284 void DoDisableVertexAttribArray(GLuint index);
1285
[email protected]60f22d32012-12-12 00:31:581286 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1287 // attachments.
1288 void DoDiscardFramebufferEXT(GLenum target,
1289 GLsizei numAttachments,
1290 const GLenum* attachments);
1291
[email protected]3a2e7c7b2010-08-06 01:12:281292 // Wrapper for glEnable
1293 void DoEnable(GLenum cap);
1294
[email protected]07f54fcc2009-12-22 02:46:301295 // Wrapper for glEnableVertexAttribArray.
1296 void DoEnableVertexAttribArray(GLuint index);
1297
[email protected]882ba1e22012-03-08 19:02:531298 // Wrapper for glFinish.
1299 void DoFinish();
1300
1301 // Wrapper for glFlush.
1302 void DoFlush();
1303
[email protected]36cef8ce2010-03-16 07:34:451304 // Wrapper for glFramebufferRenderbufffer.
1305 void DoFramebufferRenderbuffer(
1306 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1307 GLuint renderbuffer);
1308
1309 // Wrapper for glFramebufferTexture2D.
1310 void DoFramebufferTexture2D(
1311 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1312 GLint level);
1313
[email protected]7d3c36e2013-07-12 14:13:161314 // Wrapper for glFramebufferTexture2DMultisampleEXT.
1315 void DoFramebufferTexture2DMultisample(
1316 GLenum target, GLenum attachment, GLenum textarget,
1317 GLuint texture, GLint level, GLsizei samples);
1318
1319 // Common implementation for both DoFramebufferTexture2D wrappers.
1320 void DoFramebufferTexture2DCommon(const char* name,
1321 GLenum target, GLenum attachment, GLenum textarget,
1322 GLuint texture, GLint level, GLsizei samples);
1323
[email protected]a93bb842010-02-16 23:03:471324 // Wrapper for glGenerateMipmap
1325 void DoGenerateMipmap(GLenum target);
1326
[email protected]269200b12010-11-18 22:53:061327 // Helper for GenSharedIdsCHROMIUM commands.
1328 void DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:101329 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids);
1330
[email protected]7d3c36e2013-07-12 14:13:161331 // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname
1332 // to account for different pname values defined in different extension
1333 // variants.
1334 GLenum AdjustGetPname(GLenum pname);
1335
[email protected]b273e432010-04-12 17:23:581336 // Wrapper for DoGetBooleanv.
1337 void DoGetBooleanv(GLenum pname, GLboolean* params);
1338
1339 // Wrapper for DoGetFloatv.
1340 void DoGetFloatv(GLenum pname, GLfloat* params);
1341
[email protected]36cef8ce2010-03-16 07:34:451342 // Wrapper for glGetFramebufferAttachmentParameteriv.
1343 void DoGetFramebufferAttachmentParameteriv(
1344 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1345
[email protected]a0c3e972010-04-21 00:49:131346 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581347 void DoGetIntegerv(GLenum pname, GLint* params);
1348
[email protected]29a9eb52010-04-13 09:04:231349 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061350 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231351 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1352
[email protected]17cfbe0e2013-03-07 01:26:081353 // Wrapper for glGetBufferParameteriv.
1354 void DoGetBufferParameteriv(
1355 GLenum target, GLenum pname, GLint* params);
1356
[email protected]a0c3e972010-04-21 00:49:131357 // Wrapper for glGetProgramiv.
1358 void DoGetProgramiv(
1359 GLuint program_id, GLenum pname, GLint* params);
1360
[email protected]36cef8ce2010-03-16 07:34:451361 // Wrapper for glRenderbufferParameteriv.
1362 void DoGetRenderbufferParameteriv(
1363 GLenum target, GLenum pname, GLint* params);
1364
[email protected]ddd968b82010-03-02 00:44:291365 // Wrapper for glGetShaderiv
1366 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1367
[email protected]4c6f5462014-03-05 00:26:561368 // Wrappers for glGetTexParameter.
1369 void DoGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
1370 void DoGetTexParameteriv(GLenum target, GLenum pname, GLint* params);
1371 void InitTextureMaxAnisotropyIfNeeded(GLenum target, GLenum pname);
1372
[email protected]b1122982010-05-17 23:04:241373 // Wrappers for glGetVertexAttrib.
1374 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1375 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1376
[email protected]1958e0e2010-04-22 05:17:151377 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241378 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151379 bool DoIsBuffer(GLuint client_id);
1380 bool DoIsFramebuffer(GLuint client_id);
1381 bool DoIsProgram(GLuint client_id);
1382 bool DoIsRenderbuffer(GLuint client_id);
1383 bool DoIsShader(GLuint client_id);
1384 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461385 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151386
[email protected]07f54fcc2009-12-22 02:46:301387 // Wrapper for glLinkProgram
1388 void DoLinkProgram(GLuint program);
1389
[email protected]269200b12010-11-18 22:53:061390 // Helper for RegisterSharedIdsCHROMIUM.
1391 void DoRegisterSharedIdsCHROMIUM(
1392 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101393
[email protected]36cef8ce2010-03-16 07:34:451394 // Wrapper for glRenderbufferStorage.
1395 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031396 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451397
[email protected]49cabed2013-11-13 18:15:181398 // Handler for glRenderbufferStorageMultisampleCHROMIUM.
1399 void DoRenderbufferStorageMultisampleCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301400 GLenum target, GLsizei samples, GLenum internalformat,
1401 GLsizei width, GLsizei height);
1402
[email protected]49cabed2013-11-13 18:15:181403 // Handler for glRenderbufferStorageMultisampleEXT
1404 // (multisampled_render_to_texture).
1405 void DoRenderbufferStorageMultisampleEXT(
1406 GLenum target, GLsizei samples, GLenum internalformat,
1407 GLsizei width, GLsizei height);
1408
1409 // Common validation for multisample extensions.
1410 bool ValidateRenderbufferStorageMultisample(GLsizei samples,
1411 GLenum internalformat,
1412 GLsizei width,
1413 GLsizei height);
1414
[email protected]4a4c18b2013-09-13 22:50:101415 // Verifies that the currently bound multisample renderbuffer is valid
1416 // Very slow! Only done on platforms with driver bugs that return invalid
1417 // buffers under memory pressure
1418 bool VerifyMultisampleRenderbufferIntegrity(
1419 GLuint renderbuffer, GLenum format);
1420
[email protected]b273e432010-04-12 17:23:581421 // Wrapper for glReleaseShaderCompiler.
1422 void DoReleaseShaderCompiler() { }
1423
[email protected]3916c97e2010-02-25 03:20:501424 // Wrappers for glTexParameter functions.
1425 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1426 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1427 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1428 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1429
1430 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1431 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121432 void DoUniform1i(GLint fake_location, GLint v0);
1433 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1434 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1435 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1436 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101437
1438 // Wrappers for glUniformfv because some drivers don't correctly accept
1439 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121440 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1441 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1442 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1443 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501444
[email protected]43c2f1f2011-03-25 18:35:361445 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121446 GLint fake_location, GLsizei count, GLboolean transpose,
1447 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361448 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121449 GLint fake_location, GLsizei count, GLboolean transpose,
1450 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361451 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121452 GLint fake_location, GLsizei count, GLboolean transpose,
1453 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361454
[email protected]af6380962012-11-29 23:24:131455 bool SetVertexAttribValue(
1456 const char* function_name, GLuint index, const GLfloat* value);
1457
[email protected]b1122982010-05-17 23:04:241458 // Wrappers for glVertexAttrib??
1459 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1460 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1461 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1462 void DoVertexAttrib4f(
1463 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1464 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1465 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1466 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1467 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1468
[email protected]43410e92012-04-20 17:06:281469 // Wrapper for glViewport
1470 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1471
[email protected]07f54fcc2009-12-22 02:46:301472 // Wrapper for glUseProgram
1473 void DoUseProgram(GLuint program);
1474
[email protected]ae51d192010-04-27 00:48:031475 // Wrapper for glValidateProgram.
1476 void DoValidateProgram(GLuint program_client_id);
1477
[email protected]d2a0e1a2012-08-12 02:25:011478 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1479 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1480 void DoPopGroupMarkerEXT(void);
1481
[email protected]4e8a5b122010-05-08 22:00:101482 // Gets the number of values that will be returned by glGetXXX. Returns
1483 // false if pname is unknown.
1484 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1485
[email protected]07f54fcc2009-12-22 02:46:301486 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431487 bool IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:101488 const char* function_name, GLuint max_vertex_accessed, bool instanced,
1489 GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301490
[email protected]c13e1da62011-09-09 21:48:301491 // Returns true if successful, simulated will be true if attrib0 was
1492 // simulated.
[email protected]c6aef902012-02-14 03:31:421493 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431494 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]3fc38e22014-05-30 00:13:231495 void RestoreStateForAttrib(GLuint attrib, bool restore_array_binding);
[email protected]b1122982010-05-17 23:04:241496
[email protected]91c94eb2013-10-22 10:32:541497 // If an image is bound to texture, this will call Will/DidUseTexImage
1498 // if needed.
1499 void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1500 void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1501
1502 // Returns false if textures were replaced.
[email protected]e56131d22013-07-28 16:14:111503 bool PrepareTexturesForRender();
[email protected]91c94eb2013-10-22 10:32:541504 void RestoreStateForTextures();
[email protected]3916c97e2010-02-25 03:20:501505
[email protected]8fbedc02010-11-18 18:43:401506 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421507 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431508 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421509 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401510 void RestoreStateForSimulatedFixedAttribs();
1511
[email protected]c6aef902012-02-14 03:31:421512 // Handle DrawArrays and DrawElements for both instanced and non-instanced
[email protected]ac6904d62014-07-30 12:00:101513 // cases (primcount is always 1 for non-instanced).
[email protected]c6aef902012-02-14 03:31:421514 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431515 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421516 bool instanced, GLenum mode, GLint first, GLsizei count,
1517 GLsizei primcount);
1518 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431519 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421520 bool instanced, GLenum mode, GLsizei count, GLenum type,
1521 int32 offset, GLsizei primcount);
1522
[email protected]61eeb33f2011-07-26 15:30:311523 GLenum GetBindTargetForSamplerType(GLenum type) {
1524 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461525 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1526 switch (type) {
1527 case GL_SAMPLER_2D:
1528 return GL_TEXTURE_2D;
1529 case GL_SAMPLER_CUBE:
1530 return GL_TEXTURE_CUBE_MAP;
1531 case GL_SAMPLER_EXTERNAL_OES:
1532 return GL_TEXTURE_EXTERNAL_OES;
1533 case GL_SAMPLER_2D_RECT_ARB:
1534 return GL_TEXTURE_RECTANGLE_ARB;
1535 }
1536
1537 NOTREACHED();
1538 return 0;
[email protected]61eeb33f2011-07-26 15:30:311539 }
1540
[email protected]8e3e0662010-08-23 18:46:301541 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061542 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1543 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301544 switch (target) {
1545 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451546 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341547 framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301548 break;
[email protected]ebfb73c2012-08-15 02:37:451549 case GL_READ_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341550 framebuffer = framebuffer_state_.bound_read_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301551 break;
1552 default:
1553 NOTREACHED();
1554 break;
1555 }
[email protected]4d8f0dd2013-03-09 14:37:061556 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301557 }
1558
[email protected]ed9f9cd2013-02-27 21:12:351559 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201560 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271561 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201562 switch (target) {
1563 case GL_RENDERBUFFER:
[email protected]7cd76fd2013-06-02 21:11:111564 renderbuffer = state_.bound_renderbuffer.get();
[email protected]0d6bfdc2011-11-02 01:32:201565 break;
1566 default:
1567 NOTREACHED();
1568 break;
1569 }
[email protected]ee2a79c32013-03-10 03:50:271570 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201571 }
1572
[email protected]f7b85372010-02-03 01:11:371573 // Validates the program and location for a glGetUniform call and returns
1574 // a SizeResult setup to receive the result. Returns true if glGetUniform
1575 // should be called.
1576 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121577 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371578 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121579 error::Error* error, GLint* real_location, GLuint* service_id,
1580 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371581
[email protected]a10b4a02012-11-26 23:09:501582 virtual bool WasContextLost() OVERRIDE;
[email protected]93a7d98f2013-07-11 00:04:221583 virtual bool WasContextLostByRobustnessExtension() OVERRIDE;
[email protected]c4485aad62012-12-17 10:19:091584 virtual void LoseContext(uint32 reset_status) OVERRIDE;
[email protected]38d139d2011-07-14 00:38:431585
[email protected]e51bdf32011-11-23 22:21:461586#if defined(OS_MACOSX)
1587 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1588#endif
1589
[email protected]ad84a3a2012-06-08 21:42:431590 bool ValidateCompressedTexDimensions(
1591 const char* function_name,
1592 GLint level, GLsizei width, GLsizei height, GLenum format);
1593 bool ValidateCompressedTexFuncData(
1594 const char* function_name,
1595 GLsizei width, GLsizei height, GLenum format, size_t size);
1596 bool ValidateCompressedTexSubDimensions(
1597 const char* function_name,
1598 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1599 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351600 Texture* texture);
[email protected]ad84a3a2012-06-08 21:42:431601
[email protected]ab09b612013-03-11 22:11:511602 void RenderWarning(const char* filename, int line, const std::string& msg);
1603 void PerformanceWarning(
1604 const char* filename, int line, const std::string& msg);
[email protected]0f8afe82012-05-14 23:43:011605
[email protected]62e155e2012-10-23 22:43:151606 const FeatureInfo::FeatureFlags& features() const {
1607 return feature_info_->feature_flags();
1608 }
1609
1610 const FeatureInfo::Workarounds& workarounds() const {
1611 return feature_info_->workarounds();
1612 }
1613
[email protected]a7266a92012-06-28 02:11:081614 bool ShouldDeferDraws() {
1615 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341616 framebuffer_state_.bound_draw_framebuffer.get() == NULL &&
[email protected]a7266a92012-06-28 02:11:081617 surface_->DeferDraws();
1618 }
1619
[email protected]09e17272012-11-30 10:30:441620 bool ShouldDeferReads() {
1621 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341622 framebuffer_state_.bound_read_framebuffer.get() == NULL &&
[email protected]09e17272012-11-30 10:30:441623 surface_->DeferDraws();
1624 }
1625
[email protected]c76fe672013-12-13 23:30:221626 error::Error WillAccessBoundFramebufferForDraw() {
1627 if (ShouldDeferDraws())
1628 return error::kDeferCommandUntilLater;
1629 if (!offscreen_target_frame_buffer_.get() &&
1630 !framebuffer_state_.bound_draw_framebuffer.get() &&
1631 !surface_->SetBackbufferAllocation(true))
1632 return error::kLostContext;
1633 return error::kNoError;
1634 }
1635
1636 error::Error WillAccessBoundFramebufferForRead() {
1637 if (ShouldDeferReads())
1638 return error::kDeferCommandUntilLater;
1639 if (!offscreen_target_frame_buffer_.get() &&
1640 !framebuffer_state_.bound_read_framebuffer.get() &&
1641 !surface_->SetBackbufferAllocation(true))
1642 return error::kLostContext;
1643 return error::kNoError;
1644 }
1645
vmiura8266ca72014-09-09 21:37:001646 // Set remaining commands to process to 0 to force DoCommands to return
1647 // and allow context preemption and GPU watchdog checks in GpuScheduler().
1648 void ExitCommandProcessingEarly() { commands_to_process_ = 0; }
1649
[email protected]5a36dc132013-07-23 23:17:551650 void ProcessPendingReadPixels();
1651 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
1652
[email protected]96449d2c2009-11-25 00:01:321653 // Generate a member function prototype for each command in an automated and
1654 // typesafe way.
vmiuracd108592014-09-08 14:36:341655#define GLES2_CMD_OP(name) \
1656 Error Handle##name(uint32 immediate_data_size, const void* data);
[email protected]96449d2c2009-11-25 00:01:321657
1658 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1659
1660 #undef GLES2_CMD_OP
1661
[email protected]2f2d7042010-04-14 21:45:581662 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381663 scoped_refptr<gfx::GLSurface> surface_;
1664 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021665
[email protected]a3ded6d2010-10-19 06:44:391666 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351667 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391668
[email protected]1d82e822013-04-10 21:32:321669 DebugMarkerManager debug_marker_manager_;
1670 Logger logger_;
1671
[email protected]e259eb412012-10-13 05:47:241672 // All the state for this context.
1673 ContextState state_;
1674
[email protected]34ff8b0c2010-10-01 20:06:021675 // Current width and height of the offscreen frame buffer.
1676 gfx::Size offscreen_size_;
1677
[email protected]96449d2c2009-11-25 00:01:321678 // Util to help with GL.
1679 GLES2Util util_;
1680
[email protected]43410e92012-04-20 17:06:281681 // unpack flip y as last set by glPixelStorei
1682 bool unpack_flip_y_;
1683
[email protected]6c75c712012-06-19 15:43:171684 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281685 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171686 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281687
[email protected]b1122982010-05-17 23:04:241688 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1689 GLuint attrib_0_buffer_id_;
1690
1691 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131692 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241693
[email protected]fc753442011-02-04 19:49:491694 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1695 bool attrib_0_buffer_matches_value_;
1696
[email protected]b1122982010-05-17 23:04:241697 // The size of attrib 0.
1698 GLsizei attrib_0_size_;
1699
[email protected]8fbedc02010-11-18 18:43:401700 // The buffer used to simulate GL_FIXED attribs.
1701 GLuint fixed_attrib_buffer_id_;
1702
1703 // The size of fiixed attrib buffer.
1704 GLsizei fixed_attrib_buffer_size_;
1705
[email protected]b9363b22010-06-09 22:06:151706 // The offscreen frame buffer that the client renders to. With EGL, the
1707 // depth and stencil buffers are separate. With regular GL there is a single
1708 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1709 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351710 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1711 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1712 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1713 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1714 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021715 GLenum offscreen_target_color_format_;
1716 GLenum offscreen_target_depth_format_;
1717 GLenum offscreen_target_stencil_format_;
1718 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561719 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351720
[email protected]de26b3c2011-08-03 21:54:271721 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351722 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1723 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
[email protected]370eaf12013-05-18 09:19:491724 scoped_refptr<TextureRef>
[email protected]ed9f9cd2013-02-27 21:12:351725 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271726
1727 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351728 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1729 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051730 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351731
[email protected]882ba1e22012-03-08 19:02:531732 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531733
[email protected]944b62f32012-09-27 02:20:461734 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1735
[email protected]b63f1d62014-07-18 15:40:591736 scoped_ptr<ImageManager> image_manager_;
1737
[email protected]729c0b42013-05-26 02:05:071738 base::Callback<void(gfx::Size, float)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001739
[email protected]840a7e462013-02-27 01:29:511740 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481741
[email protected]e3932abb2013-03-13 00:01:371742 ShaderCacheCallback shader_cache_callback_;
1743
[email protected]85a4ac22013-05-31 01:58:471744 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
[email protected]b0af4f52011-09-28 22:04:421745
[email protected]32fe9aa2011-01-21 23:47:131746 // The format of the back buffer_
1747 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461748 bool back_buffer_has_depth_;
1749 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131750
achaulkcf5316f2014-09-26 19:28:421751 bool surfaceless_;
1752
[email protected]60f22d32012-12-12 00:31:581753 // Backbuffer attachments that are currently undefined.
1754 uint32 backbuffer_needs_clear_bits_;
1755
[email protected]a6a09f852014-05-23 13:05:031756 // The current decoder error communicates the decoder error through command
1757 // processing functions that do not return the error value. Should be set only
1758 // if not returning an error.
[email protected]a3a93e7b2010-08-28 00:48:561759 error::Error current_decoder_error_;
1760
[email protected]b1d2dcb2010-05-17 19:24:181761 bool use_shader_translator_;
[email protected]87fb6ab2012-06-13 22:28:041762 scoped_refptr<ShaderTranslator> vertex_translator_;
1763 scoped_refptr<ShaderTranslator> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181764
[email protected]e82fb792011-09-22 00:33:291765 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411766
[email protected]915a59a12010-09-30 21:29:111767 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051768 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351769 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051770
[email protected]65225772011-05-12 21:10:241771 int frame_number_;
1772
vmiura8266ca72014-09-09 21:37:001773 // Number of commands remaining to be processed in DoCommands().
1774 int commands_to_process_;
1775
[email protected]706b69f2012-07-27 04:59:301776 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431777 GLenum reset_status_;
[email protected]93a7d98f2013-07-11 00:04:221778 bool reset_by_robustness_extension_;
[email protected]b381ee32014-03-22 02:43:431779 bool supports_post_sub_buffer_;
[email protected]38d139d2011-07-14 00:38:431780
[email protected]f0d74742011-10-03 16:31:041781 // These flags are used to override the state of the shared feature_info_
1782 // member. Because the same FeatureInfo instance may be shared among many
1783 // contexts, the assumptions on the availablity of extensions in WebGL
1784 // contexts may be broken. These flags override the shared state to preserve
1785 // WebGL semantics.
1786 bool force_webgl_glsl_validation_;
1787 bool derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:491788 bool frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:131789 bool draw_buffers_explicitly_enabled_;
[email protected]93c2fd82014-04-16 02:46:061790 bool shader_texture_lod_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:041791
[email protected]062c38b2012-01-18 03:25:101792 bool compile_shader_always_succeeds_;
1793
[email protected]828a3932014-04-02 14:43:131794 // An optional behaviour to lose the context and group when OOM.
1795 bool lose_context_when_out_of_memory_;
1796
[email protected]cae20172012-12-07 00:06:191797 // Log extra info.
1798 bool service_logging_;
1799
[email protected]e51bdf32011-11-23 22:21:461800#if defined(OS_MACOSX)
[email protected]c3a6b4a2014-06-04 09:25:531801 typedef std::map<GLuint, IOSurfaceRef> TextureToIOSurfaceMap;
[email protected]e51bdf32011-11-23 22:21:461802 TextureToIOSurfaceMap texture_to_io_surface_map_;
1803#endif
1804
[email protected]43410e92012-04-20 17:06:281805 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
1806
[email protected]1868a342012-11-07 15:56:021807 // Cached values of the currently assigned viewport dimensions.
1808 GLsizei viewport_max_width_;
1809 GLsizei viewport_max_height_;
1810
[email protected]63b465922012-09-06 02:04:521811 // Command buffer stats.
[email protected]63b465922012-09-06 02:04:521812 base::TimeDelta total_processing_commands_time_;
1813
[email protected]c986af502013-08-14 01:04:441814 // States related to each manager.
1815 DecoderTextureState texture_state_;
1816 DecoderFramebufferState framebuffer_state_;
1817
[email protected]fb97b662013-02-20 23:02:141818 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]8f9b8dd2013-09-12 18:05:131819 scoped_ptr<GPUStateTracer> gpu_state_tracer_;
vmiura1c2b1de2014-09-19 19:03:241820 const unsigned char* cb_command_trace_category_;
[email protected]cac16542014-01-15 17:53:511821 int gpu_trace_level_;
1822 bool gpu_trace_commands_;
vmiura1c2b1de2014-09-19 19:03:241823 bool gpu_debug_commands_;
[email protected]94307712012-11-16 23:26:111824
[email protected]5a36dc132013-07-23 23:17:551825 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_;
1826
[email protected]4a4c18b2013-09-13 22:50:101827 // Used to validate multisample renderbuffers if needed
1828 GLuint validation_texture_;
1829 GLuint validation_fbo_multisample_;
1830 GLuint validation_fbo_;
1831
vmiuracd108592014-09-08 14:36:341832 typedef gpu::gles2::GLES2Decoder::Error (GLES2DecoderImpl::*CmdHandler)(
1833 uint32 immediate_data_size,
1834 const void* data);
1835
1836 // A struct to hold info about each command.
1837 struct CommandInfo {
1838 CmdHandler cmd_handler;
1839 uint8 arg_flags; // How to handle the arguments for this command
1840 uint8 cmd_flags; // How to handle this command
1841 uint16 arg_count; // How many arguments are expected for this command.
1842 };
1843
1844 // A table of CommandInfo for all the commands.
1845 static const CommandInfo command_info[kNumCommands - kStartPoint];
1846
[email protected]96449d2c2009-11-25 00:01:321847 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1848};
1849
vmiuracd108592014-09-08 14:36:341850const GLES2DecoderImpl::CommandInfo GLES2DecoderImpl::command_info[] = {
1851#define GLES2_CMD_OP(name) \
1852 { \
1853 &GLES2DecoderImpl::Handle##name, cmds::name::kArgFlags, \
1854 cmds::name::cmd_flags, \
1855 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, \
1856 } \
1857 , /* NOLINT */
1858 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1859#undef GLES2_CMD_OP
1860};
1861
[email protected]ab09b612013-03-11 22:11:511862ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:301863 const char* function_name, ErrorState* error_state)
[email protected]ab09b612013-03-11 22:11:511864 : function_name_(function_name),
[email protected]40621eb52013-10-08 15:40:301865 error_state_(error_state) {
1866 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351867}
1868
1869ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]40621eb52013-10-08 15:40:301870 ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351871}
1872
[email protected]2b10c02d2014-01-29 16:43:021873static void RestoreCurrentTextureBindings(ContextState* state, GLenum target) {
[email protected]ce296892013-10-24 22:04:361874 TextureUnit& info = state->texture_units[0];
1875 GLuint last_id;
[email protected]2b10c02d2014-01-29 16:43:021876 scoped_refptr<TextureRef> texture_ref;
1877 switch (target) {
1878 case GL_TEXTURE_2D:
1879 texture_ref = info.bound_texture_2d;
1880 break;
1881 case GL_TEXTURE_CUBE_MAP:
1882 texture_ref = info.bound_texture_cube_map;
1883 break;
1884 case GL_TEXTURE_EXTERNAL_OES:
1885 texture_ref = info.bound_texture_external_oes;
1886 break;
1887 case GL_TEXTURE_RECTANGLE_ARB:
1888 texture_ref = info.bound_texture_rectangle_arb;
1889 break;
1890 default:
1891 NOTREACHED();
1892 break;
1893 }
1894 if (texture_ref.get()) {
1895 last_id = texture_ref->service_id();
[email protected]ce296892013-10-24 22:04:361896 } else {
1897 last_id = 0;
1898 }
1899
[email protected]2b10c02d2014-01-29 16:43:021900 glBindTexture(target, last_id);
[email protected]ce296892013-10-24 22:04:361901 glActiveTexture(GL_TEXTURE0 + state->active_texture_unit);
1902}
1903
[email protected]2b10c02d2014-01-29 16:43:021904ScopedTextureBinder::ScopedTextureBinder(ContextState* state,
1905 GLuint id,
1906 GLenum target)
1907 : state_(state),
1908 target_(target) {
[email protected]ab09b612013-03-11 22:11:511909 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021910 "ScopedTextureBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351911
1912 // TODO(apatrick): Check if there are any other states that need to be reset
1913 // before binding a new texture.
1914 glActiveTexture(GL_TEXTURE0);
[email protected]2b10c02d2014-01-29 16:43:021915 glBindTexture(target, id);
[email protected]6217d392010-03-25 22:08:351916}
1917
[email protected]2b10c02d2014-01-29 16:43:021918ScopedTextureBinder::~ScopedTextureBinder() {
[email protected]ab09b612013-03-11 22:11:511919 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021920 "ScopedTextureBinder::dtor", state_->GetErrorState());
1921 RestoreCurrentTextureBindings(state_, target_);
[email protected]6217d392010-03-25 22:08:351922}
1923
[email protected]18e785a2013-10-09 03:29:411924ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state,
[email protected]6217d392010-03-25 22:08:351925 GLuint id)
[email protected]18e785a2013-10-09 03:29:411926 : state_(state) {
[email protected]ab09b612013-03-11 22:11:511927 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411928 "ScopedRenderBufferBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351929 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1930}
1931
1932ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511933 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411934 "ScopedRenderBufferBinder::dtor", state_->GetErrorState());
1935 state_->RestoreRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:351936}
1937
1938ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1939 GLuint id)
1940 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511941 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301942 "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351943 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:451944 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:351945}
1946
1947ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511948 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301949 "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]8e3e0662010-08-23 18:46:301950 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:351951}
1952
[email protected]34ff8b0c2010-10-01 20:06:021953ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:271954 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:521955 : decoder_(decoder) {
[email protected]9d3b2e12013-10-02 01:04:341956 resolve_and_bind_ = (
1957 decoder_->offscreen_target_frame_buffer_.get() &&
1958 decoder_->IsOffscreenBufferMultisampled() &&
1959 (!decoder_->framebuffer_state_.bound_read_framebuffer.get() ||
1960 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:021961 if (!resolve_and_bind_)
1962 return;
1963
[email protected]ab09b612013-03-11 22:11:511964 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301965 "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:021966 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
1967 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:271968 GLuint targetid;
1969 if (internal) {
1970 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
1971 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:351972 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:271973 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:351974 decoder_->offscreen_resolved_color_texture_.reset(
[email protected]ce296892013-10-24 22:04:361975 new BackTexture(decoder->memory_tracker(), &decoder->state_));
[email protected]de26b3c2011-08-03 21:54:271976 decoder_->offscreen_resolved_color_texture_->Create();
1977
1978 DCHECK(decoder_->offscreen_saved_color_format_);
1979 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:091980 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
1981 false);
[email protected]de26b3c2011-08-03 21:54:271982 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
1983 decoder_->offscreen_resolved_color_texture_.get());
1984 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
1985 GL_FRAMEBUFFER_COMPLETE) {
1986 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
1987 << "because offscreen resolved FBO was incomplete.";
1988 return;
1989 }
1990 }
1991 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
1992 } else {
1993 targetid = decoder_->offscreen_saved_frame_buffer_->id();
1994 }
1995 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021996 const int width = decoder_->offscreen_size_.width();
1997 const int height = decoder_->offscreen_size_.height();
[email protected]454157e2014-05-03 02:49:451998 decoder->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f42f05b2013-11-15 21:46:181999 decoder->BlitFramebufferHelper(0,
2000 0,
2001 width,
2002 height,
2003 0,
2004 0,
2005 width,
2006 height,
2007 GL_COLOR_BUFFER_BIT,
2008 GL_NEAREST);
[email protected]de26b3c2011-08-03 21:54:272009 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:022010}
2011
2012ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
2013 if (!resolve_and_bind_)
2014 return;
2015
[email protected]ab09b612013-03-11 22:11:512016 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302017 "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:022018 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:222019 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:452020 decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]8c3e68782010-10-27 16:41:182021 }
[email protected]34ff8b0c2010-10-01 20:06:022022}
2023
[email protected]ce296892013-10-24 22:04:362024BackTexture::BackTexture(
2025 MemoryTracker* memory_tracker,
2026 ContextState* state)
2027 : memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2028 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482029 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252030 id_(0) {
[email protected]6217d392010-03-25 22:08:352031}
2032
[email protected]ed9f9cd2013-02-27 21:12:352033BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:352034 // This does not destroy the render texture because that would require that
2035 // the associated GL context was current. Just check that it was explicitly
2036 // destroyed.
2037 DCHECK_EQ(id_, 0u);
2038}
2039
[email protected]ed9f9cd2013-02-27 21:12:352040void BackTexture::Create() {
[email protected]40621eb52013-10-08 15:40:302041 ScopedGLErrorSuppressor suppressor("BackTexture::Create",
[email protected]ce296892013-10-24 22:04:362042 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352043 Destroy();
2044 glGenTextures(1, &id_);
[email protected]2b10c02d2014-01-29 16:43:022045 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]eeeb07b92014-08-16 07:46:262046 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2047 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
[email protected]3a4d0c52011-06-29 23:11:582048 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2049 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:162050
2051 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
2052 // never called on an offscreen context, no data will ever be uploaded to the
2053 // saved offscreen color texture (it is deferred until to when SwapBuffers
2054 // is called). My idea is that some nvidia drivers might have a bug where
2055 // deleting a texture that has never been populated might cause a
2056 // crash.
2057 glTexImage2D(
2058 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:482059
2060 bytes_allocated_ = 16u * 16u * 4u;
2061 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:352062}
2063
[email protected]ed9f9cd2013-02-27 21:12:352064bool BackTexture::AllocateStorage(
2065 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:352066 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302067 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage",
[email protected]ce296892013-10-24 22:04:362068 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022069 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]678a73f2012-12-19 19:22:092070 uint32 image_size = 0;
2071 GLES2Util::ComputeImageDataSizes(
2072 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size,
2073 NULL, NULL);
2074
[email protected]7989c9e2013-01-23 06:39:262075 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
2076 return false;
2077 }
2078
[email protected]40d90a22013-04-09 03:39:552079 scoped_ptr<char[]> zero_data;
[email protected]678a73f2012-12-19 19:22:092080 if (zero) {
2081 zero_data.reset(new char[image_size]);
2082 memset(zero_data.get(), 0, image_size);
2083 }
[email protected]6217d392010-03-25 22:08:352084
[email protected]8f1d2aa2013-05-10 23:45:382085 glTexImage2D(GL_TEXTURE_2D,
2086 0, // mip level
2087 format,
2088 size.width(),
2089 size.height(),
2090 0, // border
2091 format,
2092 GL_UNSIGNED_BYTE,
2093 zero_data.get());
[email protected]6217d392010-03-25 22:08:352094
[email protected]d37231fa2010-04-09 21:16:022095 size_ = size;
2096
[email protected]1078f912011-12-23 13:12:142097 bool success = glGetError() == GL_NO_ERROR;
2098 if (success) {
[email protected]68e81a4a62012-12-13 01:16:482099 memory_tracker_.TrackMemFree(bytes_allocated_);
2100 bytes_allocated_ = image_size;
2101 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142102 }
2103 return success;
[email protected]6217d392010-03-25 22:08:352104}
2105
[email protected]ed9f9cd2013-02-27 21:12:352106void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:352107 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302108 ScopedGLErrorSuppressor suppressor("BackTexture::Copy",
[email protected]ce296892013-10-24 22:04:362109 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022110 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]6217d392010-03-25 22:08:352111 glCopyTexImage2D(GL_TEXTURE_2D,
2112 0, // level
[email protected]3a4d0c52011-06-29 23:11:582113 format,
[email protected]6217d392010-03-25 22:08:352114 0, 0,
2115 size.width(),
2116 size.height(),
2117 0); // border
2118}
2119
[email protected]ed9f9cd2013-02-27 21:12:352120void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:352121 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302122 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy",
[email protected]ce296892013-10-24 22:04:362123 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352124 glDeleteTextures(1, &id_);
2125 id_ = 0;
2126 }
[email protected]68e81a4a62012-12-13 01:16:482127 memory_tracker_.TrackMemFree(bytes_allocated_);
2128 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352129}
2130
[email protected]ed9f9cd2013-02-27 21:12:352131void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:052132 id_ = 0;
2133}
2134
[email protected]d5a28e452013-10-10 01:01:402135BackRenderbuffer::BackRenderbuffer(
2136 RenderbufferManager* renderbuffer_manager,
2137 MemoryTracker* memory_tracker,
2138 ContextState* state)
2139 : renderbuffer_manager_(renderbuffer_manager),
2140 memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2141 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482142 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252143 id_(0) {
[email protected]6217d392010-03-25 22:08:352144}
2145
[email protected]ed9f9cd2013-02-27 21:12:352146BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:352147 // This does not destroy the render buffer because that would require that
2148 // the associated GL context was current. Just check that it was explicitly
2149 // destroyed.
2150 DCHECK_EQ(id_, 0u);
2151}
2152
[email protected]ed9f9cd2013-02-27 21:12:352153void BackRenderbuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302154 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create",
[email protected]d5a28e452013-10-10 01:01:402155 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352156 Destroy();
2157 glGenRenderbuffersEXT(1, &id_);
2158}
2159
[email protected]f42f05b2013-11-15 21:46:182160bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info,
2161 const gfx::Size& size,
2162 GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:352163 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:512164 ScopedGLErrorSuppressor suppressor(
[email protected]d5a28e452013-10-10 01:01:402165 "BackRenderbuffer::AllocateStorage", state_->GetErrorState());
2166 ScopedRenderBufferBinder binder(state_, id_);
[email protected]7989c9e2013-01-23 06:39:262167
2168 uint32 estimated_size = 0;
[email protected]d5a28e452013-10-10 01:01:402169 if (!renderbuffer_manager_->ComputeEstimatedRenderbufferSize(
[email protected]8e102e102013-09-20 22:50:232170 size.width(), size.height(), samples, format, &estimated_size)) {
[email protected]7989c9e2013-01-23 06:39:262171 return false;
2172 }
2173
2174 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
2175 return false;
2176 }
2177
[email protected]34ff8b0c2010-10-01 20:06:022178 if (samples <= 1) {
2179 glRenderbufferStorageEXT(GL_RENDERBUFFER,
2180 format,
2181 size.width(),
2182 size.height());
2183 } else {
[email protected]f42f05b2013-11-15 21:46:182184 GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info,
2185 GL_RENDERBUFFER,
2186 samples,
2187 format,
2188 size.width(),
2189 size.height());
[email protected]34ff8b0c2010-10-01 20:06:022190 }
[email protected]1078f912011-12-23 13:12:142191 bool success = glGetError() == GL_NO_ERROR;
2192 if (success) {
[email protected]d5a28e452013-10-10 01:01:402193 // Mark the previously allocated bytes as free.
[email protected]68e81a4a62012-12-13 01:16:482194 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:262195 bytes_allocated_ = estimated_size;
[email protected]d5a28e452013-10-10 01:01:402196 // Track the newly allocated bytes.
[email protected]68e81a4a62012-12-13 01:16:482197 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142198 }
2199 return success;
[email protected]6217d392010-03-25 22:08:352200}
2201
[email protected]ed9f9cd2013-02-27 21:12:352202void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352203 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302204 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy",
[email protected]d5a28e452013-10-10 01:01:402205 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352206 glDeleteRenderbuffersEXT(1, &id_);
2207 id_ = 0;
2208 }
[email protected]68e81a4a62012-12-13 01:16:482209 memory_tracker_.TrackMemFree(bytes_allocated_);
2210 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352211}
2212
[email protected]ed9f9cd2013-02-27 21:12:352213void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052214 id_ = 0;
2215}
2216
[email protected]ed9f9cd2013-02-27 21:12:352217BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352218 : decoder_(decoder),
2219 id_(0) {
2220}
2221
[email protected]ed9f9cd2013-02-27 21:12:352222BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:352223 // This does not destroy the frame buffer because that would require that
2224 // the associated GL context was current. Just check that it was explicitly
2225 // destroyed.
2226 DCHECK_EQ(id_, 0u);
2227}
2228
[email protected]ed9f9cd2013-02-27 21:12:352229void BackFramebuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302230 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create",
2231 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352232 Destroy();
2233 glGenFramebuffersEXT(1, &id_);
2234}
2235
[email protected]ed9f9cd2013-02-27 21:12:352236void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:352237 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512238 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302239 "BackFramebuffer::AttachRenderTexture", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352240 ScopedFrameBufferBinder binder(decoder_, id_);
2241 GLuint attach_id = texture ? texture->id() : 0;
2242 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2243 GL_COLOR_ATTACHMENT0,
2244 GL_TEXTURE_2D,
2245 attach_id,
2246 0);
2247}
2248
[email protected]ed9f9cd2013-02-27 21:12:352249void BackFramebuffer::AttachRenderBuffer(GLenum target,
2250 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352251 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512252 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302253 "BackFramebuffer::AttachRenderBuffer", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352254 ScopedFrameBufferBinder binder(decoder_, id_);
2255 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2256 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152257 target,
[email protected]6217d392010-03-25 22:08:352258 GL_RENDERBUFFER,
2259 attach_id);
2260}
2261
[email protected]ed9f9cd2013-02-27 21:12:352262void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352263 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302264 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy",
2265 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352266 glDeleteFramebuffersEXT(1, &id_);
2267 id_ = 0;
2268 }
2269}
2270
[email protected]ed9f9cd2013-02-27 21:12:352271void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052272 id_ = 0;
2273}
2274
[email protected]ed9f9cd2013-02-27 21:12:352275GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352276 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302277 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus",
2278 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352279 ScopedFrameBufferBinder binder(decoder_, id_);
2280 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2281}
2282
[email protected]aa7666122011-09-02 19:45:522283GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2284 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322285}
2286
[email protected]aa7666122011-09-02 19:45:522287GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392288 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572289 group_(group),
[email protected]1d82e822013-04-10 21:32:322290 logger_(&debug_marker_manager_),
[email protected]828a3932014-04-02 14:43:132291 state_(group_->feature_info(), this, &logger_),
[email protected]43410e92012-04-20 17:06:282292 unpack_flip_y_(false),
2293 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172294 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242295 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492296 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242297 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402298 fixed_attrib_buffer_id_(0),
2299 fixed_attrib_buffer_size_(0),
[email protected]34ff8b0c2010-10-01 20:06:022300 offscreen_target_color_format_(0),
2301 offscreen_target_depth_format_(0),
2302 offscreen_target_stencil_format_(0),
2303 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562304 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052305 offscreen_saved_color_format_(0),
[email protected]32fe9aa2011-01-21 23:47:132306 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462307 back_buffer_has_depth_(false),
2308 back_buffer_has_stencil_(false),
achaulkcf5316f2014-09-26 19:28:422309 surfaceless_(false),
[email protected]60f22d32012-12-12 00:31:582310 backbuffer_needs_clear_bits_(0),
[email protected]a3a93e7b2010-08-28 00:48:562311 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052312 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112313 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002314 feature_info_(group_->feature_info()),
[email protected]38d139d2011-07-14 00:38:432315 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302316 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512317 reset_status_(GL_NO_ERROR),
[email protected]93a7d98f2013-07-11 00:04:222318 reset_by_robustness_extension_(false),
[email protected]b381ee32014-03-22 02:43:432319 supports_post_sub_buffer_(false),
[email protected]f0d74742011-10-03 16:31:042320 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102321 derivatives_explicitly_enabled_(false),
[email protected]70dc60932013-06-04 03:33:492322 frag_depth_explicitly_enabled_(false),
[email protected]aff39ac82013-06-08 04:53:132323 draw_buffers_explicitly_enabled_(false),
[email protected]93c2fd82014-04-16 02:46:062324 shader_texture_lod_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282325 compile_shader_always_succeeds_(false),
[email protected]828a3932014-04-02 14:43:132326 lose_context_when_out_of_memory_(false),
[email protected]cae20172012-12-07 00:06:192327 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch(
2328 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022329 viewport_max_width_(0),
[email protected]4a4c18b2013-09-13 22:50:102330 viewport_max_height_(0),
[email protected]345ba902013-11-14 21:39:002331 texture_state_(group_->feature_info()
2332 ->workarounds()
2333 .texsubimage2d_faster_than_teximage2d),
vmiura1c2b1de2014-09-19 19:03:242334 cb_command_trace_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
2335 TRACE_DISABLED_BY_DEFAULT("cb_command"))),
2336 gpu_trace_level_(2),
2337 gpu_trace_commands_(false),
2338 gpu_debug_commands_(false),
[email protected]4a4c18b2013-09-13 22:50:102339 validation_texture_(0),
2340 validation_fbo_multisample_(0),
2341 validation_fbo_(0) {
[email protected]3b1ecc262011-08-03 22:49:572342 DCHECK(group);
2343
[email protected]b1122982010-05-17 23:04:242344 attrib_0_value_.v[0] = 0.0f;
2345 attrib_0_value_.v[1] = 0.0f;
2346 attrib_0_value_.v[2] = 0.0f;
2347 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152348
[email protected]c2f8c8402010-12-06 18:07:242349 // The shader translator is used for WebGL even when running on EGL
2350 // because additional restrictions are needed (like only enabling
2351 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562352 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2353 // the empty string to CompileShader and this is not a valid shader.
2354 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
[email protected]39ba4f02012-03-26 01:16:002355 CommandLine::ForCurrentProcess()->HasSwitch(
2356 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152357 use_shader_translator_ = false;
2358 }
[email protected]96449d2c2009-11-25 00:01:322359}
2360
[email protected]80eb6b52012-01-19 00:14:412361GLES2DecoderImpl::~GLES2DecoderImpl() {
2362}
2363
[email protected]c410da802011-03-14 19:17:412364bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382365 const scoped_refptr<gfx::GLSurface>& surface,
2366 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232367 bool offscreen,
[email protected]c410da802011-03-14 19:17:412368 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:292369 const DisallowedFeatures& disallowed_features,
[email protected]3c644d82011-06-20 19:58:242370 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322371 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382372 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302373 DCHECK(!context_.get());
2374
achaulkcf5316f2014-09-26 19:28:422375 surfaceless_ = surface->IsSurfaceless();
2376
[email protected]55e136f2013-04-03 18:50:062377 set_initialized();
[email protected]b4af07d2014-08-20 00:11:572378 gpu_tracer_.reset(new GPUTracer(this));
[email protected]8f9b8dd2013-09-12 18:05:132379 gpu_state_tracer_ = GPUStateTracer::Create(&state_);
[email protected]fb97b662013-02-20 23:02:142380
[email protected]e844ae22012-01-14 03:36:262381 if (CommandLine::ForCurrentProcess()->HasSwitch(
2382 switches::kEnableGPUDebugging)) {
2383 set_debug(true);
2384 }
2385
[email protected]39ba4f02012-03-26 01:16:002386 if (CommandLine::ForCurrentProcess()->HasSwitch(
2387 switches::kEnableGPUCommandLogging)) {
2388 set_log_commands(true);
2389 }
2390
[email protected]062c38b2012-01-18 03:25:102391 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch(
2392 switches::kCompileShaderAlwaysSucceeds);
2393
[email protected]f62a5ab2011-05-23 20:34:152394
[email protected]63c9b052012-05-17 18:27:382395 // Take ownership of the context and surface. The surface can be replaced with
2396 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382397 context_ = context;
[email protected]63c9b052012-05-17 18:27:382398 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182399
[email protected]65f7efe2013-11-28 03:11:472400 ContextCreationAttribHelper attrib_parser;
2401 if (!attrib_parser.Parse(attribs))
2402 return false;
2403
[email protected]828a3932014-04-02 14:43:132404 // Save the loseContextWhenOutOfMemory context creation attribute.
2405 lose_context_when_out_of_memory_ =
[email protected]845c4e32014-08-13 11:50:402406 attrib_parser.lose_context_when_out_of_memory;
[email protected]828a3932014-04-02 14:43:132407
[email protected]65f7efe2013-11-28 03:11:472408 // If the failIfMajorPerformanceCaveat context creation attribute was true
2409 // and we are using a software renderer, fail.
[email protected]845c4e32014-08-13 11:50:402410 if (attrib_parser.fail_if_major_perf_caveat &&
[email protected]65f7efe2013-11-28 03:11:472411 feature_info_->feature_flags().is_swiftshader) {
2412 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
2413 Destroy(true);
2414 return false;
2415 }
2416
[email protected]956aec52013-09-05 15:41:192417 if (!group_->Initialize(this, disallowed_features)) {
[email protected]09ddb91f2011-04-14 23:16:222418 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392419 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422420 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382421 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032422 return false;
[email protected]a3ded6d2010-10-19 06:44:392423 }
[email protected]b64c24952012-04-19 03:20:272424 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282425
[email protected]e82fb792011-09-22 00:33:292426 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502427
[email protected]af6380962012-11-29 23:24:132428 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]da364812014-05-09 21:39:482429 vertex_array_manager_.reset(new VertexArrayManager());
2430
2431 GLuint default_vertex_attrib_service_id = 0;
2432 if (features().native_vertex_array_object) {
2433 glGenVertexArraysOES(1, &default_vertex_attrib_service_id);
2434 glBindVertexArrayOES(default_vertex_attrib_service_id);
2435 }
2436
2437 state_.default_vertex_attrib_manager =
2438 CreateVertexAttribManager(0, default_vertex_attrib_service_id, false);
2439
[email protected]81f20a622014-04-18 01:54:522440 state_.default_vertex_attrib_manager->Initialize(
[email protected]94ba2e02014-03-12 10:32:002441 group_->max_vertex_attribs(),
2442 feature_info_->workarounds().init_vertex_attributes);
[email protected]944b62f32012-09-27 02:20:462443
[email protected]81f20a622014-04-18 01:54:522444 // vertex_attrib_manager is set to default_vertex_attrib_manager by this call
[email protected]ab4fd7282012-10-12 16:25:572445 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322446
[email protected]7cd76fd2013-06-02 21:11:112447 query_manager_.reset(new QueryManager(this, feature_info_.get()));
[email protected]882ba1e22012-03-08 19:02:532448
[email protected]b63f1d62014-07-18 15:40:592449 image_manager_.reset(new ImageManager);
2450
[email protected]302ce6d2011-07-07 23:28:112451 util_.set_num_compressed_texture_formats(
2452 validators_->compressed_texture_format.GetValues().size());
2453
[email protected]1071e572011-02-09 20:00:122454 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2455 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2456 // OpenGL ES 2.0 does not have this issue.
2457 glEnableVertexAttribArray(0);
2458 }
[email protected]b1122982010-05-17 23:04:242459 glGenBuffersARB(1, &attrib_0_buffer_id_);
2460 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2461 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2462 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402463 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082464
[email protected]1868a342012-11-07 15:56:022465 state_.texture_units.resize(group_->max_texture_units());
2466 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492467 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312468 // We want the last bind to be 2D.
[email protected]370eaf12013-05-18 09:19:492469 TextureRef* ref;
[email protected]62e155e2012-10-23 22:43:152470 if (features().oes_egl_image_external) {
[email protected]370eaf12013-05-18 09:19:492471 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072472 GL_TEXTURE_EXTERNAL_OES);
[email protected]370eaf12013-05-18 09:19:492473 state_.texture_units[tt].bound_texture_external_oes = ref;
[email protected]5ebf59f2014-04-08 03:51:572474 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref ? ref->service_id() : 0);
[email protected]61eeb33f2011-07-26 15:30:312475 }
[email protected]62e155e2012-10-23 22:43:152476 if (features().arb_texture_rectangle) {
[email protected]370eaf12013-05-18 09:19:492477 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072478 GL_TEXTURE_RECTANGLE_ARB);
[email protected]370eaf12013-05-18 09:19:492479 state_.texture_units[tt].bound_texture_rectangle_arb = ref;
[email protected]5ebf59f2014-04-08 03:51:572480 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref ? ref->service_id() : 0);
[email protected]e51bdf32011-11-23 22:21:462481 }
[email protected]370eaf12013-05-18 09:19:492482 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2483 state_.texture_units[tt].bound_texture_cube_map = ref;
[email protected]5ebf59f2014-04-08 03:51:572484 glBindTexture(GL_TEXTURE_CUBE_MAP, ref ? ref->service_id() : 0);
[email protected]370eaf12013-05-18 09:19:492485 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2486 state_.texture_units[tt].bound_texture_2d = ref;
[email protected]5ebf59f2014-04-08 03:51:572487 glBindTexture(GL_TEXTURE_2D, ref ? ref->service_id() : 0);
[email protected]1958e0e2010-04-22 05:17:152488 }
[email protected]00f893d2010-08-24 18:55:492489 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502490 CHECK_GL_ERROR();
2491
[email protected]069944672012-04-25 20:52:232492 if (offscreen) {
[email protected]845c4e32014-08-13 11:50:402493 if (attrib_parser.samples > 0 && attrib_parser.sample_buffers > 0 &&
[email protected]b0609652012-12-14 07:24:542494 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022495 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432496 // max_sample_count must be initialized to a sane value. If
2497 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2498 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022499 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
[email protected]845c4e32014-08-13 11:50:402500 offscreen_target_samples_ = std::min(attrib_parser.samples,
[email protected]34ff8b0c2010-10-01 20:06:022501 max_sample_count);
2502 } else {
2503 offscreen_target_samples_ = 1;
2504 }
[email protected]845c4e32014-08-13 11:50:402505 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved;
[email protected]34ff8b0c2010-10-01 20:06:022506
2507 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2508 const bool rgb8_supported =
2509 context_->HasExtension("GL_OES_rgb8_rgba8");
2510 // The only available default render buffer formats in GLES2 have very
2511 // little precision. Don't enable multisampling unless 8-bit render
2512 // buffer formats are available--instead fall back to 8-bit textures.
2513 if (rgb8_supported && offscreen_target_samples_ > 1) {
[email protected]845c4e32014-08-13 11:50:402514 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022515 GL_RGBA8 : GL_RGB8;
2516 } else {
2517 offscreen_target_samples_ = 1;
[email protected]845c4e32014-08-13 11:50:402518 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022519 GL_RGBA : GL_RGB;
2520 }
2521
2522 // ANGLE only supports packed depth/stencil formats, so use it if it is
2523 // available.
2524 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182525 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272526 VLOG(1) << "GL_OES_packed_depth_stencil "
2527 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]845c4e32014-08-13 11:50:402528 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002529 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022530 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2531 offscreen_target_stencil_format_ = 0;
2532 } else {
2533 // It may be the case that this depth/stencil combination is not
2534 // supported, but this will be checked later by CheckFramebufferStatus.
[email protected]845c4e32014-08-13 11:50:402535 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022536 GL_DEPTH_COMPONENT16 : 0;
[email protected]845c4e32014-08-13 11:50:402537 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022538 GL_STENCIL_INDEX8 : 0;
2539 }
2540 } else {
[email protected]845c4e32014-08-13 11:50:402541 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022542 GL_RGBA : GL_RGB;
2543
2544 // If depth is requested at all, use the packed depth stencil format if
2545 // it's available, as some desktop GL drivers don't support any non-packed
2546 // formats for depth attachments.
2547 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182548 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272549 VLOG(1) << "GL_EXT_packed_depth_stencil "
2550 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022551
[email protected]845c4e32014-08-13 11:50:402552 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002553 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022554 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2555 offscreen_target_stencil_format_ = 0;
2556 } else {
[email protected]845c4e32014-08-13 11:50:402557 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022558 GL_DEPTH_COMPONENT : 0;
[email protected]845c4e32014-08-13 11:50:402559 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022560 GL_STENCIL_INDEX : 0;
2561 }
2562 }
2563
[email protected]845c4e32014-08-13 11:50:402564 offscreen_saved_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]97872062010-11-03 19:07:052565 GL_RGBA : GL_RGB;
2566
[email protected]6217d392010-03-25 22:08:352567 // Create the target frame buffer. This is the one that the client renders
2568 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352569 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352570 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022571 // Due to GLES2 format limitations, either the color texture (for
2572 // non-multisampling) or the color render buffer (for multisampling) will be
2573 // attached to the offscreen frame buffer. The render buffer has more
2574 // limited formats available to it, but the texture can't do multisampling.
2575 if (IsOffscreenBufferMultisampled()) {
[email protected]d5a28e452013-10-10 01:01:402576 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(
2577 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022578 offscreen_target_color_render_buffer_->Create();
2579 } else {
[email protected]ce296892013-10-24 22:04:362580 offscreen_target_color_texture_.reset(new BackTexture(
2581 memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022582 offscreen_target_color_texture_->Create();
2583 }
[email protected]d5a28e452013-10-10 01:01:402584 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(
2585 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152586 offscreen_target_depth_render_buffer_->Create();
[email protected]d5a28e452013-10-10 01:01:402587 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(
2588 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152589 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352590
2591 // Create the saved offscreen texture. The target frame buffer is copied
2592 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352593 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022594 offscreen_saved_frame_buffer_->Create();
2595 //
[email protected]ce296892013-10-24 22:04:362596 offscreen_saved_color_texture_.reset(new BackTexture(
2597 memory_tracker(), &state_));
[email protected]6217d392010-03-25 22:08:352598 offscreen_saved_color_texture_->Create();
2599
[email protected]6217d392010-03-25 22:08:352600 // Allocate the render buffers at their initial size and check the status
2601 // of the frame buffers is okay.
[email protected]799b4b22011-08-22 17:09:592602 if (!ResizeOffscreenFrameBuffer(size)) {
[email protected]d0498742010-09-20 20:27:012603 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382604 Destroy(true);
[email protected]6217d392010-03-25 22:08:352605 return false;
2606 }
2607
[email protected]678a73f2012-12-19 19:22:092608 // Allocate the offscreen saved color texture.
2609 DCHECK(offscreen_saved_color_format_);
2610 offscreen_saved_color_texture_->AllocateStorage(
2611 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2612
2613 offscreen_saved_frame_buffer_->AttachRenderTexture(
2614 offscreen_saved_color_texture_.get());
2615 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2616 GL_FRAMEBUFFER_COMPLETE) {
2617 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2618 Destroy(true);
2619 return false;
2620 }
2621
[email protected]6217d392010-03-25 22:08:352622 // Bind to the new default frame buffer (the offscreen target frame buffer).
2623 // This should now be associated with ID zero.
2624 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
[email protected]62e65f02013-05-29 22:28:102625 } else {
2626 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
2627 // These are NOT if the back buffer has these proprorties. They are
2628 // if we want the command buffer to enforce them regardless of what
2629 // the real backbuffer is assuming the real back buffer gives us more than
2630 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2631 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2632 // can't do anything about that.
2633
achaulkcf5316f2014-09-26 19:28:422634 if (!surfaceless_) {
2635 GLint v = 0;
2636 glGetIntegerv(GL_ALPHA_BITS, &v);
2637 // This checks if the user requested RGBA and we have RGBA then RGBA. If
2638 // the user requested RGB then RGB. If the user did not specify a
2639 // preference than use whatever we were given. Same for DEPTH and STENCIL.
2640 back_buffer_color_format_ =
2641 (attrib_parser.alpha_size != 0 && v > 0) ? GL_RGBA : GL_RGB;
2642 glGetIntegerv(GL_DEPTH_BITS, &v);
2643 back_buffer_has_depth_ = attrib_parser.depth_size != 0 && v > 0;
2644 glGetIntegerv(GL_STENCIL_BITS, &v);
2645 back_buffer_has_stencil_ = attrib_parser.stencil_size != 0 && v > 0;
2646 }
[email protected]6217d392010-03-25 22:08:352647 }
2648
[email protected]76a0ee102010-04-07 21:03:042649 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2650 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2651 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372652 // mailing list archives. It also implicitly enables the desktop GL
2653 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2654 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152655 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2656 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372657 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152658 }
[email protected]de17df392010-04-23 21:09:412659
[email protected]706b69f2012-07-27 04:59:302660 has_robustness_extension_ =
2661 context->HasExtension("GL_ARB_robustness") ||
2662 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432663
[email protected]c2f8c8402010-12-06 18:07:242664 if (!InitializeShaderTranslator()) {
2665 return false;
[email protected]de17df392010-04-23 21:09:412666 }
[email protected]76a0ee102010-04-07 21:03:042667
[email protected]e259eb412012-10-13 05:47:242668 state_.viewport_width = size.width();
2669 state_.viewport_height = size.height();
[email protected]43410e92012-04-20 17:06:282670
[email protected]5904806b2012-05-08 18:10:222671 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282672 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022673 viewport_max_width_ = viewport_params[0];
2674 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282675
[email protected]88a61bf2012-10-27 13:00:422676 state_.scissor_width = state_.viewport_width;
2677 state_.scissor_height = state_.viewport_height;
2678
[email protected]11f3e702012-06-19 19:00:012679 // Set all the default state because some GL drivers get it wrong.
[email protected]88ba52f2014-04-09 12:39:342680 state_.InitCapabilities(NULL);
2681 state_.InitState(NULL);
[email protected]e259eb412012-10-13 05:47:242682 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]11f3e702012-06-19 19:00:012683
2684 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2685 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2686 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2687 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
2688
achaulkcf5316f2014-09-26 19:28:422689 bool call_gl_clear = !surfaceless_;
[email protected]88cfd132013-07-11 00:59:002690#if defined(OS_ANDROID)
2691 // Temporary workaround for Android WebView because this clear ignores the
2692 // clip and corrupts that external UI of the App. Not calling glClear is ok
2693 // because the system already clears the buffer before each draw. Proper
2694 // fix might be setting the scissor clip properly before initialize. See
2695 // crbug.com/259023 for details.
2696 call_gl_clear = surface_->GetHandle();
2697#endif
2698 if (call_gl_clear) {
2699 // Clear the backbuffer.
2700 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2701 }
[email protected]561cc0a62013-05-07 18:34:452702
[email protected]b381ee32014-03-22 02:43:432703 supports_post_sub_buffer_ = surface->SupportsPostSubBuffer();
2704 if (feature_info_->workarounds()
2705 .disable_post_sub_buffers_for_onscreen_surfaces &&
2706 !surface->IsOffscreen())
2707 supports_post_sub_buffer_ = false;
2708
[email protected]62e155e2012-10-23 22:43:152709 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462710 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2711 }
[email protected]dd289a5d62012-06-30 22:05:462712
[email protected]9b753992013-04-27 02:04:412713 if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2714 context_->SetUnbindFboOnMakeCurrent();
[email protected]85cb4682013-04-20 00:54:242715 }
[email protected]85cb4682013-04-20 00:54:242716
[email protected]97419c02013-04-10 02:52:382717 // Only compositor contexts are known to use only the subset of GL
2718 // that can be safely migrated between the iGPU and the dGPU. Mark
2719 // those contexts as safe to forcibly transition between the GPUs.
2720 // http://crbug.com/180876, http://crbug.com/227228
2721 if (!offscreen)
2722 context_->SetSafeToForceGpuSwitch();
2723
[email protected]85a4ac22013-05-31 01:58:472724 async_pixel_transfer_manager_.reset(
[email protected]498b5c072013-06-04 19:30:072725 AsyncPixelTransferManager::Create(context.get()));
2726 async_pixel_transfer_manager_->Initialize(texture_manager());
[email protected]32145a92012-12-17 09:01:592727
[email protected]91c94eb2013-10-22 10:32:542728 framebuffer_manager()->AddObserver(this);
2729
[email protected]246a70452010-03-05 21:53:502730 return true;
[email protected]96449d2c2009-11-25 00:01:322731}
2732
[email protected]6d668892013-12-04 21:37:122733Capabilities GLES2DecoderImpl::GetCapabilities() {
2734 DCHECK(initialized());
2735
2736 Capabilities caps;
2737
[email protected]6d668892013-12-04 21:37:122738 caps.egl_image_external =
2739 feature_info_->feature_flags().oes_egl_image_external;
2740 caps.texture_format_bgra8888 =
2741 feature_info_->feature_flags().ext_texture_format_bgra8888;
2742 caps.texture_format_etc1 =
2743 feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture;
aeliasd880a3d2014-08-26 00:46:202744 caps.texture_format_etc1_npot =
2745 caps.texture_format_etc1 && !workarounds().etc1_power_of_two_only;
[email protected]6d668892013-12-04 21:37:122746 caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle;
2747 caps.texture_usage = feature_info_->feature_flags().angle_texture_usage;
2748 caps.texture_storage = feature_info_->feature_flags().ext_texture_storage;
2749 caps.discard_framebuffer =
2750 feature_info_->feature_flags().ext_discard_framebuffer;
[email protected]12c99ab02014-04-22 10:12:352751 caps.sync_query = feature_info_->feature_flags().chromium_sync_query;
[email protected]6d668892013-12-04 21:37:122752
2753#if defined(OS_MACOSX)
2754 // This is unconditionally true on mac, no need to test for it at runtime.
2755 caps.iosurface = true;
2756#endif
2757
[email protected]b381ee32014-03-22 02:43:432758 caps.post_sub_buffer = supports_post_sub_buffer_;
[email protected]b63f1d62014-07-18 15:40:592759 caps.map_image = true;
[email protected]6d668892013-12-04 21:37:122760
2761 return caps;
2762}
2763
[email protected]302ce6d2011-07-07 23:28:112764void GLES2DecoderImpl::UpdateCapabilities() {
2765 util_.set_num_compressed_texture_formats(
2766 validators_->compressed_texture_format.GetValues().size());
2767 util_.set_num_shader_binary_formats(
2768 validators_->shader_binary_format.GetValues().size());
2769}
2770
[email protected]c2f8c8402010-12-06 18:07:242771bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442772 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2773
[email protected]c2f8c8402010-12-06 18:07:242774 if (!use_shader_translator_) {
2775 return true;
2776 }
2777 ShBuiltInResources resources;
2778 ShInitBuiltInResources(&resources);
2779 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2780 resources.MaxVertexUniformVectors =
2781 group_->max_vertex_uniform_vectors();
2782 resources.MaxVaryingVectors = group_->max_varying_vectors();
2783 resources.MaxVertexTextureImageUnits =
2784 group_->max_vertex_texture_image_units();
2785 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2786 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2787 resources.MaxFragmentUniformVectors =
2788 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:492789 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]a0b78142013-05-23 00:47:242790 resources.MaxExpressionComplexity = 256;
2791 resources.MaxCallStackDepth = 256;
[email protected]f0d74742011-10-03 16:31:042792
[email protected]46c86752013-05-21 05:08:392793 GLint range[2] = { 0, 0 };
[email protected]8dc1bf92013-03-12 03:58:212794 GLint precision = 0;
2795 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
2796 range, &precision);
[email protected]448e459e2013-06-12 17:00:412797 resources.FragmentPrecisionHigh =
2798 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
[email protected]9e98f61b2013-03-05 02:21:142799
[email protected]f0d74742011-10-03 16:31:042800 if (force_webgl_glsl_validation_) {
2801 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:492802 resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:132803 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
[email protected]cd8f1892013-09-05 00:14:442804 if (!draw_buffers_explicitly_enabled_)
2805 resources.MaxDrawBuffers = 1;
[email protected]93c2fd82014-04-16 02:46:062806 resources.EXT_shader_texture_lod = shader_texture_lod_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:042807 } else {
2808 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152809 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462810 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152811 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062812 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152813 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:492814 resources.EXT_draw_buffers =
2815 features().ext_draw_buffers ? 1 : 0;
[email protected]70dc60932013-06-04 03:33:492816 resources.EXT_frag_depth =
2817 features().ext_frag_depth ? 1 : 0;
[email protected]93c2fd82014-04-16 02:46:062818 resources.EXT_shader_texture_lod =
2819 features().ext_shader_texture_lod ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:042820 }
2821
[email protected]26b61442013-03-17 16:12:012822 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC
2823 : SH_GLES2_SPEC;
[email protected]6aedcdc2013-01-24 01:25:052824 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:022825 resources.HashFunction = &CityHash64;
[email protected]6aedcdc2013-01-24 01:25:052826 else
2827 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:122828 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2829 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2830 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
[email protected]a6739bc2013-09-07 04:45:212831 int driver_bug_workarounds = 0;
2832 if (workarounds().needs_glsl_built_in_function_emulation)
2833 driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS;
[email protected]81187c62013-09-09 23:54:542834 if (workarounds().init_gl_position_in_vertex_shader)
2835 driver_bug_workarounds |= SH_INIT_GL_POSITION;
[email protected]f0c87602013-10-17 19:34:112836 if (workarounds().unfold_short_circuit_as_ternary_operation)
2837 driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT;
[email protected]b03219d2014-02-12 11:17:052838 if (workarounds().init_varyings_without_static_use)
2839 driver_bug_workarounds |= SH_INIT_VARYINGS_WITHOUT_STATIC_USE;
[email protected]f4db2b12014-03-01 03:57:062840 if (workarounds().unroll_for_loop_with_sampler_array_index)
2841 driver_bug_workarounds |= SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX;
[email protected]711e90802014-07-22 20:40:252842 if (workarounds().scalarize_vec_and_mat_constructor_args)
2843 driver_bug_workarounds |= SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS;
[email protected]fa6d3982014-08-18 18:10:272844 if (workarounds().regenerate_struct_names)
2845 driver_bug_workarounds |= SH_REGENERATE_STRUCT_NAMES;
[email protected]87fb6ab2012-06-13 22:28:042846
[email protected]03cef9b2014-04-03 15:58:142847 vertex_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:262848 GL_VERTEX_SHADER,
[email protected]03cef9b2014-04-03 15:58:142849 shader_spec,
2850 &resources,
[email protected]a6739bc2013-09-07 04:45:212851 implementation_type,
2852 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042853 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242854 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:382855 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242856 return false;
2857 }
[email protected]87fb6ab2012-06-13 22:28:042858
[email protected]03cef9b2014-04-03 15:58:142859 fragment_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:262860 GL_FRAGMENT_SHADER,
[email protected]03cef9b2014-04-03 15:58:142861 shader_spec,
2862 &resources,
[email protected]a6739bc2013-09-07 04:45:212863 implementation_type,
2864 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042865 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242866 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:382867 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242868 return false;
2869 }
2870 return true;
2871}
2872
[email protected]ae51d192010-04-27 00:48:032873bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:472874 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352875 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032876 return false;
2877 }
2878 }
[email protected]40d90a22013-04-09 03:39:552879 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032880 glGenBuffersARB(n, service_ids.get());
2881 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352882 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032883 }
2884 return true;
2885}
2886
2887bool GLES2DecoderImpl::GenFramebuffersHelper(
2888 GLsizei n, const GLuint* client_ids) {
2889 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352890 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032891 return false;
2892 }
2893 }
[email protected]40d90a22013-04-09 03:39:552894 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032895 glGenFramebuffersEXT(n, service_ids.get());
2896 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352897 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032898 }
2899 return true;
2900}
2901
2902bool GLES2DecoderImpl::GenRenderbuffersHelper(
2903 GLsizei n, const GLuint* client_ids) {
2904 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352905 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032906 return false;
2907 }
2908 }
[email protected]40d90a22013-04-09 03:39:552909 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032910 glGenRenderbuffersEXT(n, service_ids.get());
2911 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352912 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032913 }
2914 return true;
2915}
2916
2917bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
2918 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352919 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032920 return false;
2921 }
2922 }
[email protected]40d90a22013-04-09 03:39:552923 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032924 glGenTextures(n, service_ids.get());
2925 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352926 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032927 }
2928 return true;
2929}
2930
2931void GLES2DecoderImpl::DeleteBuffersHelper(
2932 GLsizei n, const GLuint* client_ids) {
2933 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:212934 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102935 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242936 state_.vertex_attrib_manager->Unbind(buffer);
[email protected]7cd76fd2013-06-02 21:11:112937 if (state_.bound_array_buffer.get() == buffer) {
[email protected]e259eb412012-10-13 05:47:242938 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102939 }
[email protected]ed9f9cd2013-02-27 21:12:352940 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032941 }
[email protected]a93bb842010-02-16 23:03:472942 }
[email protected]07f54fcc2009-12-22 02:46:302943}
2944
[email protected]ae51d192010-04-27 00:48:032945void GLES2DecoderImpl::DeleteFramebuffersHelper(
2946 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452947 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152948 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:112949
[email protected]a25fa872010-03-25 02:57:582950 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352951 Framebuffer* framebuffer =
2952 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102953 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]9d3b2e12013-10-02 01:04:342954 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
2955 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]c986af502013-08-14 01:04:442956 framebuffer_state_.clear_state_dirty = true;
[email protected]ebfb73c2012-08-15 02:37:452957 GLenum target = supports_separate_framebuffer_binds ?
2958 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112959 glBindFramebufferEXT(target, GetBackbufferServiceId());
2960 }
[email protected]9d3b2e12013-10-02 01:04:342961 if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) {
2962 framebuffer_state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:452963 GLenum target = supports_separate_framebuffer_binds ?
2964 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112965 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:462966 }
[email protected]70d34263c2013-01-09 00:27:452967 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:352968 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032969 }
[email protected]a25fa872010-03-25 02:57:582970 }
[email protected]07f54fcc2009-12-22 02:46:302971}
2972
[email protected]ae51d192010-04-27 00:48:032973void GLES2DecoderImpl::DeleteRenderbuffersHelper(
2974 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452975 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152976 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:582977 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352978 Renderbuffer* renderbuffer =
2979 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102980 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:112981 if (state_.bound_renderbuffer.get() == renderbuffer) {
[email protected]e259eb412012-10-13 05:47:242982 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102983 }
2984 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452985 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:342986 if (framebuffer_state_.bound_read_framebuffer.get()) {
2987 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112988 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102989 }
[email protected]9d3b2e12013-10-02 01:04:342990 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2991 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112992 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102993 }
2994 } else {
[email protected]9d3b2e12013-10-02 01:04:342995 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2996 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112997 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102998 }
2999 }
[email protected]c986af502013-08-14 01:04:443000 framebuffer_state_.clear_state_dirty = true;
[email protected]ed9f9cd2013-02-27 21:12:353001 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033002 }
[email protected]a25fa872010-03-25 02:57:583003 }
[email protected]07f54fcc2009-12-22 02:46:303004}
3005
[email protected]ae51d192010-04-27 00:48:033006void GLES2DecoderImpl::DeleteTexturesHelper(
3007 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453008 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153009 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:473010 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]370eaf12013-05-18 09:19:493011 TextureRef* texture_ref = GetTexture(client_ids[ii]);
3012 if (texture_ref) {
3013 Texture* texture = texture_ref->texture();
[email protected]a0b78dc2011-11-11 10:43:103014 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:443015 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463016 }
[email protected]370eaf12013-05-18 09:19:493017 // Unbind texture_ref from texture_ref units.
[email protected]1868a342012-11-07 15:56:023018 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]370eaf12013-05-18 09:19:493019 state_.texture_units[jj].Unbind(texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103020 }
3021 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:453022 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:343023 if (framebuffer_state_.bound_read_framebuffer.get()) {
3024 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113025 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103026 }
[email protected]9d3b2e12013-10-02 01:04:343027 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3028 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113029 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103030 }
3031 } else {
[email protected]9d3b2e12013-10-02 01:04:343032 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3033 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113034 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103035 }
3036 }
[email protected]e51bdf32011-11-23 22:21:463037#if defined(OS_MACOSX)
[email protected]4f9958142013-07-02 03:58:073038 GLuint service_id = texture->service_id();
[email protected]e51bdf32011-11-23 22:21:463039 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
3040 ReleaseIOSurfaceForTexture(service_id);
3041 }
3042#endif
[email protected]ed9f9cd2013-02-27 21:12:353043 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033044 }
[email protected]a93bb842010-02-16 23:03:473045 }
[email protected]07f54fcc2009-12-22 02:46:303046}
3047
[email protected]43f28f832010-02-03 02:28:483048// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:323049
[email protected]eb54a562010-01-20 21:55:183050bool GLES2DecoderImpl::MakeCurrent() {
[email protected]177d1342013-12-07 04:20:343051 if (!context_.get())
[email protected]63c9b052012-05-17 18:27:383052 return false;
3053
[email protected]177d1342013-12-07 04:20:343054 if (!context_->MakeCurrent(surface_.get()) || WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:433055 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]e9f0ca82013-04-01 23:52:293056
3057 // Some D3D drivers cannot recover from device lost in the GPU process
3058 // sandbox. Allow a new GPU process to launch.
3059 if (workarounds().exit_on_context_lost) {
3060 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
3061 << " a D3D device in the Chrome GPU process sandbox.";
[email protected]6eb775352013-08-27 05:57:163062#if defined(OS_WIN)
3063 base::win::SetShouldCrashOnProcessDetach(false);
3064#endif
[email protected]e9f0ca82013-04-01 23:52:293065 exit(0);
3066 }
3067
[email protected]63c9b052012-05-17 18:27:383068 return false;
[email protected]38d139d2011-07-14 00:38:433069 }
3070
[email protected]69a8701e2013-03-07 21:31:093071 ProcessFinishedAsyncTransfers();
[email protected]69a8701e2013-03-07 21:31:093072
[email protected]9b753992013-04-27 02:04:413073 // Rebind the FBO if it was unbound by the context.
3074 if (workarounds().unbind_fbo_on_context_switch)
3075 RestoreFramebufferBindings();
3076
[email protected]c986af502013-08-14 01:04:443077 framebuffer_state_.clear_state_dirty = true;
[email protected]370eaf12013-05-18 09:19:493078
[email protected]69a8701e2013-03-07 21:31:093079 return true;
3080}
3081
3082void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]5a36dc132013-07-23 23:17:553083 ProcessPendingReadPixels();
[email protected]fe8d73c2013-02-16 22:37:323084 if (engine() && query_manager_.get())
3085 query_manager_->ProcessPendingTransferQueries();
3086
[email protected]5b3a8e02013-03-13 05:36:443087 // TODO(epenner): Is there a better place to do this?
3088 // This needs to occur before we execute any batch of commands
3089 // from the client, as the client may have recieved an async
3090 // completion while issuing those commands.
3091 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]b68b100752013-06-05 08:34:483092 async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
[email protected]eb54a562010-01-20 21:55:183093}
3094
[email protected]8e3e0662010-08-23 18:46:303095static void RebindCurrentFramebuffer(
3096 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:063097 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:243098 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:063099 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:463100
[email protected]a3783712012-01-20 22:18:243101 if (framebuffer_id == 0) {
3102 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:303103 }
[email protected]297ca1c2011-06-20 23:08:463104
[email protected]8e3e0662010-08-23 18:46:303105 glBindFramebufferEXT(target, framebuffer_id);
3106}
3107
3108void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]c986af502013-08-14 01:04:443109 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463110
[email protected]62e155e2012-10-23 22:43:153111 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:303112 RebindCurrentFramebuffer(
3113 GL_FRAMEBUFFER,
[email protected]9d3b2e12013-10-02 01:04:343114 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243115 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303116 } else {
3117 RebindCurrentFramebuffer(
3118 GL_READ_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343119 framebuffer_state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243120 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303121 RebindCurrentFramebuffer(
3122 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343123 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243124 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303125 }
[email protected]70d34263c2013-01-09 00:27:453126 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:303127}
3128
[email protected]0d6bfdc2011-11-02 01:32:203129bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:353130 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:203131 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:103132 if (!framebuffer) {
achaulkcf5316f2014-09-26 19:28:423133 if (surfaceless_)
3134 return false;
[email protected]60f22d32012-12-12 00:31:583135 if (backbuffer_needs_clear_bits_) {
3136 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
3137 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
[email protected]454157e2014-05-03 02:49:453138 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]60f22d32012-12-12 00:31:583139 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473140 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3141 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]60f22d32012-12-12 00:31:583142 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:453143 state_.SetDeviceDepthMask(GL_TRUE);
3144 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]ee757922014-06-06 05:21:423145 bool reset_draw_buffer = false;
3146 if ((backbuffer_needs_clear_bits_ | GL_COLOR_BUFFER_BIT) != 0 &&
3147 group_->draw_buffer() == GL_NONE) {
3148 reset_draw_buffer = true;
3149 GLenum buf = GL_BACK;
3150 if (GetBackbufferServiceId() != 0) // emulated backbuffer
3151 buf = GL_COLOR_ATTACHMENT0;
3152 glDrawBuffersARB(1, &buf);
3153 }
[email protected]60f22d32012-12-12 00:31:583154 glClear(backbuffer_needs_clear_bits_);
[email protected]ee757922014-06-06 05:21:423155 if (reset_draw_buffer) {
3156 GLenum buf = GL_NONE;
3157 glDrawBuffersARB(1, &buf);
3158 }
[email protected]60f22d32012-12-12 00:31:583159 backbuffer_needs_clear_bits_ = 0;
3160 RestoreClearState();
3161 }
[email protected]0d6bfdc2011-11-02 01:32:203162 return true;
3163 }
3164
[email protected]968351b2011-12-20 08:26:513165 if (framebuffer_manager()->IsComplete(framebuffer)) {
3166 return true;
3167 }
3168
[email protected]0d6bfdc2011-11-02 01:32:203169 GLenum completeness = framebuffer->IsPossiblyComplete();
3170 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513171 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433172 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:273173 return false;
3174 }
[email protected]0d6bfdc2011-11-02 01:32:203175
3176 // Are all the attachments cleared?
3177 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
3178 texture_manager()->HaveUnclearedMips()) {
3179 if (!framebuffer->IsCleared()) {
3180 // Can we clear them?
[email protected]73276522012-11-09 05:50:203181 if (framebuffer->GetStatus(texture_manager(), target) !=
3182 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513183 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433184 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3185 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:203186 return false;
3187 }
3188 ClearUnclearedAttachments(target, framebuffer);
3189 }
3190 }
3191
[email protected]968351b2011-12-20 08:26:513192 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:203193 if (framebuffer->GetStatus(texture_manager(), target) !=
3194 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513195 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433196 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3197 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:513198 return false;
3199 }
3200 framebuffer_manager()->MarkAsComplete(framebuffer);
3201 }
3202
[email protected]0d6bfdc2011-11-02 01:32:203203 // NOTE: At this point we don't know if the framebuffer is complete but
3204 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:273205 return true;
3206}
3207
[email protected]0d6bfdc2011-11-02 01:32:203208bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:153209 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:513210 bool valid = CheckFramebufferValid(
[email protected]9d3b2e12013-10-02 01:04:343211 framebuffer_state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT,
3212 func_name);
[email protected]28718a92013-04-04 12:12:513213
3214 if (valid)
3215 OnUseFramebuffer();
3216
3217 return valid;
[email protected]0d6bfdc2011-11-02 01:32:203218 }
[email protected]9d3b2e12013-10-02 01:04:343219 return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113220 GL_DRAW_FRAMEBUFFER_EXT,
3221 func_name) &&
[email protected]9d3b2e12013-10-02 01:04:343222 CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113223 GL_READ_FRAMEBUFFER_EXT,
3224 func_name);
[email protected]0d6bfdc2011-11-02 01:32:203225}
3226
[email protected]2ea5950d2014-07-09 18:20:343227bool GLES2DecoderImpl::CheckBoundReadFramebufferColorAttachment(
3228 const char* func_name) {
3229 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3230 framebuffer_state_.bound_read_framebuffer.get() :
3231 framebuffer_state_.bound_draw_framebuffer.get();
3232 if (!framebuffer)
3233 return true;
3234 if (framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL) {
3235 LOCAL_SET_GL_ERROR(
3236 GL_INVALID_OPERATION, func_name, "no color image attached");
3237 return false;
3238 }
3239 return true;
3240}
3241
[email protected]8e3e0662010-08-23 18:46:303242gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:353243 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453244 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203245 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:353246 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:203247 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:263248 if (attachment) {
3249 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:503250 }
[email protected]9edc6b22010-12-23 02:00:263251 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:023252 } else if (offscreen_target_frame_buffer_.get()) {
3253 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:353254 } else {
[email protected]f62a5ab2011-05-23 20:34:153255 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:023256 }
[email protected]246a70452010-03-05 21:53:503257}
3258
[email protected]68586372013-12-11 01:27:593259GLenum GLES2DecoderImpl::GetBoundReadFrameBufferTextureType() {
3260 Framebuffer* framebuffer =
3261 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
3262 if (framebuffer != NULL) {
3263 return framebuffer->GetColorAttachmentTextureType();
3264 } else {
3265 return GL_UNSIGNED_BYTE;
3266 }
3267}
3268
[email protected]9edc6b22010-12-23 02:00:263269GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353270 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453271 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203272 if (framebuffer != NULL) {
3273 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:463274 } else if (offscreen_target_frame_buffer_.get()) {
3275 return offscreen_target_color_format_;
3276 } else {
3277 return back_buffer_color_format_;
3278 }
3279}
3280
3281GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353282 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453283 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203284 if (framebuffer != NULL) {
3285 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:263286 } else if (offscreen_target_frame_buffer_.get()) {
3287 return offscreen_target_color_format_;
3288 } else {
[email protected]32fe9aa2011-01-21 23:47:133289 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:263290 }
3291}
3292
[email protected]9a5afa432011-07-22 18:16:393293void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]2ad674132013-06-05 07:48:513294 if (!offscreen_saved_color_texture_info_.get())
3295 return;
3296 GLenum target = offscreen_saved_color_texture_info_->texture()->target();
3297 glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
3298 texture_manager()->SetLevelInfo(
3299 offscreen_saved_color_texture_info_.get(),
3300 GL_TEXTURE_2D,
3301 0, // level
3302 GL_RGBA,
3303 offscreen_size_.width(),
3304 offscreen_size_.height(),
3305 1, // depth
3306 0, // border
3307 GL_RGBA,
3308 GL_UNSIGNED_BYTE,
3309 true);
[email protected]737191ee72014-03-09 08:02:423310 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513311 "UpdateParentTextureInfo",
3312 GetErrorState(),
3313 offscreen_saved_color_texture_info_.get(),
3314 GL_TEXTURE_MAG_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263315 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423316 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513317 "UpdateParentTextureInfo",
3318 GetErrorState(),
3319 offscreen_saved_color_texture_info_.get(),
3320 GL_TEXTURE_MIN_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263321 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423322 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513323 "UpdateParentTextureInfo",
3324 GetErrorState(),
3325 offscreen_saved_color_texture_info_.get(),
3326 GL_TEXTURE_WRAP_S,
3327 GL_CLAMP_TO_EDGE);
[email protected]737191ee72014-03-09 08:02:423328 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513329 "UpdateParentTextureInfo",
3330 GetErrorState(),
3331 offscreen_saved_color_texture_info_.get(),
3332 GL_TEXTURE_WRAP_T,
3333 GL_CLAMP_TO_EDGE);
[email protected]c986af502013-08-14 01:04:443334 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
3335 &state_, target);
[email protected]2ad674132013-06-05 07:48:513336 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
[email protected]6217d392010-03-25 22:08:353337}
3338
[email protected]799b4b22011-08-22 17:09:593339void GLES2DecoderImpl::SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:073340 const base::Callback<void(gfx::Size, float)>& callback) {
[email protected]9d37f062011-11-22 01:24:523341 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:003342}
3343
[email protected]1d82e822013-04-10 21:32:323344Logger* GLES2DecoderImpl::GetLogger() {
3345 return &logger_;
[email protected]6b6e7ee2011-12-13 08:04:523346}
3347
[email protected]cac16542014-01-15 17:53:513348void GLES2DecoderImpl::BeginDecoding() {
3349 gpu_tracer_->BeginDecoding();
3350 gpu_trace_commands_ = gpu_tracer_->IsTracing();
vmiura1c2b1de2014-09-19 19:03:243351 gpu_debug_commands_ = log_commands() || debug() || gpu_trace_commands_ ||
3352 (*cb_command_trace_category_ != 0);
[email protected]cac16542014-01-15 17:53:513353}
3354
3355void GLES2DecoderImpl::EndDecoding() {
3356 gpu_tracer_->EndDecoding();
3357}
3358
[email protected]d3eba342013-04-18 21:11:503359ErrorState* GLES2DecoderImpl::GetErrorState() {
3360 return state_.GetErrorState();
3361}
3362
[email protected]e3932abb2013-03-13 00:01:373363void GLES2DecoderImpl::SetShaderCacheCallback(
3364 const ShaderCacheCallback& callback) {
3365 shader_cache_callback_ = callback;
3366}
3367
[email protected]840a7e462013-02-27 01:29:513368void GLES2DecoderImpl::SetWaitSyncPointCallback(
3369 const WaitSyncPointCallback& callback) {
3370 wait_sync_point_callback_ = callback;
3371}
3372
[email protected]85a4ac22013-05-31 01:58:473373AsyncPixelTransferManager*
3374 GLES2DecoderImpl::GetAsyncPixelTransferManager() {
3375 return async_pixel_transfer_manager_.get();
3376}
3377
3378void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
3379 async_pixel_transfer_manager_.reset();
[email protected]32145a92012-12-17 09:01:593380}
3381
[email protected]498b5c072013-06-04 19:30:073382void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest(
3383 AsyncPixelTransferManager* manager) {
3384 async_pixel_transfer_manager_ = make_scoped_ptr(manager);
3385}
3386
[email protected]1318e922010-09-17 22:03:163387bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3388 uint32* service_texture_id) {
[email protected]370eaf12013-05-18 09:19:493389 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3390 if (texture_ref) {
3391 *service_texture_id = texture_ref->service_id();
[email protected]1318e922010-09-17 22:03:163392 return true;
3393 }
3394 return false;
3395}
3396
[email protected]63b465922012-09-06 02:04:523397uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]c986af502013-08-14 01:04:443398 return texture_state_.texture_upload_count +
[email protected]b68b100752013-06-05 08:34:483399 async_pixel_transfer_manager_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523400}
3401
3402base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]c986af502013-08-14 01:04:443403 return texture_state_.total_texture_upload_time +
[email protected]b68b100752013-06-05 08:34:483404 async_pixel_transfer_manager_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523405}
3406
3407base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3408 return total_processing_commands_time_;
3409}
3410
[email protected]dc25dda2012-09-27 21:36:303411void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3412 total_processing_commands_time_ += time;
3413}
3414
[email protected]63c9b052012-05-17 18:27:383415void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063416 if (!initialized())
3417 return;
3418
[email protected]63c9b052012-05-17 18:27:383419 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053420
[email protected]80eb6b52012-01-19 00:14:413421 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243422 state_.vertex_attrib_manager = NULL;
[email protected]81f20a622014-04-18 01:54:523423 state_.default_vertex_attrib_manager = NULL;
[email protected]1868a342012-11-07 15:56:023424 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243425 state_.bound_array_buffer = NULL;
[email protected]8ebd46c2014-01-08 12:06:133426 state_.current_queries.clear();
[email protected]9d3b2e12013-10-02 01:04:343427 framebuffer_state_.bound_read_framebuffer = NULL;
3428 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]e259eb412012-10-13 05:47:243429 state_.bound_renderbuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413430
[email protected]cadac622013-06-11 16:46:363431 if (offscreen_saved_color_texture_info_.get()) {
[email protected]2ad674132013-06-05 07:48:513432 DCHECK(offscreen_target_color_texture_);
3433 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
3434 offscreen_saved_color_texture_->id());
3435 offscreen_saved_color_texture_->Invalidate();
3436 offscreen_saved_color_texture_info_ = NULL;
3437 }
[email protected]eadc96792010-10-27 19:39:393438 if (have_context) {
[email protected]c322e882012-05-23 18:06:183439 if (copy_texture_CHROMIUM_.get()) {
3440 copy_texture_CHROMIUM_->Destroy();
3441 copy_texture_CHROMIUM_.reset();
3442 }
[email protected]43410e92012-04-20 17:06:283443
[email protected]7cd76fd2013-06-02 21:11:113444 if (state_.current_program.get()) {
3445 program_manager()->UnuseProgram(shader_manager(),
3446 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:143447 }
3448
[email protected]b1122982010-05-17 23:04:243449 if (attrib_0_buffer_id_) {
3450 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3451 }
[email protected]8fbedc02010-11-18 18:43:403452 if (fixed_attrib_buffer_id_) {
3453 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3454 }
[email protected]b1122982010-05-17 23:04:243455
[email protected]4a4c18b2013-09-13 22:50:103456 if (validation_texture_) {
3457 glDeleteTextures(1, &validation_texture_);
3458 glDeleteFramebuffersEXT(1, &validation_fbo_multisample_);
3459 glDeleteFramebuffersEXT(1, &validation_fbo_);
3460 }
3461
[email protected]97872062010-11-03 19:07:053462 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543463 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053464 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543465 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053466 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023467 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053468 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153469 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053470 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153471 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053472 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023473 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053474 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543475 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273476 if (offscreen_resolved_frame_buffer_.get())
3477 offscreen_resolved_frame_buffer_->Destroy();
3478 if (offscreen_resolved_color_texture_.get())
3479 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053480 } else {
3481 if (offscreen_target_frame_buffer_.get())
3482 offscreen_target_frame_buffer_->Invalidate();
3483 if (offscreen_target_color_texture_.get())
3484 offscreen_target_color_texture_->Invalidate();
3485 if (offscreen_target_color_render_buffer_.get())
3486 offscreen_target_color_render_buffer_->Invalidate();
3487 if (offscreen_target_depth_render_buffer_.get())
3488 offscreen_target_depth_render_buffer_->Invalidate();
3489 if (offscreen_target_stencil_render_buffer_.get())
3490 offscreen_target_stencil_render_buffer_->Invalidate();
3491 if (offscreen_saved_frame_buffer_.get())
3492 offscreen_saved_frame_buffer_->Invalidate();
3493 if (offscreen_saved_color_texture_.get())
3494 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273495 if (offscreen_resolved_frame_buffer_.get())
3496 offscreen_resolved_frame_buffer_->Invalidate();
3497 if (offscreen_resolved_color_texture_.get())
3498 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023499 }
[email protected]83a52d032013-07-24 10:30:373500
3501 // Current program must be cleared after calling ProgramManager::UnuseProgram.
3502 // Otherwise, we can leak objects. http://crbug.com/258772.
3503 // state_.current_program must be reset before group_ is reset because
3504 // the later deletes the ProgramManager object that referred by
3505 // state_.current_program object.
3506 state_.current_program = NULL;
3507
[email protected]43410e92012-04-20 17:06:283508 copy_texture_CHROMIUM_.reset();
[email protected]97872062010-11-03 19:07:053509
[email protected]882ba1e22012-03-08 19:02:533510 if (query_manager_.get()) {
3511 query_manager_->Destroy(have_context);
3512 query_manager_.reset();
3513 }
3514
[email protected]944b62f32012-09-27 02:20:463515 if (vertex_array_manager_ .get()) {
3516 vertex_array_manager_->Destroy(have_context);
3517 vertex_array_manager_.reset();
3518 }
3519
[email protected]d2eaf52f2014-07-31 15:01:243520 if (image_manager_.get()) {
3521 image_manager_->Destroy(have_context);
3522 image_manager_.reset();
3523 }
3524
[email protected]97872062010-11-03 19:07:053525 offscreen_target_frame_buffer_.reset();
3526 offscreen_target_color_texture_.reset();
3527 offscreen_target_color_render_buffer_.reset();
3528 offscreen_target_depth_render_buffer_.reset();
3529 offscreen_target_stencil_render_buffer_.reset();
3530 offscreen_saved_frame_buffer_.reset();
3531 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273532 offscreen_resolved_frame_buffer_.reset();
3533 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463534
[email protected]03cef9b2014-04-03 15:58:143535 // Need to release these before releasing |group_| which may own the
3536 // ShaderTranslatorCache.
3537 fragment_translator_ = NULL;
3538 vertex_translator_ = NULL;
3539
[email protected]85a4ac22013-05-31 01:58:473540 // Should destroy the transfer manager before the texture manager held
3541 // by the context group.
3542 async_pixel_transfer_manager_.reset();
3543
[email protected]7cd76fd2013-06-02 21:11:113544 if (group_.get()) {
[email protected]ac5e4022014-01-24 12:44:393545 framebuffer_manager()->RemoveObserver(this);
[email protected]2d9d3b92013-01-18 01:07:233546 group_->Destroy(this, have_context);
3547 group_ = NULL;
3548 }
3549
3550 if (context_.get()) {
3551 context_->ReleaseCurrent(NULL);
3552 context_ = NULL;
3553 }
3554
[email protected]e51bdf32011-11-23 22:21:463555#if defined(OS_MACOSX)
3556 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3557 it != texture_to_io_surface_map_.end(); ++it) {
3558 CFRelease(it->second);
3559 }
3560 texture_to_io_surface_map_.clear();
3561#endif
[email protected]96449d2c2009-11-25 00:01:323562}
3563
[email protected]63c9b052012-05-17 18:27:383564void GLES2DecoderImpl::SetSurface(
3565 const scoped_refptr<gfx::GLSurface>& surface) {
3566 DCHECK(context_->IsCurrent(NULL));
3567 DCHECK(surface_.get());
3568 surface_ = surface;
3569 RestoreCurrentFramebufferBindings();
3570}
3571
[email protected]aba551b2014-02-08 03:38:323572void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
3573 if (!offscreen_saved_color_texture_.get()) {
3574 LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context";
3575 return;
3576 }
[email protected]2ad674132013-06-05 07:48:513577 if (!offscreen_saved_color_texture_info_.get()) {
[email protected]3c644d82011-06-20 19:58:243578 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]f46476932013-06-08 05:36:073579 offscreen_saved_color_texture_info_ = TextureRef::Create(
3580 texture_manager(), 0, service_id);
[email protected]2ad674132013-06-05 07:48:513581 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(),
3582 GL_TEXTURE_2D);
[email protected]9a5afa432011-07-22 18:16:393583 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243584 }
[email protected]aba551b2014-02-08 03:38:323585 mailbox_manager()->ProduceTexture(
3586 GL_TEXTURE_2D, mailbox, offscreen_saved_color_texture_info_->texture());
[email protected]3c644d82011-06-20 19:58:243587}
3588
[email protected]799b4b22011-08-22 17:09:593589bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3590 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3591 if (!is_offscreen) {
3592 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3593 << " with an onscreen framebuffer.";
3594 return false;
3595 }
3596
3597 if (offscreen_size_ == size)
3598 return true;
3599
3600 offscreen_size_ = size;
3601 int w = offscreen_size_.width();
3602 int h = offscreen_size_.height();
3603 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3604 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3605 << "to allocate storage due to excessive dimensions.";
3606 return false;
3607 }
3608
3609 // Reallocate the offscreen target buffers.
3610 DCHECK(offscreen_target_color_format_);
3611 if (IsOffscreenBufferMultisampled()) {
3612 if (!offscreen_target_color_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253613 feature_info_.get(),
3614 offscreen_size_,
3615 offscreen_target_color_format_,
3616 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593617 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3618 << "to allocate storage for offscreen target color buffer.";
3619 return false;
3620 }
3621 } else {
3622 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093623 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593624 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3625 << "to allocate storage for offscreen target color texture.";
3626 return false;
3627 }
3628 }
3629 if (offscreen_target_depth_format_ &&
3630 !offscreen_target_depth_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253631 feature_info_.get(),
3632 offscreen_size_,
3633 offscreen_target_depth_format_,
3634 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593635 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3636 << "to allocate storage for offscreen target depth buffer.";
3637 return false;
3638 }
3639 if (offscreen_target_stencil_format_ &&
3640 !offscreen_target_stencil_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253641 feature_info_.get(),
3642 offscreen_size_,
3643 offscreen_target_stencil_format_,
3644 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593645 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3646 << "to allocate storage for offscreen target stencil buffer.";
3647 return false;
3648 }
3649
3650 // Attach the offscreen target buffers to the target frame buffer.
3651 if (IsOffscreenBufferMultisampled()) {
3652 offscreen_target_frame_buffer_->AttachRenderBuffer(
3653 GL_COLOR_ATTACHMENT0,
3654 offscreen_target_color_render_buffer_.get());
3655 } else {
3656 offscreen_target_frame_buffer_->AttachRenderTexture(
3657 offscreen_target_color_texture_.get());
3658 }
3659 if (offscreen_target_depth_format_) {
3660 offscreen_target_frame_buffer_->AttachRenderBuffer(
3661 GL_DEPTH_ATTACHMENT,
3662 offscreen_target_depth_render_buffer_.get());
3663 }
3664 const bool packed_depth_stencil =
3665 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3666 if (packed_depth_stencil) {
3667 offscreen_target_frame_buffer_->AttachRenderBuffer(
3668 GL_STENCIL_ATTACHMENT,
3669 offscreen_target_depth_render_buffer_.get());
3670 } else if (offscreen_target_stencil_format_) {
3671 offscreen_target_frame_buffer_->AttachRenderBuffer(
3672 GL_STENCIL_ATTACHMENT,
3673 offscreen_target_stencil_render_buffer_.get());
3674 }
3675
3676 if (offscreen_target_frame_buffer_->CheckStatus() !=
3677 GL_FRAMEBUFFER_COMPLETE) {
3678 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3679 << "because offscreen FBO was incomplete.";
3680 return false;
3681 }
3682
3683 // Clear the target frame buffer.
3684 {
3685 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3686 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
3687 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
[email protected]454157e2014-05-03 02:49:453688 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]799b4b22011-08-22 17:09:593689 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473690 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3691 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]799b4b22011-08-22 17:09:593692 glClearDepth(0);
[email protected]454157e2014-05-03 02:49:453693 state_.SetDeviceDepthMask(GL_TRUE);
3694 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]799b4b22011-08-22 17:09:593695 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3696 RestoreClearState();
3697 }
[email protected]d85ef76d2011-09-08 22:21:433698
3699 // Destroy the offscreen resolved framebuffers.
3700 if (offscreen_resolved_frame_buffer_.get())
3701 offscreen_resolved_frame_buffer_->Destroy();
3702 if (offscreen_resolved_color_texture_.get())
3703 offscreen_resolved_color_texture_->Destroy();
3704 offscreen_resolved_color_texture_.reset();
3705 offscreen_resolved_frame_buffer_.reset();
3706
[email protected]799b4b22011-08-22 17:09:593707 return true;
[email protected]6217d392010-03-25 22:08:353708}
3709
vmiuracd108592014-09-08 14:36:343710error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(uint32 immediate_data_size,
3711 const void* cmd_data) {
3712 const gles2::cmds::ResizeCHROMIUM& c =
3713 *static_cast<const gles2::cmds::ResizeCHROMIUM*>(cmd_data);
[email protected]09e17272012-11-30 10:30:443714 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023715 return error::kDeferCommandUntilLater;
3716
[email protected]799b4b22011-08-22 17:09:593717 GLuint width = static_cast<GLuint>(c.width);
3718 GLuint height = static_cast<GLuint>(c.height);
[email protected]729c0b42013-05-26 02:05:073719 GLfloat scale_factor = c.scale_factor;
[email protected]799b4b22011-08-22 17:09:593720 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:413721
3722 width = std::max(1U, width);
3723 height = std::max(1U, height);
3724
[email protected]a0d989162011-11-22 13:15:073725#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3726 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003727 // Make sure that we are done drawing to the back buffer before resizing.
3728 glFinish();
3729#endif
[email protected]799b4b22011-08-22 17:09:593730 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3731 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493732 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3733 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3734 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593735 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493736 }
[email protected]7ff86b92010-11-25 17:50:003737 }
[email protected]799b4b22011-08-22 17:09:593738
[email protected]9d37f062011-11-22 01:24:523739 if (!resize_callback_.is_null()) {
[email protected]729c0b42013-05-26 02:05:073740 resize_callback_.Run(gfx::Size(width, height), scale_factor);
[email protected]0e9346b2013-03-16 16:35:443741 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493742 if (!context_->IsCurrent(surface_.get())) {
3743 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3744 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053745 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493746 }
[email protected]658f7562011-09-09 05:24:053747 }
[email protected]799b4b22011-08-22 17:09:593748
3749 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393750}
3751
[email protected]96449d2c2009-11-25 00:01:323752const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3753 if (command_id > kStartPoint && command_id < kNumCommands) {
3754 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3755 }
3756 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3757}
3758
vmiura8266ca72014-09-09 21:37:003759// Decode a command, and call the corresponding GL functions.
3760// NOTE: DoCommand() is slower than calling DoCommands() on larger batches
3761// of commands at once, and is now only used for tests that need to track
3762// individual commands.
3763error::Error GLES2DecoderImpl::DoCommand(unsigned int command,
3764 unsigned int arg_count,
3765 const void* cmd_data) {
3766 return DoCommands(1, cmd_data, arg_count + 1, 0);
3767}
3768
3769// Decode multiple commands, and call the corresponding GL functions.
3770// NOTE: 'buffer' is a pointer to the command buffer. As such, it could be
3771// changed by a (malicious) client at any time, so if validation has to happen,
3772// it should operate on a copy of them.
3773// NOTE: This is duplicating code from AsyncAPIInterface::DoCommands() in the
3774// interest of performance in this critical execution loop.
vmiura1c2b1de2014-09-19 19:03:243775template <bool DebugImpl>
3776error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands,
3777 const void* buffer,
3778 int num_entries,
3779 int* entries_processed) {
vmiura8266ca72014-09-09 21:37:003780 commands_to_process_ = num_commands;
[email protected]f7a64ee2010-02-01 22:24:143781 error::Error result = error::kNoError;
vmiura8266ca72014-09-09 21:37:003782 const CommandBufferEntry* cmd_data =
3783 static_cast<const CommandBufferEntry*>(buffer);
3784 int process_pos = 0;
3785 unsigned int command = 0;
3786
3787 while (process_pos < num_entries && result == error::kNoError &&
3788 commands_to_process_--) {
3789 const unsigned int size = cmd_data->value_header.size;
3790 command = cmd_data->value_header.command;
3791
3792 if (size == 0) {
3793 result = error::kInvalidSize;
3794 break;
3795 }
3796
3797 if (static_cast<int>(size) + process_pos > num_entries) {
3798 result = error::kOutOfBounds;
3799 break;
3800 }
3801
vmiura1c2b1de2014-09-19 19:03:243802 if (DebugImpl) {
3803 TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
3804 GetCommandName(command));
vmiura8266ca72014-09-09 21:37:003805
vmiura1c2b1de2014-09-19 19:03:243806 if (log_commands()) {
3807 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]"
3808 << "cmd: " << GetCommandName(command);
3809 }
vmiura8266ca72014-09-09 21:37:003810 }
3811
3812 const unsigned int arg_count = size - 1;
3813 unsigned int command_index = command - kStartPoint - 1;
3814 if (command_index < arraysize(command_info)) {
3815 const CommandInfo& info = command_info[command_index];
3816 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3817 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3818 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
3819 bool doing_gpu_trace = false;
vmiura1c2b1de2014-09-19 19:03:243820 if (DebugImpl && gpu_trace_commands_) {
vmiura8266ca72014-09-09 21:37:003821 if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) {
3822 doing_gpu_trace = true;
3823 gpu_tracer_->Begin(GetCommandName(command), kTraceDecoder);
3824 }
[email protected]cac16542014-01-15 17:53:513825 }
[email protected]cac16542014-01-15 17:53:513826
vmiura8266ca72014-09-09 21:37:003827 uint32 immediate_data_size = (arg_count - info_arg_count) *
3828 sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:323829
vmiura8266ca72014-09-09 21:37:003830 result = (this->*info.cmd_handler)(immediate_data_size, cmd_data);
[email protected]cac16542014-01-15 17:53:513831
vmiura1c2b1de2014-09-19 19:03:243832 if (DebugImpl && doing_gpu_trace)
vmiura8266ca72014-09-09 21:37:003833 gpu_tracer_->End(kTraceDecoder);
[email protected]cac16542014-01-15 17:53:513834
vmiura1c2b1de2014-09-19 19:03:243835 if (DebugImpl && debug()) {
vmiura8266ca72014-09-09 21:37:003836 GLenum error;
3837 while ((error = glGetError()) != GL_NO_ERROR) {
3838 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
3839 << "GL ERROR: " << GLES2Util::GetStringEnum(error)
3840 << " : " << GetCommandName(command);
3841 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
3842 }
[email protected]b9849abf2009-11-25 19:13:193843 }
vmiura8266ca72014-09-09 21:37:003844 } else {
3845 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:323846 }
3847 } else {
vmiura8266ca72014-09-09 21:37:003848 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:323849 }
vmiura1c2b1de2014-09-19 19:03:243850
3851 if (DebugImpl) {
3852 TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
3853 GetCommandName(command));
3854 }
3855
vmiura8266ca72014-09-09 21:37:003856 if (result == error::kNoError &&
3857 current_decoder_error_ != error::kNoError) {
[email protected]a3a93e7b2010-08-28 00:48:563858 result = current_decoder_error_;
3859 current_decoder_error_ = error::kNoError;
vmiura8266ca72014-09-09 21:37:003860 }
3861
3862 if (result != error::kDeferCommandUntilLater) {
3863 process_pos += size;
3864 cmd_data += size;
3865 }
[email protected]a3a93e7b2010-08-28 00:48:563866 }
vmiura8266ca72014-09-09 21:37:003867
3868 if (entries_processed)
3869 *entries_processed = process_pos;
3870
3871 if (error::IsError(result)) {
3872 LOG(ERROR) << "Error: " << result << " for Command "
3873 << GetCommandName(command);
3874 }
3875
[email protected]b9849abf2009-11-25 19:13:193876 return result;
[email protected]96449d2c2009-11-25 00:01:323877}
3878
vmiura1c2b1de2014-09-19 19:03:243879error::Error GLES2DecoderImpl::DoCommands(unsigned int num_commands,
3880 const void* buffer,
3881 int num_entries,
3882 int* entries_processed) {
3883 if (gpu_debug_commands_) {
3884 return DoCommandsImpl<true>(
3885 num_commands, buffer, num_entries, entries_processed);
3886 } else {
3887 return DoCommandsImpl<false>(
3888 num_commands, buffer, num_entries, entries_processed);
3889 }
3890}
3891
[email protected]ed9f9cd2013-02-27 21:12:353892void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
3893 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:503894}
3895
[email protected]ae51d192010-04-27 00:48:033896bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353897 if (GetProgram(client_id)) {
[email protected]ae51d192010-04-27 00:48:033898 return false;
3899 }
[email protected]96449d2c2009-11-25 00:01:323900 GLuint service_id = glCreateProgram();
[email protected]ae51d192010-04-27 00:48:033901 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353902 CreateProgram(client_id, service_id);
[email protected]96449d2c2009-11-25 00:01:323903 }
[email protected]ae51d192010-04-27 00:48:033904 return true;
[email protected]96449d2c2009-11-25 00:01:323905}
3906
[email protected]ae51d192010-04-27 00:48:033907bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353908 if (GetShader(client_id)) {
[email protected]ae51d192010-04-27 00:48:033909 return false;
[email protected]96449d2c2009-11-25 00:01:323910 }
[email protected]ae51d192010-04-27 00:48:033911 GLuint service_id = glCreateShader(type);
3912 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353913 CreateShader(client_id, service_id, type);
[email protected]ae51d192010-04-27 00:48:033914 }
3915 return true;
[email protected]96449d2c2009-11-25 00:01:323916}
3917
[email protected]882ba1e22012-03-08 19:02:533918void GLES2DecoderImpl::DoFinish() {
3919 glFinish();
[email protected]5a36dc132013-07-23 23:17:553920 ProcessPendingReadPixels();
[email protected]22e3f552012-03-13 01:54:193921 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533922}
3923
3924void GLES2DecoderImpl::DoFlush() {
3925 glFlush();
[email protected]22e3f552012-03-13 01:54:193926 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533927}
3928
[email protected]3916c97e2010-02-25 03:20:503929void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:453930 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:023931 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:513932 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:533933 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:503934 return;
3935 }
[email protected]e259eb412012-10-13 05:47:243936 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:453937 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:503938}
3939
[email protected]051b1372010-04-12 02:42:083940void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:073941 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:083942 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033943 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:073944 buffer = GetBuffer(client_id);
3945 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:353946 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:223947 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
3948 "glBindBuffer",
3949 "id not generated by glGenBuffers");
[email protected]bf5a8d132011-08-16 08:39:353950 return;
3951 }
3952
[email protected]b10492f2013-03-08 05:24:073953 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:033954 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353955 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:073956 buffer = GetBuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573957 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103958 group_->GetIdAllocator(id_namespaces::kBuffers);
3959 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033960 }
[email protected]051b1372010-04-12 02:42:083961 }
[email protected]b10492f2013-03-08 05:24:073962 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
3963 if (buffer) {
3964 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:513965 LOCAL_SET_GL_ERROR(
3966 GL_INVALID_OPERATION,
3967 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:473968 return;
3969 }
[email protected]b10492f2013-03-08 05:24:073970 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:473971 }
[email protected]96449d2c2009-11-25 00:01:323972 switch (target) {
3973 case GL_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073974 state_.bound_array_buffer = buffer;
[email protected]96449d2c2009-11-25 00:01:323975 break;
3976 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073977 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
[email protected]96449d2c2009-11-25 00:01:323978 break;
3979 default:
[email protected]a93bb842010-02-16 23:03:473980 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:323981 break;
3982 }
[email protected]051b1372010-04-12 02:42:083983 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:323984}
3985
[email protected]f3b191b2013-06-19 03:43:543986bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha(
3987 bool all_draw_buffers) {
3988 Framebuffer* framebuffer =
3989 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
3990 if (!all_draw_buffers || !framebuffer) {
3991 return (GLES2Util::GetChannelsForFormat(
3992 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
3993 }
3994 return framebuffer->HasAlphaMRT();
[email protected]297ca1c2011-06-20 23:08:463995}
3996
3997bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353998 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453999 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204000 if (framebuffer) {
4001 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:464002 }
4003 if (offscreen_target_frame_buffer_.get()) {
4004 return offscreen_target_depth_format_ != 0;
4005 }
4006 return back_buffer_has_depth_;
4007}
4008
4009bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:354010 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454011 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204012 if (framebuffer) {
4013 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:464014 }
4015 if (offscreen_target_frame_buffer_.get()) {
4016 return offscreen_target_stencil_format_ != 0 ||
4017 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
4018 }
4019 return back_buffer_has_stencil_;
4020}
4021
4022void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]c986af502013-08-14 01:04:444023 if (framebuffer_state_.clear_state_dirty) {
[email protected]454157e2014-05-03 02:49:454024 bool have_alpha = BoundFramebufferHasColorAttachmentWithAlpha(true);
4025 state_.SetDeviceColorMask(state_.color_mask_red,
4026 state_.color_mask_green,
4027 state_.color_mask_blue,
4028 state_.color_mask_alpha && have_alpha);
4029
[email protected]297ca1c2011-06-20 23:08:464030 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]454157e2014-05-03 02:49:454031 state_.SetDeviceDepthMask(state_.depth_mask && have_depth);
4032
[email protected]297ca1c2011-06-20 23:08:464033 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]454157e2014-05-03 02:49:454034 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424035 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]454157e2014-05-03 02:49:454036 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424037 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]454157e2014-05-03 02:49:454038
4039 state_.SetDeviceCapabilityState(
4040 GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
4041 state_.SetDeviceCapabilityState(
[email protected]f731b9462012-10-30 00:35:224042 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
[email protected]c986af502013-08-14 01:04:444043 framebuffer_state_.clear_state_dirty = false;
[email protected]297ca1c2011-06-20 23:08:464044 }
4045}
4046
[email protected]1868a342012-11-07 15:56:024047GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]7cd76fd2013-06-02 21:11:114048 return (offscreen_target_frame_buffer_.get())
4049 ? offscreen_target_frame_buffer_->id()
4050 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0);
[email protected]1868a342012-11-07 15:56:024051}
4052
[email protected]8875a5f2014-06-27 08:33:474053void GLES2DecoderImpl::RestoreState(const ContextState* prev_state) {
[email protected]962bfbe72013-05-24 11:16:144054 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
4055 "context", logger_.GetLogPrefix());
[email protected]29a4d902013-02-26 20:18:064056 // Restore the Framebuffer first because of bugs in Intel drivers.
4057 // Intel drivers incorrectly clip the viewport settings to
4058 // the size of the current framebuffer object.
4059 RestoreFramebufferBindings();
[email protected]5baa86bc2014-01-16 04:33:164060 state_.RestoreState(prev_state);
[email protected]29a4d902013-02-26 20:18:064061}
4062
4063void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]9d3b2e12013-10-02 01:04:344064 GLuint service_id =
4065 framebuffer_state_.bound_draw_framebuffer.get()
4066 ? framebuffer_state_.bound_draw_framebuffer->service_id()
4067 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064068 if (!features().chromium_framebuffer_multisample) {
4069 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
4070 } else {
4071 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
[email protected]9d3b2e12013-10-02 01:04:344072 service_id = framebuffer_state_.bound_read_framebuffer.get()
4073 ? framebuffer_state_.bound_read_framebuffer->service_id()
[email protected]7cd76fd2013-06-02 21:11:114074 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064075 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
4076 }
[email protected]70d34263c2013-01-09 00:27:454077 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:064078}
4079
[email protected]8875a5f2014-06-27 08:33:474080void GLES2DecoderImpl::RestoreRenderbufferBindings() {
4081 state_.RestoreRenderbufferBindings();
4082}
4083
[email protected]29a4d902013-02-26 20:18:064084void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
[email protected]62e65f02013-05-29 22:28:104085 Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
4086 if (texture) {
[email protected]9bc9a2e82013-04-03 03:56:254087 GLenum target = texture->target();
4088 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:064089 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254090 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:064091 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254092 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:064093 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254094 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:064095 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254096 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:064097 RestoreTextureUnitBindings(state_.active_texture_unit);
4098 }
[email protected]70d34263c2013-01-09 00:27:454099}
4100
[email protected]cd2ef752014-02-12 23:16:034101void GLES2DecoderImpl::ClearAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524102 // Must use native VAO 0, as RestoreAllAttributes can't fully restore
4103 // other VAOs.
4104 if (feature_info_->feature_flags().native_vertex_array_object)
4105 glBindVertexArrayOES(0);
4106
[email protected]cd2ef752014-02-12 23:16:034107 for (uint32 i = 0; i < group_->max_vertex_attribs(); ++i) {
4108 if (i != 0) // Never disable attribute 0
4109 glDisableVertexAttribArray(i);
4110 if(features().angle_instanced_arrays)
4111 glVertexAttribDivisorANGLE(i, 0);
4112 }
4113}
4114
4115void GLES2DecoderImpl::RestoreAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524116 state_.RestoreVertexAttribs();
[email protected]cd2ef752014-02-12 23:16:034117}
4118
[email protected]454157e2014-05-03 02:49:454119void GLES2DecoderImpl::SetIgnoreCachedStateForTest(bool ignore) {
4120 state_.SetIgnoreCachedStateForTest(ignore);
4121}
4122
[email protected]70d34263c2013-01-09 00:27:454123void GLES2DecoderImpl::OnFboChanged() const {
4124 if (workarounds().restore_scissor_on_fbo_change)
[email protected]28718a92013-04-04 12:12:514125 state_.fbo_binding_for_scissor_workaround_dirty_ = true;
4126}
4127
4128// Called after the FBO is checked for completeness.
4129void GLES2DecoderImpl::OnUseFramebuffer() const {
4130 if (state_.fbo_binding_for_scissor_workaround_dirty_) {
4131 state_.fbo_binding_for_scissor_workaround_dirty_ = false;
[email protected]81fc9d02013-03-14 23:53:324132 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:514133 glScissor(state_.scissor_x,
4134 state_.scissor_y,
4135 state_.scissor_width,
4136 state_.scissor_height);
4137
4138 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
4139 // it's unclear how this bug works.
4140 glFlush();
4141 }
[email protected]b177ae22011-11-01 03:29:114142}
4143
[email protected]051b1372010-04-12 02:42:084144void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:064145 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:084146 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034147 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:064148 framebuffer = GetFramebuffer(client_id);
4149 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:354150 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224151 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4152 "glBindFramebuffer",
4153 "id not generated by glGenFramebuffers");
4154 return;
[email protected]bf5a8d132011-08-16 08:39:354155 }
4156
[email protected]4d8f0dd2013-03-09 14:37:064157 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:034158 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354159 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:064160 framebuffer = GetFramebuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:574161 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:104162 group_->GetIdAllocator(id_namespaces::kFramebuffers);
4163 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:034164 } else {
[email protected]4d8f0dd2013-03-09 14:37:064165 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:084166 }
[email protected]4d8f0dd2013-03-09 14:37:064167 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084168 }
[email protected]4d8f0dd2013-03-09 14:37:064169 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:304170
4171 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344172 framebuffer_state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304173 }
[email protected]cac16542014-01-15 17:53:514174
4175 // vmiura: This looks like dup code
[email protected]8e3e0662010-08-23 18:46:304176 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344177 framebuffer_state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304178 }
[email protected]6217d392010-03-25 22:08:354179
[email protected]c986af502013-08-14 01:04:444180 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:464181
[email protected]b177ae22011-11-01 03:29:114182 // If we are rendering to the backbuffer get the FBO id for any simulated
4183 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:064184 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:114185 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:464186 }
[email protected]6217d392010-03-25 22:08:354187
[email protected]051b1372010-04-12 02:42:084188 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:454189 OnFboChanged();
[email protected]86093972010-03-11 00:13:564190}
4191
[email protected]051b1372010-04-12 02:42:084192void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:274193 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:084194 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034195 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:274196 renderbuffer = GetRenderbuffer(client_id);
4197 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:354198 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224199 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4200 "glBindRenderbuffer",
4201 "id not generated by glGenRenderbuffers");
[email protected]bf5a8d132011-08-16 08:39:354202 return;
4203 }
4204
[email protected]8875a5f2014-06-27 08:33:474205 // It's a new id so make a renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:034206 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354207 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:274208 renderbuffer = GetRenderbuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:574209 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:104210 group_->GetIdAllocator(id_namespaces::kRenderbuffers);
4211 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:034212 } else {
[email protected]ee2a79c32013-03-10 03:50:274213 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:084214 }
[email protected]ee2a79c32013-03-10 03:50:274215 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084216 }
[email protected]caa13ed2014-02-17 11:29:204217 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenderbuffer");
[email protected]ee2a79c32013-03-10 03:50:274218 state_.bound_renderbuffer = renderbuffer;
[email protected]8875a5f2014-06-27 08:33:474219 state_.bound_renderbuffer_valid = true;
4220 glBindRenderbufferEXT(GL_RENDERBUFFER, service_id);
[email protected]86093972010-03-11 00:13:564221}
4222
[email protected]051b1372010-04-12 02:42:084223void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:494224 TextureRef* texture_ref = NULL;
[email protected]051b1372010-04-12 02:42:084225 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034226 if (client_id != 0) {
[email protected]370eaf12013-05-18 09:19:494227 texture_ref = GetTexture(client_id);
4228 if (!texture_ref) {
[email protected]bf5a8d132011-08-16 08:39:354229 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224230 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4231 "glBindTexture",
4232 "id not generated by glGenTextures");
4233 return;
[email protected]bf5a8d132011-08-16 08:39:354234 }
4235
[email protected]02965c22013-03-09 02:40:074236 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:034237 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:414238 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:354239 CreateTexture(client_id, service_id);
[email protected]370eaf12013-05-18 09:19:494240 texture_ref = GetTexture(client_id);
[email protected]3b1ecc262011-08-03 22:49:574241 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:104242 group_->GetIdAllocator(id_namespaces::kTextures);
4243 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:034244 }
4245 } else {
[email protected]370eaf12013-05-18 09:19:494246 texture_ref = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:084247 }
[email protected]ae51d192010-04-27 00:48:034248
[email protected]1958e0e2010-04-22 05:17:154249 // Check the texture exists
[email protected]5ebf59f2014-04-08 03:51:574250 if (texture_ref) {
4251 Texture* texture = texture_ref->texture();
4252 // Check that we are not trying to bind it to a different target.
4253 if (texture->target() != 0 && texture->target() != target) {
4254 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4255 "glBindTexture",
4256 "texture bound to more than 1 target.");
4257 return;
4258 }
4259 LogClientServiceForInfo(texture, client_id, "glBindTexture");
4260 if (texture->target() == 0) {
4261 texture_manager()->SetTarget(texture_ref, target);
4262 }
4263 glBindTexture(target, texture->service_id());
4264 } else {
4265 glBindTexture(target, 0);
[email protected]1958e0e2010-04-22 05:17:154266 }
[email protected]32145a92012-12-17 09:01:594267
[email protected]e259eb412012-10-13 05:47:244268 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:504269 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:474270 switch (target) {
4271 case GL_TEXTURE_2D:
[email protected]370eaf12013-05-18 09:19:494272 unit.bound_texture_2d = texture_ref;
[email protected]a93bb842010-02-16 23:03:474273 break;
4274 case GL_TEXTURE_CUBE_MAP:
[email protected]370eaf12013-05-18 09:19:494275 unit.bound_texture_cube_map = texture_ref;
[email protected]a93bb842010-02-16 23:03:474276 break;
[email protected]61eeb33f2011-07-26 15:30:314277 case GL_TEXTURE_EXTERNAL_OES:
[email protected]370eaf12013-05-18 09:19:494278 unit.bound_texture_external_oes = texture_ref;
[email protected]61eeb33f2011-07-26 15:30:314279 break;
[email protected]e51bdf32011-11-23 22:21:464280 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]370eaf12013-05-18 09:19:494281 unit.bound_texture_rectangle_arb = texture_ref;
[email protected]e51bdf32011-11-23 22:21:464282 break;
[email protected]a93bb842010-02-16 23:03:474283 default:
4284 NOTREACHED(); // Validation should prevent us getting here.
4285 break;
4286 }
4287}
4288
[email protected]07f54fcc2009-12-22 02:46:304289void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244290 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:124291 if (index != 0 ||
4292 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:244293 glDisableVertexAttribArray(index);
4294 }
[email protected]07f54fcc2009-12-22 02:46:304295 } else {
[email protected]ab09b612013-03-11 22:11:514296 LOCAL_SET_GL_ERROR(
4297 GL_INVALID_VALUE,
4298 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304299 }
4300}
4301
[email protected]60f22d32012-12-12 00:31:584302void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
4303 GLsizei numAttachments,
4304 const GLenum* attachments) {
[email protected]ed9f9cd2013-02-27 21:12:354305 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:584306 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4307
4308 // Validates the attachments. If one of them fails
4309 // the whole command fails.
4310 for (GLsizei i = 0; i < numAttachments; ++i) {
4311 if ((framebuffer &&
4312 !validators_->attachment.IsValid(attachments[i])) ||
4313 (!framebuffer &&
4314 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:514315 LOCAL_SET_GL_ERROR_INVALID_ENUM(
4316 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:584317 return;
4318 }
4319 }
4320
4321 // Marks each one of them as not cleared
4322 for (GLsizei i = 0; i < numAttachments; ++i) {
4323 if (framebuffer) {
4324 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
4325 texture_manager(),
4326 attachments[i],
4327 false);
4328 } else {
4329 switch (attachments[i]) {
4330 case GL_COLOR_EXT:
4331 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
4332 break;
4333 case GL_DEPTH_EXT:
4334 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
4335 case GL_STENCIL_EXT:
4336 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
4337 break;
4338 default:
4339 NOTREACHED();
4340 break;
4341 }
4342 }
4343 }
4344
[email protected]d49c5402013-09-11 15:39:024345 // If the default framebuffer is bound but we are still rendering to an
4346 // FBO, translate attachment names that refer to default framebuffer
4347 // channels to corresponding framebuffer attachments.
4348 scoped_ptr<GLenum[]> translated_attachments(new GLenum[numAttachments]);
4349 for (GLsizei i = 0; i < numAttachments; ++i) {
4350 GLenum attachment = attachments[i];
4351 if (!framebuffer && GetBackbufferServiceId()) {
4352 switch (attachment) {
4353 case GL_COLOR_EXT:
4354 attachment = GL_COLOR_ATTACHMENT0;
4355 break;
4356 case GL_DEPTH_EXT:
4357 attachment = GL_DEPTH_ATTACHMENT;
4358 break;
4359 case GL_STENCIL_EXT:
4360 attachment = GL_STENCIL_ATTACHMENT;
4361 break;
4362 default:
4363 NOTREACHED();
4364 return;
4365 }
4366 }
4367 translated_attachments[i] = attachment;
4368 }
4369
4370 glDiscardFramebufferEXT(target, numAttachments, translated_attachments.get());
[email protected]60f22d32012-12-12 00:31:584371}
4372
[email protected]07f54fcc2009-12-22 02:46:304373void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244374 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:304375 glEnableVertexAttribArray(index);
4376 } else {
[email protected]ab09b612013-03-11 22:11:514377 LOCAL_SET_GL_ERROR(
4378 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304379 }
4380}
4381
[email protected]a93bb842010-02-16 23:03:474382void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]c986af502013-08-14 01:04:444383 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
4384 &state_, target);
[email protected]370eaf12013-05-18 09:19:494385 if (!texture_ref ||
4386 !texture_manager()->CanGenerateMipmaps(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:514387 LOCAL_SET_GL_ERROR(
4388 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:474389 return;
4390 }
[email protected]38c0a972012-05-12 00:48:024391
[email protected]12d95352012-12-14 07:23:544392 if (target == GL_TEXTURE_CUBE_MAP) {
4393 for (int i = 0; i < 6; ++i) {
4394 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]370eaf12013-05-18 09:19:494395 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
[email protected]ab09b612013-03-11 22:11:514396 LOCAL_SET_GL_ERROR(
4397 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544398 return;
4399 }
4400 }
4401 } else {
[email protected]370eaf12013-05-18 09:19:494402 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
[email protected]ab09b612013-03-11 22:11:514403 LOCAL_SET_GL_ERROR(
4404 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544405 return;
4406 }
[email protected]7687479c2012-05-14 23:54:044407 }
4408
[email protected]ab09b612013-03-11 22:11:514409 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:194410 // Workaround for Mac driver bug. In the large scheme of things setting
4411 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:564412 // hit so there's probably no need to make this conditional. The bug appears
4413 // to be that if the filtering mode is set to something that doesn't require
4414 // mipmaps for rendering, or is never set to something other than the default,
4415 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:154416 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:194417 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4418 }
[email protected]a93bb842010-02-16 23:03:474419 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:154420 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]370eaf12013-05-18 09:19:494421 glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
4422 texture_ref->texture()->min_filter());
[email protected]c892a4e12012-05-08 18:20:194423 }
[email protected]ab09b612013-03-11 22:11:514424 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:024425 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:494426 texture_manager()->MarkMipmapsGenerated(texture_ref);
[email protected]38c0a972012-05-12 00:48:024427 }
[email protected]a93bb842010-02-16 23:03:474428}
4429
[email protected]b273e432010-04-12 17:23:584430bool GLES2DecoderImpl::GetHelper(
4431 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:584432 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:154433 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4434 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434435 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4436 *num_written = 1;
[email protected]c959a09a2014-03-27 11:44:214437 // Return the GL implementation's preferred format and (see below type)
4438 // if we have the GL extension that exposes this. This allows the GPU
4439 // client to use the implementation's preferred format for glReadPixels
4440 // for optimisation.
4441 //
4442 // A conflicting extension (GL_ARB_ES2_compatibility) specifies an error
4443 // case when requested on integer/floating point buffers but which is
4444 // acceptable on GLES2 and with the GL_OES_read_format extension.
4445 //
4446 // Therefore if an error occurs we swallow the error and use the
4447 // internal implementation.
[email protected]ad84a3a2012-06-08 21:42:434448 if (params) {
[email protected]c959a09a2014-03-27 11:44:214449 if (context_->HasExtension("GL_OES_read_format")) {
4450 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4451 GetErrorState());
4452 glGetIntegerv(pname, params);
4453 if (glGetError() == GL_NO_ERROR)
4454 return true;
4455 }
[email protected]68586372013-12-11 01:27:594456 *params = GLES2Util::GetPreferredGLReadPixelsFormat(
4457 GetBoundReadFrameBufferInternalFormat());
[email protected]ad84a3a2012-06-08 21:42:434458 }
4459 return true;
4460 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4461 *num_written = 1;
4462 if (params) {
[email protected]c959a09a2014-03-27 11:44:214463 if (context_->HasExtension("GL_OES_read_format")) {
4464 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4465 GetErrorState());
4466 glGetIntegerv(pname, params);
4467 if (glGetError() == GL_NO_ERROR)
4468 return true;
4469 }
[email protected]68586372013-12-11 01:27:594470 *params = GLES2Util::GetPreferredGLReadPixelsType(
4471 GetBoundReadFrameBufferInternalFormat(),
4472 GetBoundReadFrameBufferTextureType());
[email protected]ad84a3a2012-06-08 21:42:434473 }
4474 return true;
4475 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4476 *num_written = 1;
4477 if (params) {
4478 *params = group_->max_fragment_uniform_vectors();
4479 }
4480 return true;
4481 case GL_MAX_VARYING_VECTORS:
4482 *num_written = 1;
4483 if (params) {
4484 *params = group_->max_varying_vectors();
4485 }
4486 return true;
4487 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4488 *num_written = 1;
4489 if (params) {
4490 *params = group_->max_vertex_uniform_vectors();
4491 }
4492 return true;
[email protected]4e8a5b122010-05-08 22:00:104493 }
[email protected]5cb735d2011-10-13 01:37:234494 }
4495 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:244496 case GL_MAX_VIEWPORT_DIMS:
4497 if (offscreen_target_frame_buffer_.get()) {
4498 *num_written = 2;
4499 if (params) {
4500 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4501 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4502 }
4503 return true;
4504 }
[email protected]5cb735d2011-10-13 01:37:234505 return false;
[email protected]84afefa2011-10-19 21:45:534506 case GL_MAX_SAMPLES:
4507 *num_written = 1;
4508 if (params) {
4509 params[0] = renderbuffer_manager()->max_samples();
4510 }
4511 return true;
4512 case GL_MAX_RENDERBUFFER_SIZE:
4513 *num_written = 1;
4514 if (params) {
4515 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4516 }
4517 return true;
[email protected]5cb735d2011-10-13 01:37:234518 case GL_MAX_TEXTURE_SIZE:
4519 *num_written = 1;
4520 if (params) {
4521 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4522 }
4523 return true;
4524 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4525 *num_written = 1;
4526 if (params) {
4527 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4528 }
4529 return true;
[email protected]2f143d482013-03-14 18:04:494530 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4531 *num_written = 1;
4532 if (params) {
4533 params[0] = group_->max_color_attachments();
4534 }
4535 return true;
4536 case GL_MAX_DRAW_BUFFERS_ARB:
4537 *num_written = 1;
4538 if (params) {
4539 params[0] = group_->max_draw_buffers();
4540 }
4541 return true;
[email protected]297ca1c2011-06-20 23:08:464542 case GL_ALPHA_BITS:
4543 *num_written = 1;
4544 if (params) {
4545 GLint v = 0;
4546 glGetIntegerv(GL_ALPHA_BITS, &v);
[email protected]f3b191b2013-06-19 03:43:544547 params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
[email protected]297ca1c2011-06-20 23:08:464548 }
4549 return true;
4550 case GL_DEPTH_BITS:
4551 *num_written = 1;
4552 if (params) {
4553 GLint v = 0;
4554 glGetIntegerv(GL_DEPTH_BITS, &v);
4555 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4556 }
4557 return true;
4558 case GL_STENCIL_BITS:
4559 *num_written = 1;
4560 if (params) {
4561 GLint v = 0;
4562 glGetIntegerv(GL_STENCIL_BITS, &v);
4563 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4564 }
4565 return true;
[email protected]656dcaad2010-05-07 17:18:374566 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114567 *num_written = validators_->compressed_texture_format.GetValues().size();
4568 if (params) {
4569 for (GLint ii = 0; ii < *num_written; ++ii) {
4570 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4571 }
4572 }
[email protected]656dcaad2010-05-07 17:18:374573 return true;
[email protected]b273e432010-04-12 17:23:584574 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4575 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104576 if (params) {
[email protected]302ce6d2011-07-07 23:28:114577 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104578 }
[email protected]b273e432010-04-12 17:23:584579 return true;
4580 case GL_NUM_SHADER_BINARY_FORMATS:
4581 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104582 if (params) {
[email protected]302ce6d2011-07-07 23:28:114583 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104584 }
[email protected]b273e432010-04-12 17:23:584585 return true;
4586 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114587 *num_written = validators_->shader_binary_format.GetValues().size();
4588 if (params) {
4589 for (GLint ii = 0; ii < *num_written; ++ii) {
4590 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4591 }
4592 }
4593 return true;
[email protected]b273e432010-04-12 17:23:584594 case GL_SHADER_COMPILER:
4595 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104596 if (params) {
4597 *params = GL_TRUE;
4598 }
[email protected]b273e432010-04-12 17:23:584599 return true;
[email protected]6b8cf1a2010-05-06 16:13:584600 case GL_ARRAY_BUFFER_BINDING:
4601 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104602 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114603 if (state_.bound_array_buffer.get()) {
[email protected]4e8a5b122010-05-08 22:00:104604 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:244605 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:104606 &client_id);
4607 *params = client_id;
4608 } else {
4609 *params = 0;
4610 }
[email protected]6b8cf1a2010-05-06 16:13:584611 }
4612 return true;
4613 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4614 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104615 if (params) {
[email protected]e259eb412012-10-13 05:47:244616 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:104617 GLuint client_id = 0;
4618 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:254619 state_.vertex_attrib_manager->element_array_buffer()->
4620 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104621 *params = client_id;
4622 } else {
4623 *params = 0;
4624 }
[email protected]6b8cf1a2010-05-06 16:13:584625 }
4626 return true;
4627 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304628 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584629 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104630 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354631 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454632 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204633 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104634 GLuint client_id = 0;
4635 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204636 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304637 *params = client_id;
4638 } else {
4639 *params = 0;
4640 }
4641 }
4642 return true;
[email protected]ebfb73c2012-08-15 02:37:454643 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304644 *num_written = 1;
4645 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354646 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454647 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204648 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304649 GLuint client_id = 0;
4650 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204651 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104652 *params = client_id;
4653 } else {
4654 *params = 0;
4655 }
[email protected]6b8cf1a2010-05-06 16:13:584656 }
4657 return true;
4658 case GL_RENDERBUFFER_BINDING:
4659 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104660 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354661 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204662 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4663 if (renderbuffer) {
[email protected]62e65f02013-05-29 22:28:104664 *params = renderbuffer->client_id();
[email protected]4e8a5b122010-05-08 22:00:104665 } else {
4666 *params = 0;
4667 }
[email protected]6b8cf1a2010-05-06 16:13:584668 }
4669 return true;
4670 case GL_CURRENT_PROGRAM:
4671 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104672 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114673 if (state_.current_program.get()) {
[email protected]4e8a5b122010-05-08 22:00:104674 GLuint client_id = 0;
4675 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244676 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104677 *params = client_id;
4678 } else {
4679 *params = 0;
4680 }
[email protected]6b8cf1a2010-05-06 16:13:584681 }
4682 return true;
[email protected]bf835842012-11-19 15:21:514683 case GL_VERTEX_ARRAY_BINDING_OES:
4684 *num_written = 1;
4685 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114686 if (state_.vertex_attrib_manager.get() !=
[email protected]81f20a622014-04-18 01:54:524687 state_.default_vertex_attrib_manager.get()) {
[email protected]bf835842012-11-19 15:21:514688 GLuint client_id = 0;
4689 vertex_array_manager_->GetClientId(
4690 state_.vertex_attrib_manager->service_id(), &client_id);
4691 *params = client_id;
4692 } else {
4693 *params = 0;
4694 }
4695 }
4696 return true;
[email protected]4e8a5b122010-05-08 22:00:104697 case GL_TEXTURE_BINDING_2D:
4698 *num_written = 1;
4699 if (params) {
[email protected]e259eb412012-10-13 05:47:244700 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114701 if (unit.bound_texture_2d.get()) {
[email protected]62e65f02013-05-29 22:28:104702 *params = unit.bound_texture_2d->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584703 } else {
4704 *params = 0;
4705 }
[email protected]6b8cf1a2010-05-06 16:13:584706 }
[email protected]4e8a5b122010-05-08 22:00:104707 return true;
4708 case GL_TEXTURE_BINDING_CUBE_MAP:
4709 *num_written = 1;
4710 if (params) {
[email protected]e259eb412012-10-13 05:47:244711 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114712 if (unit.bound_texture_cube_map.get()) {
[email protected]62e65f02013-05-29 22:28:104713 *params = unit.bound_texture_cube_map->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584714 } else {
4715 *params = 0;
4716 }
[email protected]6b8cf1a2010-05-06 16:13:584717 }
[email protected]4e8a5b122010-05-08 22:00:104718 return true;
[email protected]61eeb33f2011-07-26 15:30:314719 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4720 *num_written = 1;
4721 if (params) {
[email protected]e259eb412012-10-13 05:47:244722 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114723 if (unit.bound_texture_external_oes.get()) {
[email protected]62e65f02013-05-29 22:28:104724 *params = unit.bound_texture_external_oes->client_id();
[email protected]61eeb33f2011-07-26 15:30:314725 } else {
4726 *params = 0;
4727 }
4728 }
4729 return true;
[email protected]e51bdf32011-11-23 22:21:464730 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4731 *num_written = 1;
4732 if (params) {
[email protected]e259eb412012-10-13 05:47:244733 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114734 if (unit.bound_texture_rectangle_arb.get()) {
[email protected]62e65f02013-05-29 22:28:104735 *params = unit.bound_texture_rectangle_arb->client_id();
[email protected]e51bdf32011-11-23 22:21:464736 } else {
4737 *params = 0;
4738 }
4739 }
4740 return true;
[email protected]6c75c712012-06-19 15:43:174741 case GL_UNPACK_FLIP_Y_CHROMIUM:
4742 *num_written = 1;
4743 if (params) {
4744 params[0] = unpack_flip_y_;
4745 }
4746 return true;
4747 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4748 *num_written = 1;
4749 if (params) {
4750 params[0] = unpack_premultiply_alpha_;
4751 }
4752 return true;
4753 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4754 *num_written = 1;
4755 if (params) {
4756 params[0] = unpack_unpremultiply_alpha_;
4757 }
4758 return true;
[email protected]6eda6822014-04-03 23:00:504759 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
4760 *num_written = 1;
4761 if (params) {
4762 params[0] = group_->bind_generates_resource() ? 1 : 0;
4763 }
4764 return true;
[email protected]b273e432010-04-12 17:23:584765 default:
[email protected]2f143d482013-03-14 18:04:494766 if (pname >= GL_DRAW_BUFFER0_ARB &&
4767 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
4768 *num_written = 1;
4769 if (params) {
4770 Framebuffer* framebuffer =
4771 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4772 if (framebuffer) {
4773 params[0] = framebuffer->GetDrawBuffer(pname);
4774 } else { // backbuffer
4775 if (pname == GL_DRAW_BUFFER0_ARB)
4776 params[0] = group_->draw_buffer();
4777 else
4778 params[0] = GL_NONE;
4779 }
4780 }
4781 return true;
4782 }
[email protected]4e8a5b122010-05-08 22:00:104783 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534784 return false;
[email protected]b273e432010-04-12 17:23:584785 }
4786}
4787
[email protected]4e8a5b122010-05-08 22:00:104788bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4789 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264790 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534791 return true;
4792 }
[email protected]4e8a5b122010-05-08 22:00:104793 return GetHelper(pname, NULL, num_values);
4794}
4795
[email protected]7d3c36e2013-07-12 14:13:164796GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) {
4797 if (GL_MAX_SAMPLES == pname &&
4798 features().use_img_for_multisampled_render_to_texture) {
4799 return GL_MAX_SAMPLES_IMG;
4800 }
4801 return pname;
4802}
4803
[email protected]b273e432010-04-12 17:23:584804void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4805 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104806 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534807 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554808 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:264809 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:534810 GetHelper(pname, values.get(), &num_written);
4811 }
[email protected]b273e432010-04-12 17:23:584812 for (GLsizei ii = 0; ii < num_written; ++ii) {
4813 params[ii] = static_cast<GLboolean>(values[ii]);
4814 }
4815 } else {
[email protected]7d3c36e2013-07-12 14:13:164816 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584817 glGetBooleanv(pname, params);
4818 }
4819}
4820
4821void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4822 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104823 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:264824 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:534825 if (GetHelper(pname, NULL, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554826 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]f63b1232012-10-31 07:03:534827 GetHelper(pname, values.get(), &num_written);
4828 for (GLsizei ii = 0; ii < num_written; ++ii) {
4829 params[ii] = static_cast<GLfloat>(values[ii]);
4830 }
4831 } else {
[email protected]7d3c36e2013-07-12 14:13:164832 pname = AdjustGetPname(pname);
[email protected]f63b1232012-10-31 07:03:534833 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:584834 }
[email protected]b273e432010-04-12 17:23:584835 }
4836}
4837
4838void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4839 DCHECK(params);
4840 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:264841 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:534842 !GetHelper(pname, params, &num_written)) {
[email protected]7d3c36e2013-07-12 14:13:164843 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584844 glGetIntegerv(pname, params);
4845 }
4846}
4847
[email protected]a0c3e972010-04-21 00:49:134848void GLES2DecoderImpl::DoGetProgramiv(
4849 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:424850 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
4851 if (!program) {
[email protected]a0c3e972010-04-21 00:49:134852 return;
4853 }
[email protected]df37b9932013-03-08 05:21:424854 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:134855}
4856
[email protected]17cfbe0e2013-03-07 01:26:084857void GLES2DecoderImpl::DoGetBufferParameteriv(
4858 GLenum target, GLenum pname, GLint* params) {
[email protected]0fbba3732013-07-17 15:40:134859 // Just delegate it. Some validation is actually done before this.
4860 buffer_manager()->ValidateAndDoGetBufferParameteriv(
4861 &state_, target, pname, params);
[email protected]17cfbe0e2013-03-07 01:26:084862}
4863
[email protected]258a3313f2011-10-18 20:13:574864void GLES2DecoderImpl::DoBindAttribLocation(
[email protected]df37b9932013-03-08 05:21:424865 GLuint program_id, GLuint index, const char* name) {
[email protected]258a3313f2011-10-18 20:13:574866 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514867 LOCAL_SET_GL_ERROR(
4868 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:574869 return;
4870 }
[email protected]68dcb1f2012-04-07 00:14:564871 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514872 LOCAL_SET_GL_ERROR(
4873 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:564874 return;
4875 }
4876 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:514877 LOCAL_SET_GL_ERROR(
4878 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:564879 return;
4880 }
[email protected]df37b9932013-03-08 05:21:424881 Program* program = GetProgramInfoNotShader(
4882 program_id, "glBindAttribLocation");
4883 if (!program) {
[email protected]258a3313f2011-10-18 20:13:574884 return;
[email protected]558847a2010-03-24 07:02:544885 }
[email protected]df37b9932013-03-08 05:21:424886 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
4887 glBindAttribLocation(program->service_id(), index, name);
[email protected]258a3313f2011-10-18 20:13:574888}
4889
[email protected]558847a2010-03-24 07:02:544890error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
vmiuracd108592014-09-08 14:36:344891 uint32 immediate_data_size,
4892 const void* cmd_data) {
4893 const gles2::cmds::BindAttribLocationBucket& c =
4894 *static_cast<const gles2::cmds::BindAttribLocationBucket*>(cmd_data);
[email protected]6b8cf1a2010-05-06 16:13:584895 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544896 GLuint index = static_cast<GLuint>(c.index);
4897 Bucket* bucket = GetBucket(c.name_bucket_id);
4898 if (!bucket || bucket->size() == 0) {
4899 return error::kInvalidArguments;
4900 }
4901 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:184902 if (!bucket->GetAsString(&name_str)) {
4903 return error::kInvalidArguments;
4904 }
[email protected]258a3313f2011-10-18 20:13:574905 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544906 return error::kNoError;
4907}
4908
[email protected]2be6abf32012-06-26 00:28:334909void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:424910 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:334911 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514912 LOCAL_SET_GL_ERROR(
4913 GL_INVALID_VALUE,
4914 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:334915 return;
4916 }
4917 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514918 LOCAL_SET_GL_ERROR(
4919 GL_INVALID_OPERATION,
4920 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:334921 return;
4922 }
4923 if (location < 0 || static_cast<uint32>(location) >=
4924 (group_->max_fragment_uniform_vectors() +
4925 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:514926 LOCAL_SET_GL_ERROR(
4927 GL_INVALID_VALUE,
4928 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334929 return;
4930 }
[email protected]df37b9932013-03-08 05:21:424931 Program* program = GetProgramInfoNotShader(
4932 program_id, "glBindUniformLocationCHROMIUM");
4933 if (!program) {
[email protected]2be6abf32012-06-26 00:28:334934 return;
4935 }
[email protected]df37b9932013-03-08 05:21:424936 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:514937 LOCAL_SET_GL_ERROR(
4938 GL_INVALID_VALUE,
4939 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334940 }
4941}
4942
[email protected]2be6abf32012-06-26 00:28:334943error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
4944 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:344945 const void* cmd_data) {
4946 const gles2::cmds::BindUniformLocationCHROMIUMBucket& c =
4947 *static_cast<const gles2::cmds::BindUniformLocationCHROMIUMBucket*>(
4948 cmd_data);
[email protected]2be6abf32012-06-26 00:28:334949 GLuint program = static_cast<GLuint>(c.program);
4950 GLint location = static_cast<GLint>(c.location);
4951 Bucket* bucket = GetBucket(c.name_bucket_id);
4952 if (!bucket || bucket->size() == 0) {
4953 return error::kInvalidArguments;
4954 }
4955 std::string name_str;
4956 if (!bucket->GetAsString(&name_str)) {
4957 return error::kInvalidArguments;
4958 }
4959 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4960 return error::kNoError;
4961}
4962
vmiuracd108592014-09-08 14:36:344963error::Error GLES2DecoderImpl::HandleDeleteShader(uint32 immediate_data_size,
4964 const void* cmd_data) {
4965 const gles2::cmds::DeleteShader& c =
4966 *static_cast<const gles2::cmds::DeleteShader*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:034967 GLuint client_id = c.shader;
4968 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424969 Shader* shader = GetShader(client_id);
4970 if (shader) {
4971 if (!shader->IsDeleted()) {
4972 glDeleteShader(shader->service_id());
4973 shader_manager()->MarkAsDeleted(shader);
[email protected]ca488e12010-12-13 20:06:144974 }
[email protected]ae51d192010-04-27 00:48:034975 } else {
[email protected]ab09b612013-03-11 22:11:514976 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:034977 }
[email protected]96449d2c2009-11-25 00:01:324978 }
[email protected]f7a64ee2010-02-01 22:24:144979 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324980}
4981
vmiuracd108592014-09-08 14:36:344982error::Error GLES2DecoderImpl::HandleDeleteProgram(uint32 immediate_data_size,
4983 const void* cmd_data) {
4984 const gles2::cmds::DeleteProgram& c =
4985 *static_cast<const gles2::cmds::DeleteProgram*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:034986 GLuint client_id = c.program;
4987 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424988 Program* program = GetProgram(client_id);
4989 if (program) {
4990 if (!program->IsDeleted()) {
4991 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:144992 }
[email protected]ae51d192010-04-27 00:48:034993 } else {
[email protected]ab09b612013-03-11 22:11:514994 LOCAL_SET_GL_ERROR(
4995 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:034996 }
[email protected]96449d2c2009-11-25 00:01:324997 }
[email protected]f7a64ee2010-02-01 22:24:144998 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324999}
5000
[email protected]269200b12010-11-18 22:53:065001void GLES2DecoderImpl::DoDeleteSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:105002 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:575003 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:105004 for (GLsizei ii = 0; ii < n; ++ii) {
5005 id_allocator->FreeID(ids[ii]);
5006 }
5007}
5008
[email protected]269200b12010-11-18 22:53:065009error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM(
vmiuracd108592014-09-08 14:36:345010 uint32 immediate_data_size,
5011 const void* cmd_data) {
5012 const gles2::cmds::DeleteSharedIdsCHROMIUM& c =
5013 *static_cast<const gles2::cmds::DeleteSharedIdsCHROMIUM*>(cmd_data);
[email protected]066849e32010-05-03 19:14:105014 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
5015 GLsizei n = static_cast<GLsizei>(c.n);
5016 uint32 data_size;
5017 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
5018 return error::kOutOfBounds;
5019 }
5020 const GLuint* ids = GetSharedMemoryAs<const GLuint*>(
5021 c.ids_shm_id, c.ids_shm_offset, data_size);
5022 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:515023 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "DeleteSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:105024 return error::kNoError;
5025 }
5026 if (ids == NULL) {
5027 return error::kOutOfBounds;
5028 }
[email protected]269200b12010-11-18 22:53:065029 DoDeleteSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:105030 return error::kNoError;
5031}
5032
[email protected]269200b12010-11-18 22:53:065033void GLES2DecoderImpl::DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:105034 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:575035 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:105036 if (id_offset == 0) {
5037 for (GLsizei ii = 0; ii < n; ++ii) {
5038 ids[ii] = id_allocator->AllocateID();
5039 }
5040 } else {
5041 for (GLsizei ii = 0; ii < n; ++ii) {
5042 ids[ii] = id_allocator->AllocateIDAtOrAbove(id_offset);
5043 id_offset = ids[ii] + 1;
5044 }
5045 }
5046}
5047
[email protected]269200b12010-11-18 22:53:065048error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM(
vmiuracd108592014-09-08 14:36:345049 uint32 immediate_data_size,
5050 const void* cmd_data) {
5051 const gles2::cmds::GenSharedIdsCHROMIUM& c =
5052 *static_cast<const gles2::cmds::GenSharedIdsCHROMIUM*>(cmd_data);
[email protected]066849e32010-05-03 19:14:105053 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
5054 GLuint id_offset = static_cast<GLuint>(c.id_offset);
5055 GLsizei n = static_cast<GLsizei>(c.n);
5056 uint32 data_size;
5057 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
5058 return error::kOutOfBounds;
5059 }
5060 GLuint* ids = GetSharedMemoryAs<GLuint*>(
5061 c.ids_shm_id, c.ids_shm_offset, data_size);
5062 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:515063 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "GenSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:105064 return error::kNoError;
5065 }
5066 if (ids == NULL) {
5067 return error::kOutOfBounds;
5068 }
[email protected]269200b12010-11-18 22:53:065069 DoGenSharedIdsCHROMIUM(namespace_id, id_offset, n, ids);
[email protected]066849e32010-05-03 19:14:105070 return error::kNoError;
5071}
5072
[email protected]269200b12010-11-18 22:53:065073void GLES2DecoderImpl::DoRegisterSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:105074 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:575075 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:105076 for (GLsizei ii = 0; ii < n; ++ii) {
5077 if (!id_allocator->MarkAsUsed(ids[ii])) {
5078 for (GLsizei jj = 0; jj < ii; ++jj) {
5079 id_allocator->FreeID(ids[jj]);
5080 }
[email protected]ab09b612013-03-11 22:11:515081 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435082 GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM",
5083 "attempt to register id that already exists");
[email protected]066849e32010-05-03 19:14:105084 return;
5085 }
5086 }
5087}
5088
[email protected]269200b12010-11-18 22:53:065089error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM(
vmiuracd108592014-09-08 14:36:345090 uint32 immediate_data_size,
5091 const void* cmd_data) {
5092 const gles2::cmds::RegisterSharedIdsCHROMIUM& c =
5093 *static_cast<const gles2::cmds::RegisterSharedIdsCHROMIUM*>(cmd_data);
[email protected]066849e32010-05-03 19:14:105094 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
5095 GLsizei n = static_cast<GLsizei>(c.n);
5096 uint32 data_size;
5097 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
5098 return error::kOutOfBounds;
5099 }
5100 GLuint* ids = GetSharedMemoryAs<GLuint*>(
5101 c.ids_shm_id, c.ids_shm_offset, data_size);
5102 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:515103 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:105104 return error::kNoError;
5105 }
5106 if (ids == NULL) {
5107 return error::kOutOfBounds;
5108 }
[email protected]269200b12010-11-18 22:53:065109 DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:105110 return error::kNoError;
5111}
5112
[email protected]a7266a92012-06-28 02:11:085113error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:445114 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:205115 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]297ca1c2011-06-20 23:08:465116 ApplyDirtyState();
[email protected]3a03a8f2011-03-19 00:51:275117 glClear(mask);
5118 }
[email protected]a7266a92012-06-28 02:11:085119 return error::kNoError;
5120}
5121
[email protected]36cef8ce2010-03-16 07:34:455122void GLES2DecoderImpl::DoFramebufferRenderbuffer(
5123 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:035124 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:065125 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5126 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515127 LOCAL_SET_GL_ERROR(
5128 GL_INVALID_OPERATION,
5129 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455130 return;
5131 }
[email protected]ae51d192010-04-27 00:48:035132 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:275133 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:035134 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:275135 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
5136 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515137 LOCAL_SET_GL_ERROR(
5138 GL_INVALID_OPERATION,
5139 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:035140 return;
5141 }
[email protected]ee2a79c32013-03-10 03:50:275142 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:035143 }
[email protected]ab09b612013-03-11 22:11:515144 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:035145 glFramebufferRenderbufferEXT(
5146 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:515147 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:265148 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:275149 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:285150 }
[email protected]9d3b2e12013-10-02 01:04:345151 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445152 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465153 }
[email protected]81fc9d02013-03-14 23:53:325154 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:285155}
5156
[email protected]3a2e7c7b2010-08-06 01:12:285157void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465158 if (SetCapabilityState(cap, false)) {
5159 glDisable(cap);
5160 }
[email protected]3a2e7c7b2010-08-06 01:12:285161}
5162
5163void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465164 if (SetCapabilityState(cap, true)) {
5165 glEnable(cap);
5166 }
[email protected]3a2e7c7b2010-08-06 01:12:285167}
5168
[email protected]88a61bf2012-10-27 13:00:425169void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
5170 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
5171 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
5172 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:285173}
5174
[email protected]b04e24c2013-01-08 18:35:255175void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:425176 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
5177 state_.sample_coverage_invert = (invert != 0);
5178 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:285179}
5180
[email protected]0d6bfdc2011-11-02 01:32:205181// Assumes framebuffer is complete.
5182void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:065183 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:305184 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:205185 // bind this to the DRAW point, clear then bind back to READ
5186 // TODO(gman): I don't think there is any guarantee that an FBO that
5187 // is complete on the READ attachment will be complete as a DRAW
5188 // attachment.
5189 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:065190 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:305191 }
[email protected]3a2e7c7b2010-08-06 01:12:285192 GLbitfield clear_bits = 0;
[email protected]ee757922014-06-06 05:21:425193 if (framebuffer->HasUnclearedColorAttachments()) {
[email protected]297ca1c2011-06-20 23:08:465194 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:205195 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:465196 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:065197 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
5198 1.0f);
[email protected]454157e2014-05-03 02:49:455199 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285200 clear_bits |= GL_COLOR_BUFFER_BIT;
[email protected]0e58af82014-08-08 14:02:535201 if (feature_info_->feature_flags().ext_draw_buffers)
5202 framebuffer->PrepareDrawBuffersForClear();
[email protected]3a2e7c7b2010-08-06 01:12:285203 }
5204
[email protected]4d8f0dd2013-03-09 14:37:065205 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
5206 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285207 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:475208 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
5209 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]3a2e7c7b2010-08-06 01:12:285210 clear_bits |= GL_STENCIL_BUFFER_BIT;
5211 }
5212
[email protected]4d8f0dd2013-03-09 14:37:065213 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
5214 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285215 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:455216 state_.SetDeviceDepthMask(GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285217 clear_bits |= GL_DEPTH_BUFFER_BIT;
5218 }
5219
[email protected]454157e2014-05-03 02:49:455220 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]3a2e7c7b2010-08-06 01:12:285221 glClear(clear_bits);
5222
[email protected]0e58af82014-08-08 14:02:535223 if ((clear_bits | GL_COLOR_BUFFER_BIT) != 0 &&
5224 feature_info_->feature_flags().ext_draw_buffers)
[email protected]ee757922014-06-06 05:21:425225 framebuffer->RestoreDrawBuffersAfterClear();
5226
[email protected]968351b2011-12-20 08:26:515227 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:065228 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:285229
[email protected]c007aa02010-09-02 22:22:405230 RestoreClearState();
5231
5232 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:065233 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
5234 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:485235 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:065236 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
5237 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:485238 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:405239 }
5240}
5241
5242void GLES2DecoderImpl::RestoreClearState() {
[email protected]c986af502013-08-14 01:04:445243 framebuffer_state_.clear_state_dirty = true;
[email protected]e259eb412012-10-13 05:47:245244 glClearColor(
5245 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
5246 state_.color_clear_alpha);
5247 glClearStencil(state_.stencil_clear);
5248 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:225249 if (state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:455250 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]3a2e7c7b2010-08-06 01:12:285251 }
[email protected]36cef8ce2010-03-16 07:34:455252}
5253
5254GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:355255 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:305256 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:205257 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:455258 return GL_FRAMEBUFFER_COMPLETE;
5259 }
[email protected]0d6bfdc2011-11-02 01:32:205260 GLenum completeness = framebuffer->IsPossiblyComplete();
5261 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
5262 return completeness;
5263 }
[email protected]73276522012-11-09 05:50:205264 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:455265}
5266
5267void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:035268 GLenum target, GLenum attachment, GLenum textarget,
5269 GLuint client_texture_id, GLint level) {
[email protected]7d3c36e2013-07-12 14:13:165270 DoFramebufferTexture2DCommon(
5271 "glFramebufferTexture2D", target, attachment,
5272 textarget, client_texture_id, level, 0);
5273}
5274
5275void GLES2DecoderImpl::DoFramebufferTexture2DMultisample(
5276 GLenum target, GLenum attachment, GLenum textarget,
5277 GLuint client_texture_id, GLint level, GLsizei samples) {
[email protected]7d3c36e2013-07-12 14:13:165278 DoFramebufferTexture2DCommon(
5279 "glFramebufferTexture2DMultisample", target, attachment,
5280 textarget, client_texture_id, level, samples);
5281}
5282
5283void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
5284 const char* name, GLenum target, GLenum attachment, GLenum textarget,
5285 GLuint client_texture_id, GLint level, GLsizei samples) {
5286 if (samples > renderbuffer_manager()->max_samples()) {
5287 LOCAL_SET_GL_ERROR(
5288 GL_INVALID_VALUE,
5289 "glFramebufferTexture2DMultisample", "samples too large");
5290 return;
5291 }
[email protected]4d8f0dd2013-03-09 14:37:065292 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5293 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515294 LOCAL_SET_GL_ERROR(
5295 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165296 name, "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:455297 return;
5298 }
[email protected]ae51d192010-04-27 00:48:035299 GLuint service_id = 0;
[email protected]370eaf12013-05-18 09:19:495300 TextureRef* texture_ref = NULL;
[email protected]ae51d192010-04-27 00:48:035301 if (client_texture_id) {
[email protected]370eaf12013-05-18 09:19:495302 texture_ref = GetTexture(client_texture_id);
5303 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:515304 LOCAL_SET_GL_ERROR(
5305 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165306 name, "unknown texture_ref");
[email protected]ae51d192010-04-27 00:48:035307 return;
5308 }
[email protected]370eaf12013-05-18 09:19:495309 service_id = texture_ref->service_id();
[email protected]ae51d192010-04-27 00:48:035310 }
[email protected]0d6bfdc2011-11-02 01:32:205311
[email protected]80eb6b52012-01-19 00:14:415312 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:515313 LOCAL_SET_GL_ERROR(
5314 GL_INVALID_VALUE,
[email protected]7d3c36e2013-07-12 14:13:165315 name, "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:205316 return;
5317 }
5318
[email protected]91c94eb2013-10-22 10:32:545319 if (texture_ref)
5320 DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget);
5321
[email protected]7d3c36e2013-07-12 14:13:165322 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
5323 if (0 == samples) {
5324 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
5325 } else {
5326 if (features().use_img_for_multisampled_render_to_texture) {
5327 glFramebufferTexture2DMultisampleIMG(target, attachment, textarget,
5328 service_id, level, samples);
5329 } else {
5330 glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
5331 service_id, level, samples);
5332 }
5333 }
5334 GLenum error = LOCAL_PEEK_GL_ERROR(name);
[email protected]9edc6b22010-12-23 02:00:265335 if (error == GL_NO_ERROR) {
[email protected]7d3c36e2013-07-12 14:13:165336 framebuffer->AttachTexture(attachment, texture_ref, textarget, level,
5337 samples);
[email protected]3a2e7c7b2010-08-06 01:12:285338 }
[email protected]9d3b2e12013-10-02 01:04:345339 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445340 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465341 }
[email protected]91c94eb2013-10-22 10:32:545342
5343 if (texture_ref)
5344 DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget);
5345
[email protected]81fc9d02013-03-14 23:53:325346 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:455347}
5348
5349void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
5350 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:065351 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5352 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515353 LOCAL_SET_GL_ERROR(
5354 GL_INVALID_OPERATION,
[email protected]caa13ed2014-02-17 11:29:205355 "glGetFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455356 return;
5357 }
[email protected]74c1ec42010-08-12 01:55:575358 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
[email protected]62e65f02013-05-29 22:28:105359 const Framebuffer::Attachment* attachment_object =
5360 framebuffer->GetAttachment(attachment);
5361 *params = attachment_object ? attachment_object->object_name() : 0;
5362 } else {
[email protected]7d3c36e2013-07-12 14:13:165363 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT &&
5364 features().use_img_for_multisampled_render_to_texture) {
5365 pname = GL_TEXTURE_SAMPLES_IMG;
5366 }
[email protected]62e65f02013-05-29 22:28:105367 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:575368 }
[email protected]36cef8ce2010-03-16 07:34:455369}
5370
5371void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
5372 GLenum target, GLenum pname, GLint* params) {
[email protected]ed9f9cd2013-02-27 21:12:355373 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205374 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5375 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515376 LOCAL_SET_GL_ERROR(
5377 GL_INVALID_OPERATION,
5378 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455379 return;
5380 }
[email protected]8875a5f2014-06-27 08:33:475381
5382 EnsureRenderbufferBound();
[email protected]3a03a8f2011-03-19 00:51:275383 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:435384 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5385 *params = renderbuffer->internal_format();
5386 break;
5387 case GL_RENDERBUFFER_WIDTH:
5388 *params = renderbuffer->width();
5389 break;
5390 case GL_RENDERBUFFER_HEIGHT:
5391 *params = renderbuffer->height();
5392 break;
[email protected]7d3c36e2013-07-12 14:13:165393 case GL_RENDERBUFFER_SAMPLES_EXT:
5394 if (features().use_img_for_multisampled_render_to_texture) {
5395 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG,
5396 params);
5397 } else {
5398 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT,
5399 params);
5400 }
[email protected]ad84a3a2012-06-08 21:42:435401 default:
5402 glGetRenderbufferParameterivEXT(target, pname, params);
5403 break;
[email protected]b71f52c2010-06-18 22:20:205404 }
[email protected]36cef8ce2010-03-16 07:34:455405}
5406
[email protected]49cabed2013-11-13 18:15:185407void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:305408 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
5409 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5410 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:445411 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]0c16343f2013-03-08 20:40:165412
[email protected]49cabed2013-11-13 18:15:185413 if (!CheckBoundFramebuffersValid("glBlitFramebufferCHROMIUM")) {
[email protected]0c16343f2013-03-08 20:40:165414 return;
5415 }
5416
[email protected]454157e2014-05-03 02:49:455417 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f42f05b2013-11-15 21:46:185418 BlitFramebufferHelper(
5419 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]454157e2014-05-03 02:49:455420 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST,
5421 state_.enable_flags.scissor_test);
[email protected]f42f05b2013-11-15 21:46:185422}
5423
[email protected]8875a5f2014-06-27 08:33:475424void GLES2DecoderImpl::EnsureRenderbufferBound() {
5425 if (!state_.bound_renderbuffer_valid) {
5426 state_.bound_renderbuffer_valid = true;
5427 glBindRenderbufferEXT(GL_RENDERBUFFER,
5428 state_.bound_renderbuffer.get()
5429 ? state_.bound_renderbuffer->service_id()
5430 : 0);
5431 }
5432}
5433
[email protected]f42f05b2013-11-15 21:46:185434void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(
5435 const FeatureInfo* feature_info,
5436 GLenum target,
5437 GLsizei samples,
5438 GLenum internal_format,
5439 GLsizei width,
5440 GLsizei height) {
5441 // TODO(sievers): This could be resolved at the GL binding level, but the
5442 // binding process is currently a bit too 'brute force'.
5443 if (feature_info->feature_flags().is_angle) {
5444 glRenderbufferStorageMultisampleANGLE(
5445 target, samples, internal_format, width, height);
5446 } else if (feature_info->feature_flags().use_core_framebuffer_multisample) {
5447 glRenderbufferStorageMultisample(
5448 target, samples, internal_format, width, height);
5449 } else {
5450 glRenderbufferStorageMultisampleEXT(
5451 target, samples, internal_format, width, height);
5452 }
5453}
5454
5455void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0,
5456 GLint srcY0,
5457 GLint srcX1,
5458 GLint srcY1,
5459 GLint dstX0,
5460 GLint dstY0,
5461 GLint dstX1,
5462 GLint dstY1,
5463 GLbitfield mask,
5464 GLenum filter) {
5465 // TODO(sievers): This could be resolved at the GL binding level, but the
5466 // binding process is currently a bit too 'brute force'.
5467 if (feature_info_->feature_flags().is_angle) {
[email protected]5094b0f2010-11-09 19:45:245468 glBlitFramebufferANGLE(
5469 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]f42f05b2013-11-15 21:46:185470 } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) {
5471 glBlitFramebuffer(
5472 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]5094b0f2010-11-09 19:45:245473 } else {
5474 glBlitFramebufferEXT(
5475 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5476 }
[email protected]8e3e0662010-08-23 18:46:305477}
5478
[email protected]49cabed2013-11-13 18:15:185479bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample(
5480 GLsizei samples,
5481 GLenum internalformat,
5482 GLsizei width,
5483 GLsizei height) {
[email protected]84afefa2011-10-19 21:45:535484 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:515485 LOCAL_SET_GL_ERROR(
5486 GL_INVALID_VALUE,
5487 "glRenderbufferStorageMultisample", "samples too large");
[email protected]49cabed2013-11-13 18:15:185488 return false;
[email protected]84afefa2011-10-19 21:45:535489 }
5490
5491 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5492 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515493 LOCAL_SET_GL_ERROR(
5494 GL_INVALID_VALUE,
5495 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185496 return false;
[email protected]84afefa2011-10-19 21:45:535497 }
5498
[email protected]7989c9e2013-01-23 06:39:265499 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235500 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5501 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515502 LOCAL_SET_GL_ERROR(
5503 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205504 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185505 return false;
[email protected]8e3e0662010-08-23 18:46:305506 }
5507
[email protected]7989c9e2013-01-23 06:39:265508 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515509 LOCAL_SET_GL_ERROR(
5510 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205511 "glRenderbufferStorageMultisample", "out of memory");
[email protected]49cabed2013-11-13 18:15:185512 return false;
5513 }
5514
5515 return true;
5516}
5517
5518void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM(
5519 GLenum target, GLsizei samples, GLenum internalformat,
5520 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185521 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5522 if (!renderbuffer) {
5523 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5524 "glRenderbufferStorageMultisampleCHROMIUM",
5525 "no renderbuffer bound");
5526 return;
5527 }
5528
5529 if (!ValidateRenderbufferStorageMultisample(
5530 samples, internalformat, width, height)) {
[email protected]7989c9e2013-01-23 06:39:265531 return;
5532 }
5533
[email protected]8875a5f2014-06-27 08:33:475534 EnsureRenderbufferBound();
[email protected]8e102e102013-09-20 22:50:235535 GLenum impl_format =
5536 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5537 internalformat);
[email protected]49cabed2013-11-13 18:15:185538 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(
5539 "glRenderbufferStorageMultisampleCHROMIUM");
[email protected]f42f05b2013-11-15 21:46:185540 RenderbufferStorageMultisampleHelper(
Daniel Cheng3d7ce9f2014-08-26 00:26:255541 feature_info_.get(), target, samples, impl_format, width, height);
[email protected]49cabed2013-11-13 18:15:185542 GLenum error =
5543 LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM");
[email protected]9edc6b22010-12-23 02:00:265544 if (error == GL_NO_ERROR) {
[email protected]4a4c18b2013-09-13 22:50:105545
5546 if (workarounds().validate_multisample_buffer_allocation) {
5547 if (!VerifyMultisampleRenderbufferIntegrity(
5548 renderbuffer->service_id(), impl_format)) {
5549 LOCAL_SET_GL_ERROR(
5550 GL_OUT_OF_MEMORY,
[email protected]49cabed2013-11-13 18:15:185551 "glRenderbufferStorageMultisampleCHROMIUM", "out of memory");
[email protected]4a4c18b2013-09-13 22:50:105552 return;
5553 }
5554 }
5555
[email protected]968351b2011-12-20 08:26:515556 // TODO(gman): If renderbuffers tracked which framebuffers they were
5557 // attached to we could just mark those framebuffers as not complete.
5558 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205559 renderbuffer_manager()->SetInfo(
5560 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265561 }
[email protected]8e3e0662010-08-23 18:46:305562}
5563
[email protected]49cabed2013-11-13 18:15:185564// This is the handler for multisampled_render_to_texture extensions.
5565void GLES2DecoderImpl::DoRenderbufferStorageMultisampleEXT(
5566 GLenum target, GLsizei samples, GLenum internalformat,
5567 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185568 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5569 if (!renderbuffer) {
5570 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5571 "glRenderbufferStorageMultisampleEXT",
5572 "no renderbuffer bound");
5573 return;
5574 }
5575
5576 if (!ValidateRenderbufferStorageMultisample(
5577 samples, internalformat, width, height)) {
5578 return;
5579 }
5580
[email protected]8875a5f2014-06-27 08:33:475581 EnsureRenderbufferBound();
[email protected]49cabed2013-11-13 18:15:185582 GLenum impl_format =
5583 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5584 internalformat);
5585 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT");
5586 if (features().use_img_for_multisampled_render_to_texture) {
5587 glRenderbufferStorageMultisampleIMG(
5588 target, samples, impl_format, width, height);
5589 } else {
5590 glRenderbufferStorageMultisampleEXT(
5591 target, samples, impl_format, width, height);
5592 }
5593 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT");
5594 if (error == GL_NO_ERROR) {
5595 // TODO(gman): If renderbuffers tracked which framebuffers they were
5596 // attached to we could just mark those framebuffers as not complete.
5597 framebuffer_manager()->IncFramebufferStateChangeCount();
5598 renderbuffer_manager()->SetInfo(
5599 renderbuffer, samples, internalformat, width, height);
5600 }
5601}
5602
[email protected]4a4c18b2013-09-13 22:50:105603// This function validates the allocation of a multisampled renderbuffer
5604// by clearing it to a key color, blitting the contents to a texture, and
5605// reading back the color to ensure it matches the key.
5606bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity(
5607 GLuint renderbuffer, GLenum format) {
5608
5609 // Only validate color buffers.
5610 // These formats have been selected because they are very common or are known
5611 // to be used by the WebGL backbuffer. If problems are observed with other
5612 // color formats they can be added here.
5613 switch(format) {
5614 case GL_RGB:
5615 case GL_RGB8:
5616 case GL_RGBA:
5617 case GL_RGBA8:
5618 break;
5619 default:
5620 return true;
5621 }
5622
5623 GLint draw_framebuffer, read_framebuffer;
5624
5625 // Cache framebuffer and texture bindings.
5626 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer);
5627 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer);
5628
5629 if (!validation_texture_) {
5630 GLint bound_texture;
5631 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
5632
5633 // Create additional resources needed for the verification.
5634 glGenTextures(1, &validation_texture_);
5635 glGenFramebuffersEXT(1, &validation_fbo_multisample_);
5636 glGenFramebuffersEXT(1, &validation_fbo_);
5637
5638 // Texture only needs to be 1x1.
5639 glBindTexture(GL_TEXTURE_2D, validation_texture_);
5640 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB,
5641 GL_UNSIGNED_BYTE, NULL);
5642
5643 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5644 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5645 GL_TEXTURE_2D, validation_texture_, 0);
5646
5647 glBindTexture(GL_TEXTURE_2D, bound_texture);
5648 }
5649
5650 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5651 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5652 GL_RENDERBUFFER, renderbuffer);
5653
5654 // Cache current state and reset it to the values we require.
5655 GLboolean scissor_enabled = false;
5656 glGetBooleanv(GL_SCISSOR_TEST, &scissor_enabled);
5657 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455658 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]4a4c18b2013-09-13 22:50:105659
[email protected]454157e2014-05-03 02:49:455660 GLboolean color_mask[4] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
[email protected]4a4c18b2013-09-13 22:50:105661 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask);
[email protected]454157e2014-05-03 02:49:455662 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]4a4c18b2013-09-13 22:50:105663
5664 GLfloat clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5665 glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color);
5666 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
5667
5668 // Clear the buffer to the desired key color.
5669 glClear(GL_COLOR_BUFFER_BIT);
5670
5671 // Blit from the multisample buffer to a standard texture.
5672 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, validation_fbo_multisample_);
5673 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, validation_fbo_);
5674
[email protected]f42f05b2013-11-15 21:46:185675 BlitFramebufferHelper(
5676 0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
[email protected]4a4c18b2013-09-13 22:50:105677
5678 // Read a pixel from the buffer.
5679 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5680
5681 unsigned char pixel[3] = {0, 0, 0};
5682 glReadPixels(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);
5683
5684 // Detach the renderbuffer.
5685 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5686 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5687 GL_RENDERBUFFER, 0);
5688
5689 // Restore cached state.
5690 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455691 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]4a4c18b2013-09-13 22:50:105692
[email protected]454157e2014-05-03 02:49:455693 state_.SetDeviceColorMask(
5694 color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
[email protected]4a4c18b2013-09-13 22:50:105695 glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
5696 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, draw_framebuffer);
5697 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, read_framebuffer);
5698
5699 // Return true if the pixel matched the desired key color.
5700 return (pixel[0] == 0xFF &&
5701 pixel[1] == 0x00 &&
5702 pixel[2] == 0xFF);
5703}
5704
[email protected]36cef8ce2010-03-16 07:34:455705void GLES2DecoderImpl::DoRenderbufferStorage(
5706 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:355707 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205708 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5709 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515710 LOCAL_SET_GL_ERROR(
5711 GL_INVALID_OPERATION,
5712 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455713 return;
5714 }
[email protected]876f6fee2010-08-02 23:10:325715
[email protected]84afefa2011-10-19 21:45:535716 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5717 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515718 LOCAL_SET_GL_ERROR(
5719 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535720 return;
5721 }
5722
[email protected]7989c9e2013-01-23 06:39:265723 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235724 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5725 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515726 LOCAL_SET_GL_ERROR(
5727 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265728 return;
5729 }
5730
5731 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515732 LOCAL_SET_GL_ERROR(
5733 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265734 return;
[email protected]b71f52c2010-06-18 22:20:205735 }
[email protected]876f6fee2010-08-02 23:10:325736
[email protected]8875a5f2014-06-27 08:33:475737 EnsureRenderbufferBound();
[email protected]ab09b612013-03-11 22:11:515738 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:265739 glRenderbufferStorageEXT(
[email protected]8e102e102013-09-20 22:50:235740 target,
5741 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5742 internalformat),
5743 width,
5744 height);
[email protected]ab09b612013-03-11 22:11:515745 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:265746 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515747 // TODO(gman): If tetxures tracked which framebuffers they were attached to
5748 // we could just mark those framebuffers as not complete.
5749 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205750 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:265751 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265752 }
[email protected]36cef8ce2010-03-16 07:34:455753}
5754
[email protected]df37b9932013-03-08 05:21:425755void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:385756 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:425757 Program* program = GetProgramInfoNotShader(
5758 program_id, "glLinkProgram");
5759 if (!program) {
[email protected]a93bb842010-02-16 23:03:475760 return;
5761 }
[email protected]05afda12011-01-20 00:17:345762
[email protected]df37b9932013-03-08 05:21:425763 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]65dfc602012-07-23 20:39:395764 ShaderTranslator* vertex_translator = NULL;
5765 ShaderTranslator* fragment_translator = NULL;
5766 if (use_shader_translator_) {
[email protected]7cd76fd2013-06-02 21:11:115767 vertex_translator = vertex_translator_.get();
5768 fragment_translator = fragment_translator_.get();
[email protected]65dfc602012-07-23 20:39:395769 }
[email protected]df37b9932013-03-08 05:21:425770 if (program->Link(shader_manager(),
[email protected]7cd76fd2013-06-02 21:11:115771 vertex_translator,
5772 fragment_translator,
[email protected]008401532014-02-07 00:10:505773 workarounds().count_all_in_varyings_packing ?
5774 Program::kCountAll : Program::kCountOnlyStaticallyUsed,
[email protected]7cd76fd2013-06-02 21:11:115775 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:425776 if (program == state_.current_program.get()) {
[email protected]b05955552014-02-06 18:41:185777 if (workarounds().use_current_program_after_successful_link)
[email protected]df37b9932013-03-08 05:21:425778 glUseProgram(program->service_id());
[email protected]b05955552014-02-06 18:41:185779 if (workarounds().clear_uniforms_before_first_program_use)
5780 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:545781 }
5782 }
vmiura8266ca72014-09-09 21:37:005783
5784 // LinkProgram can be very slow. Exit command processing to allow for
5785 // context preemption and GPU watchdog checks.
5786 ExitCommandProcessingEarly();
[email protected]07f54fcc2009-12-22 02:46:305787};
5788
[email protected]3916c97e2010-02-25 03:20:505789void GLES2DecoderImpl::DoTexParameterf(
5790 GLenum target, GLenum pname, GLfloat param) {
[email protected]c986af502013-08-14 01:04:445791 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5792 &state_, target);
[email protected]02965c22013-03-09 02:40:075793 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515794 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245795 return;
[email protected]07f54fcc2009-12-22 02:46:305796 }
[email protected]cbb22e42011-05-12 23:36:245797
[email protected]737191ee72014-03-09 08:02:425798 texture_manager()->SetParameterf(
5799 "glTexParameterf", GetErrorState(), texture, pname, param);
[email protected]07f54fcc2009-12-22 02:46:305800}
5801
[email protected]3916c97e2010-02-25 03:20:505802void GLES2DecoderImpl::DoTexParameteri(
5803 GLenum target, GLenum pname, GLint param) {
[email protected]c986af502013-08-14 01:04:445804 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5805 &state_, target);
[email protected]02965c22013-03-09 02:40:075806 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515807 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245808 return;
[email protected]3916c97e2010-02-25 03:20:505809 }
[email protected]cbb22e42011-05-12 23:36:245810
[email protected]737191ee72014-03-09 08:02:425811 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505812 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:505813}
5814
5815void GLES2DecoderImpl::DoTexParameterfv(
5816 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]c986af502013-08-14 01:04:445817 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5818 &state_, target);
[email protected]02965c22013-03-09 02:40:075819 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515820 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245821 return;
[email protected]3916c97e2010-02-25 03:20:505822 }
[email protected]cbb22e42011-05-12 23:36:245823
[email protected]737191ee72014-03-09 08:02:425824 texture_manager()->SetParameterf(
5825 "glTexParameterfv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505826}
5827
5828void GLES2DecoderImpl::DoTexParameteriv(
5829 GLenum target, GLenum pname, const GLint* params) {
[email protected]c986af502013-08-14 01:04:445830 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5831 &state_, target);
[email protected]02965c22013-03-09 02:40:075832 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515833 LOCAL_SET_GL_ERROR(
5834 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245835 return;
[email protected]3916c97e2010-02-25 03:20:505836 }
[email protected]cbb22e42011-05-12 23:36:245837
[email protected]737191ee72014-03-09 08:02:425838 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505839 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505840}
5841
[email protected]939e7362010-05-13 20:49:105842bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]7cd76fd2013-06-02 21:11:115843 if (!state_.current_program.get()) {
[email protected]ad84a3a2012-06-08 21:42:435844 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:515845 LOCAL_SET_GL_ERROR(
5846 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:435847 return false;
[email protected]939e7362010-05-13 20:49:105848 }
[email protected]e259eb412012-10-13 05:47:245849 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:515850 LOCAL_SET_GL_ERROR(
5851 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:105852 return false;
5853 }
5854 return true;
5855}
5856
5857bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
5858 GLint location, const char* function_name) {
5859 if (!CheckCurrentProgram(function_name)) {
5860 return false;
5861 }
5862 return location != -1;
5863}
5864
[email protected]43c2f1f2011-03-25 18:35:365865bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]9b1f1b52014-03-12 10:40:135866 GLint fake_location,
5867 const char* function_name,
5868 Program::UniformApiType api_type,
5869 GLint* real_location,
5870 GLenum* type,
5871 GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:365872 DCHECK(type);
5873 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:125874 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:525875
[email protected]1b0a6752012-02-22 03:44:125876 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:105877 return false;
5878 }
[email protected]43c2f1f2011-03-25 18:35:365879 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:355880 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:245881 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:125882 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:365883 if (!info) {
[email protected]ab09b612013-03-11 22:11:515884 LOCAL_SET_GL_ERROR(
5885 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:105886 return false;
5887 }
[email protected]9b1f1b52014-03-12 10:40:135888
5889 if ((api_type & info->accepts_api_type) == 0) {
[email protected]ab09b612013-03-11 22:11:515890 LOCAL_SET_GL_ERROR(
5891 GL_INVALID_OPERATION, function_name,
5892 "wrong uniform function for type");
[email protected]476ccb72012-12-06 15:52:525893 return false;
5894 }
[email protected]43c2f1f2011-03-25 18:35:365895 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:515896 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435897 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:365898 return false;
5899 }
5900 *count = std::min(info->size - array_index, *count);
5901 if (*count <= 0) {
5902 return false;
5903 }
5904 *type = info->type;
[email protected]939e7362010-05-13 20:49:105905 return true;
5906}
5907
[email protected]1b0a6752012-02-22 03:44:125908void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
5909 GLenum type = 0;
5910 GLsizei count = 1;
5911 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135912 if (!PrepForSetUniformByLocation(fake_location,
5913 "glUniform1i",
5914 Program::kUniform1i,
5915 &real_location,
5916 &type,
5917 &count)) {
[email protected]3916c97e2010-02-25 03:20:505918 return;
5919 }
[email protected]e259eb412012-10-13 05:47:245920 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025921 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:515922 LOCAL_SET_GL_ERROR(
5923 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465924 return;
5925 }
[email protected]1b0a6752012-02-22 03:44:125926 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:505927}
5928
5929void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:125930 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:365931 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125932 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135933 if (!PrepForSetUniformByLocation(fake_location,
5934 "glUniform1iv",
5935 Program::kUniform1i,
5936 &real_location,
5937 &type,
5938 &count)) {
[email protected]43c2f1f2011-03-25 18:35:365939 return;
5940 }
[email protected]74727112012-06-13 21:18:085941 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
5942 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:245943 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025944 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:515945 LOCAL_SET_GL_ERROR(
5946 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465947 return;
5948 }
[email protected]43c2f1f2011-03-25 18:35:365949 }
[email protected]1b0a6752012-02-22 03:44:125950 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:505951}
5952
[email protected]939e7362010-05-13 20:49:105953void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:125954 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365955 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125956 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135957 if (!PrepForSetUniformByLocation(fake_location,
5958 "glUniform1fv",
5959 Program::kUniform1f,
5960 &real_location,
5961 &type,
5962 &count)) {
[email protected]939e7362010-05-13 20:49:105963 return;
5964 }
5965 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:555966 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:105967 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:535968 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105969 }
[email protected]1b0a6752012-02-22 03:44:125970 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105971 } else {
[email protected]1b0a6752012-02-22 03:44:125972 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105973 }
5974}
5975
5976void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:125977 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365978 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125979 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135980 if (!PrepForSetUniformByLocation(fake_location,
5981 "glUniform2fv",
5982 Program::kUniform2f,
5983 &real_location,
5984 &type,
5985 &count)) {
[email protected]939e7362010-05-13 20:49:105986 return;
5987 }
5988 if (type == GL_BOOL_VEC2) {
5989 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:555990 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105991 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535992 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105993 }
[email protected]1b0a6752012-02-22 03:44:125994 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105995 } else {
[email protected]1b0a6752012-02-22 03:44:125996 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105997 }
5998}
5999
6000void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:126001 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366002 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126003 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136004 if (!PrepForSetUniformByLocation(fake_location,
6005 "glUniform3fv",
6006 Program::kUniform3f,
6007 &real_location,
6008 &type,
6009 &count)) {
[email protected]939e7362010-05-13 20:49:106010 return;
6011 }
6012 if (type == GL_BOOL_VEC3) {
6013 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:556014 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106015 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536016 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106017 }
[email protected]1b0a6752012-02-22 03:44:126018 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106019 } else {
[email protected]1b0a6752012-02-22 03:44:126020 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106021 }
6022}
6023
6024void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:126025 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366026 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126027 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136028 if (!PrepForSetUniformByLocation(fake_location,
6029 "glUniform4fv",
6030 Program::kUniform4f,
6031 &real_location,
6032 &type,
6033 &count)) {
[email protected]939e7362010-05-13 20:49:106034 return;
6035 }
6036 if (type == GL_BOOL_VEC4) {
6037 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:556038 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106039 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536040 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106041 }
[email protected]1b0a6752012-02-22 03:44:126042 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106043 } else {
[email protected]1b0a6752012-02-22 03:44:126044 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106045 }
6046}
6047
[email protected]43c2f1f2011-03-25 18:35:366048void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:126049 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366050 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126051 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136052 if (!PrepForSetUniformByLocation(fake_location,
6053 "glUniform2iv",
6054 Program::kUniform2i,
6055 &real_location,
6056 &type,
6057 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366058 return;
6059 }
[email protected]1b0a6752012-02-22 03:44:126060 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366061}
6062
6063void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:126064 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366065 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126066 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136067 if (!PrepForSetUniformByLocation(fake_location,
6068 "glUniform3iv",
6069 Program::kUniform3i,
6070 &real_location,
6071 &type,
6072 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366073 return;
6074 }
[email protected]1b0a6752012-02-22 03:44:126075 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366076}
6077
6078void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:126079 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366080 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126081 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136082 if (!PrepForSetUniformByLocation(fake_location,
6083 "glUniform4iv",
6084 Program::kUniform4i,
6085 &real_location,
6086 &type,
6087 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366088 return;
6089 }
[email protected]1b0a6752012-02-22 03:44:126090 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366091}
6092
6093void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:126094 GLint fake_location, GLsizei count, GLboolean transpose,
6095 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366096 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126097 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136098 if (!PrepForSetUniformByLocation(fake_location,
6099 "glUniformMatrix2fv",
6100 Program::kUniformMatrix2f,
6101 &real_location,
6102 &type,
6103 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366104 return;
6105 }
[email protected]1b0a6752012-02-22 03:44:126106 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366107}
6108
6109void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:126110 GLint fake_location, GLsizei count, GLboolean transpose,
6111 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366112 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126113 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136114 if (!PrepForSetUniformByLocation(fake_location,
6115 "glUniformMatrix3fv",
6116 Program::kUniformMatrix3f,
6117 &real_location,
6118 &type,
6119 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366120 return;
6121 }
[email protected]1b0a6752012-02-22 03:44:126122 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366123}
6124
6125void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:126126 GLint fake_location, GLsizei count, GLboolean transpose,
6127 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366128 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126129 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136130 if (!PrepForSetUniformByLocation(fake_location,
6131 "glUniformMatrix4fv",
6132 Program::kUniformMatrix4f,
6133 &real_location,
6134 &type,
6135 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366136 return;
6137 }
[email protected]1b0a6752012-02-22 03:44:126138 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366139}
6140
[email protected]df37b9932013-03-08 05:21:426141void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:036142 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:426143 Program* program = NULL;
6144 if (program_id) {
6145 program = GetProgramInfoNotShader(program_id, "glUseProgram");
6146 if (!program) {
[email protected]ae51d192010-04-27 00:48:036147 return;
6148 }
[email protected]df37b9932013-03-08 05:21:426149 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:506150 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:516151 LOCAL_SET_GL_ERROR(
6152 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:506153 return;
6154 }
[email protected]df37b9932013-03-08 05:21:426155 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:506156 }
[email protected]7cd76fd2013-06-02 21:11:116157 if (state_.current_program.get()) {
6158 program_manager()->UnuseProgram(shader_manager(),
6159 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:146160 }
[email protected]df37b9932013-03-08 05:21:426161 state_.current_program = program;
6162 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:546163 glUseProgram(service_id);
[email protected]7cd76fd2013-06-02 21:11:116164 if (state_.current_program.get()) {
6165 program_manager()->UseProgram(state_.current_program.get());
[email protected]b05955552014-02-06 18:41:186166 if (workarounds().clear_uniforms_before_first_program_use)
6167 program_manager()->ClearUniforms(program);
[email protected]ca488e12010-12-13 20:06:146168 }
[email protected]3916c97e2010-02-25 03:20:506169}
6170
[email protected]ab09b612013-03-11 22:11:516171void GLES2DecoderImpl::RenderWarning(
6172 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:326173 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016174}
6175
[email protected]ab09b612013-03-11 22:11:516176void GLES2DecoderImpl::PerformanceWarning(
6177 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:506178 logger_.LogMessage(filename, line,
6179 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016180}
6181
[email protected]91c94eb2013-10-22 10:32:546182void GLES2DecoderImpl::DoWillUseTexImageIfNeeded(
6183 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546184 // Image is already in use if texture is attached to a framebuffer.
6185 if (texture && !texture->IsAttachedToFramebuffer()) {
6186 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6187 if (image) {
6188 ScopedGLErrorSuppressor suppressor(
6189 "GLES2DecoderImpl::DoWillUseTexImageIfNeeded",
6190 GetErrorState());
6191 glBindTexture(textarget, texture->service_id());
6192 image->WillUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026193 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546194 }
6195 }
6196}
6197
6198void GLES2DecoderImpl::DoDidUseTexImageIfNeeded(
6199 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546200 // Image is still in use if texture is attached to a framebuffer.
6201 if (texture && !texture->IsAttachedToFramebuffer()) {
6202 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6203 if (image) {
6204 ScopedGLErrorSuppressor suppressor(
6205 "GLES2DecoderImpl::DoDidUseTexImageIfNeeded",
6206 GetErrorState());
6207 glBindTexture(textarget, texture->service_id());
6208 image->DidUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026209 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546210 }
6211 }
6212}
6213
[email protected]e56131d22013-07-28 16:14:116214bool GLES2DecoderImpl::PrepareTexturesForRender() {
[email protected]7cd76fd2013-06-02 21:11:116215 DCHECK(state_.current_program.get());
[email protected]91c94eb2013-10-22 10:32:546216 if (!texture_manager()->HaveUnrenderableTextures() &&
[email protected]7bffe9e12014-01-27 23:02:556217 !texture_manager()->HaveImages()) {
[email protected]e56131d22013-07-28 16:14:116218 return true;
[email protected]ef526492010-06-02 23:12:256219 }
[email protected]e2367b42013-05-31 03:37:216220
[email protected]ef526492010-06-02 23:12:256221 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:356222 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:246223 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506224 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356225 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246226 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506227 DCHECK(uniform_info);
6228 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6229 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026230 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246231 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]91c94eb2013-10-22 10:32:546232 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366233 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]91c94eb2013-10-22 10:32:546234 GLenum textarget = GetBindTargetForSamplerType(uniform_info->type);
6235 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]ef526492010-06-02 23:12:256236 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:506237 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6238 glBindTexture(
[email protected]91c94eb2013-10-22 10:32:546239 textarget,
[email protected]00f893d2010-08-24 18:55:496240 texture_manager()->black_texture_id(uniform_info->type));
[email protected]ab09b612013-03-11 22:11:516241 LOCAL_RENDER_WARNING(
[email protected]0f8afe82012-05-14 23:43:016242 std::string("texture bound to texture unit ") +
6243 base::IntToString(texture_unit_index) +
[email protected]ad9b7f8b2013-06-17 07:36:296244 " is not renderable. It maybe non-power-of-2 and have"
6245 " incompatible texture filtering or is not"
6246 " 'texture complete'");
[email protected]91c94eb2013-10-22 10:32:546247 continue;
[email protected]3916c97e2010-02-25 03:20:506248 }
[email protected]91c94eb2013-10-22 10:32:546249
[email protected]4e7b89202014-01-28 01:44:066250 if (textarget != GL_TEXTURE_CUBE_MAP) {
6251 Texture* texture = texture_ref->texture();
6252 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6253 if (image && !texture->IsAttachedToFramebuffer()) {
6254 ScopedGLErrorSuppressor suppressor(
6255 "GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState());
6256 textures_set = true;
6257 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6258 image->WillUseTexImage();
6259 continue;
6260 }
[email protected]91c94eb2013-10-22 10:32:546261 }
[email protected]3916c97e2010-02-25 03:20:506262 }
6263 // else: should this be an error?
6264 }
6265 }
[email protected]e56131d22013-07-28 16:14:116266 return !textures_set;
[email protected]3916c97e2010-02-25 03:20:506267}
6268
[email protected]91c94eb2013-10-22 10:32:546269void GLES2DecoderImpl::RestoreStateForTextures() {
[email protected]7cd76fd2013-06-02 21:11:116270 DCHECK(state_.current_program.get());
[email protected]ed9f9cd2013-02-27 21:12:356271 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116272 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506273 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356274 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246275 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506276 DCHECK(uniform_info);
6277 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6278 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026279 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246280 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]7cd76fd2013-06-02 21:11:116281 TextureRef* texture_ref =
[email protected]91c94eb2013-10-22 10:32:546282 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496283 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]3916c97e2010-02-25 03:20:506284 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]370eaf12013-05-18 09:19:496285 // Get the texture_ref info that was previously bound here.
[email protected]7cd76fd2013-06-02 21:11:116286 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D
6287 ? texture_unit.bound_texture_2d.get()
6288 : texture_unit.bound_texture_cube_map.get();
[email protected]3916c97e2010-02-25 03:20:506289 glBindTexture(texture_unit.bind_target,
[email protected]370eaf12013-05-18 09:19:496290 texture_ref ? texture_ref->service_id() : 0);
[email protected]91c94eb2013-10-22 10:32:546291 continue;
6292 }
6293
[email protected]4e7b89202014-01-28 01:44:066294 if (texture_unit.bind_target != GL_TEXTURE_CUBE_MAP) {
6295 Texture* texture = texture_ref->texture();
6296 gfx::GLImage* image =
6297 texture->GetLevelImage(texture_unit.bind_target, 0);
6298 if (image && !texture->IsAttachedToFramebuffer()) {
6299 ScopedGLErrorSuppressor suppressor(
6300 "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState());
6301 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6302 image->DidUseTexImage();
6303 continue;
6304 }
[email protected]3916c97e2010-02-25 03:20:506305 }
6306 }
6307 }
6308 }
6309 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:246310 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:306311}
6312
[email protected]0d6bfdc2011-11-02 01:32:206313bool GLES2DecoderImpl::ClearUnclearedTextures() {
6314 // Only check if there are some uncleared textures.
6315 if (!texture_manager()->HaveUnsafeTextures()) {
6316 return true;
6317 }
6318
6319 // 1: Check all textures we are about to render with.
[email protected]7cd76fd2013-06-02 21:11:116320 if (state_.current_program.get()) {
[email protected]ed9f9cd2013-02-27 21:12:356321 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116322 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:206323 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356324 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246325 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:206326 DCHECK(uniform_info);
6327 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6328 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026329 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246330 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:496331 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366332 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496333 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
6334 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
[email protected]0d6bfdc2011-11-02 01:32:206335 return false;
6336 }
6337 }
6338 }
6339 }
6340 }
6341 }
6342 return true;
6343}
6344
[email protected]c6aef902012-02-14 03:31:426345bool GLES2DecoderImpl::IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:106346 const char* function_name, GLuint max_vertex_accessed, bool instanced,
6347 GLsizei primcount) {
6348 DCHECK(instanced || primcount == 1);
6349
[email protected]689fa1c52010-06-09 18:35:036350 // NOTE: We specifically do not check current_program->IsValid() because
6351 // it could never be invalid since glUseProgram would have failed. While
6352 // glLinkProgram could later mark the program as invalid the previous
6353 // valid program will still function if it is still the current program.
[email protected]7cd76fd2013-06-02 21:11:116354 if (!state_.current_program.get()) {
[email protected]3916c97e2010-02-25 03:20:506355 // The program does not exist.
6356 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:516357 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:506358 return false;
6359 }
[email protected]c6aef902012-02-14 03:31:426360
[email protected]7cd76fd2013-06-02 21:11:116361 return state_.vertex_attrib_manager
6362 ->ValidateBindings(function_name,
6363 this,
6364 feature_info_.get(),
6365 state_.current_program.get(),
6366 max_vertex_accessed,
[email protected]ac6904d62014-07-30 12:00:106367 instanced,
[email protected]7cd76fd2013-06-02 21:11:116368 primcount);
[email protected]b1122982010-05-17 23:04:246369}
6370
[email protected]c13e1da62011-09-09 21:48:306371bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:436372 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:306373 DCHECK(simulated);
6374 *simulated = false;
6375
[email protected]876f6fee2010-08-02 23:10:326376 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:306377 return true;
[email protected]876f6fee2010-08-02 23:10:326378
[email protected]ac77603c72013-03-08 13:52:066379 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:356380 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:246381 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:246382 bool attrib_0_used =
6383 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:066384 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:306385 return true;
[email protected]b1122982010-05-17 23:04:246386 }
6387
[email protected]b1122982010-05-17 23:04:246388 // Make a buffer with a single repeated vec4 value enough to
6389 // simulate the constant value that is supposed to be here.
6390 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:306391 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:476392 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:306393
6394 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:476395 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306396 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516397 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306398 return false;
6399 }
6400
[email protected]ab09b612013-03-11 22:11:516401 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016402 "Attribute 0 is disabled. This has signficant performance penalty");
6403
[email protected]ab09b612013-03-11 22:11:516404 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:306405 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
6406
[email protected]8f0b86c2f2012-04-10 05:48:286407 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
6408 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:496409 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306410 GLenum error = glGetError();
6411 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516412 LOCAL_SET_GL_ERROR(
6413 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306414 return false;
6415 }
[email protected]fc753442011-02-04 19:49:496416 }
[email protected]af6380962012-11-29 23:24:136417
6418 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:286419 if (new_buffer ||
6420 (attrib_0_used &&
6421 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:136422 (value.v[0] != attrib_0_value_.v[0] ||
6423 value.v[1] != attrib_0_value_.v[1] ||
6424 value.v[2] != attrib_0_value_.v[2] ||
6425 value.v[3] != attrib_0_value_.v[3])))) {
6426 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:496427 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
6428 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:136429 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:246430 attrib_0_size_ = size_needed;
6431 }
6432
6433 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
6434
[email protected]ac77603c72013-03-08 13:52:066435 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:426436 glVertexAttribDivisorANGLE(0, 0);
6437
[email protected]c13e1da62011-09-09 21:48:306438 *simulated = true;
[email protected]b1122982010-05-17 23:04:246439 return true;
[email protected]b1122982010-05-17 23:04:246440}
6441
[email protected]3fc38e22014-05-30 00:13:236442void GLES2DecoderImpl::RestoreStateForAttrib(
6443 GLuint attrib_index, bool restore_array_binding) {
[email protected]ac77603c72013-03-08 13:52:066444 const VertexAttrib* attrib =
6445 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
[email protected]3fc38e22014-05-30 00:13:236446 if (restore_array_binding) {
6447 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
6448 Buffer* buffer = attrib->buffer();
6449 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
6450 glVertexAttribPointer(
6451 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
6452 attrib->gl_stride(), ptr);
6453 }
[email protected]ac77603c72013-03-08 13:52:066454 if (attrib->divisor())
6455 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:246456 glBindBuffer(
[email protected]3fc38e22014-05-30 00:13:236457 GL_ARRAY_BUFFER, state_.bound_array_buffer.get() ?
6458 state_.bound_array_buffer->service_id() : 0);
[email protected]43410e92012-04-20 17:06:286459
[email protected]265f8992012-07-20 01:03:146460 // Never touch vertex attribute 0's state (in particular, never
6461 // disable it) when running on desktop GL because it will never be
6462 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:066463 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:146464 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:066465 if (attrib->enabled()) {
6466 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146467 } else {
[email protected]ac77603c72013-03-08 13:52:066468 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146469 }
[email protected]43410e92012-04-20 17:06:286470 }
[email protected]b1122982010-05-17 23:04:246471}
[email protected]07f54fcc2009-12-22 02:46:306472
[email protected]8fbedc02010-11-18 18:43:406473bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:436474 const char* function_name,
[email protected]c6aef902012-02-14 03:31:426475 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:406476 DCHECK(simulated);
6477 *simulated = false;
6478 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
6479 return true;
6480
[email protected]e259eb412012-10-13 05:47:246481 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:406482 return true;
6483 }
6484
[email protected]ab09b612013-03-11 22:11:516485 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016486 "GL_FIXED attributes have a signficant performance penalty");
6487
[email protected]8fbedc02010-11-18 18:43:406488 // NOTE: we could be smart and try to check if a buffer is used
6489 // twice in 2 different attribs, find the overlapping parts and therefore
6490 // duplicate the minimum amount of data but this whole code path is not meant
6491 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
6492 // tests so we just add to the buffer attrib used.
6493
[email protected]c13e1da62011-09-09 21:48:306494 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:066495 const VertexAttribManager::VertexAttribList& enabled_attribs =
6496 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
6497 for (VertexAttribManager::VertexAttribList::const_iterator it =
6498 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6499 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356500 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066501 state_.current_program->GetAttribInfoByLocation(attrib->index());
6502 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
6503 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:426504 GLuint num_vertices = max_accessed + 1;
6505 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516506 LOCAL_SET_GL_ERROR(
6507 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426508 return false;
6509 }
[email protected]8fbedc02010-11-18 18:43:406510 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066511 attrib->CanAccess(max_accessed) &&
6512 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:476513 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:066514 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:476515 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:516516 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436517 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406518 return false;
6519 }
6520 }
6521 }
6522
[email protected]3aad1a32012-09-07 20:54:476523 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
6524 uint32 size_needed = 0;
6525 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306526 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516527 LOCAL_SET_GL_ERROR(
6528 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406529 return false;
6530 }
6531
[email protected]ab09b612013-03-11 22:11:516532 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:406533
6534 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:306535 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:406536 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306537 GLenum error = glGetError();
6538 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516539 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436540 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:306541 return false;
6542 }
[email protected]8fbedc02010-11-18 18:43:406543 }
6544
6545 // Copy the elements and convert to float
6546 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:066547 for (VertexAttribManager::VertexAttribList::const_iterator it =
6548 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6549 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356550 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066551 state_.current_program->GetAttribInfoByLocation(attrib->index());
6552 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:426553 max_vertex_accessed);
6554 GLuint num_vertices = max_accessed + 1;
6555 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516556 LOCAL_SET_GL_ERROR(
6557 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426558 return false;
6559 }
[email protected]8fbedc02010-11-18 18:43:406560 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066561 attrib->CanAccess(max_accessed) &&
6562 attrib->type() == GL_FIXED) {
6563 int num_elements = attrib->size() * kSizeOfFloat;
[email protected]8fbedc02010-11-18 18:43:406564 int size = num_elements * num_vertices;
[email protected]40d90a22013-04-09 03:39:556565 scoped_ptr<float[]> data(new float[size]);
[email protected]8fbedc02010-11-18 18:43:406566 const int32* src = reinterpret_cast<const int32 *>(
[email protected]ac77603c72013-03-08 13:52:066567 attrib->buffer()->GetRange(attrib->offset(), size));
[email protected]8fbedc02010-11-18 18:43:406568 const int32* end = src + num_elements;
6569 float* dst = data.get();
6570 while (src != end) {
6571 *dst++ = static_cast<float>(*src++) / 65536.0f;
6572 }
6573 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get());
6574 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066575 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:406576 reinterpret_cast<GLvoid*>(offset));
6577 offset += size;
6578 }
6579 }
6580 *simulated = true;
6581 return true;
6582}
6583
6584void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
6585 // There's no need to call glVertexAttribPointer because we shadow all the
6586 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:246587 glBindBuffer(
6588 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:116589 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
6590 : 0);
[email protected]8fbedc02010-11-18 18:43:406591}
6592
[email protected]ad84a3a2012-06-08 21:42:436593error::Error GLES2DecoderImpl::DoDrawArrays(
6594 const char* function_name,
6595 bool instanced,
6596 GLenum mode,
6597 GLint first,
6598 GLsizei count,
6599 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226600 error::Error error = WillAccessBoundFramebufferForDraw();
6601 if (error != error::kNoError)
6602 return error;
[email protected]38d139d2011-07-14 00:38:436603 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516604 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:436605 return error::kNoError;
6606 }
6607 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516608 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:436609 return error::kNoError;
6610 }
[email protected]c6aef902012-02-14 03:31:426611 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516612 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426613 return error::kNoError;
6614 }
[email protected]ad84a3a2012-06-08 21:42:436615 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:436616 return error::kNoError;
6617 }
6618 // We have to check this here because the prototype for glDrawArrays
6619 // is GLint not GLsizei.
6620 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:516621 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:436622 return error::kNoError;
6623 }
6624
[email protected]ac6904d62014-07-30 12:00:106625 if (count == 0 || primcount == 0) {
[email protected]ab09b612013-03-11 22:11:516626 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:436627 return error::kNoError;
6628 }
6629
6630 GLuint max_vertex_accessed = first + count - 1;
[email protected]ac6904d62014-07-30 12:00:106631 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206632 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516633 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206634 return error::kNoError;
6635 }
[email protected]c13e1da62011-09-09 21:48:306636 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436637 if (!SimulateAttrib0(
6638 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306639 return error::kNoError;
6640 }
[email protected]38d139d2011-07-14 00:38:436641 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436642 if (SimulateFixedAttribs(
6643 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6644 primcount)) {
[email protected]e56131d22013-07-28 16:14:116645 bool textures_set = !PrepareTexturesForRender();
[email protected]38d139d2011-07-14 00:38:436646 ApplyDirtyState();
[email protected]00c2cf92014-03-14 00:08:376647 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:426648 if (!instanced) {
6649 glDrawArrays(mode, first, count);
6650 } else {
6651 glDrawArraysInstancedANGLE(mode, first, count, primcount);
6652 }
[email protected]38d139d2011-07-14 00:38:436653 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546654 RestoreStateForTextures();
[email protected]38d139d2011-07-14 00:38:436655 }
6656 if (simulated_fixed_attribs) {
6657 RestoreStateForSimulatedFixedAttribs();
6658 }
6659 }
6660 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:236661 // We don't have to restore attrib 0 generic data at the end of this
6662 // function even if it is simulated. This is because we will simulate
6663 // it in each draw call, and attrib 0 generic data queries use cached
6664 // values instead of passing down to the underlying driver.
6665 RestoreStateForAttrib(0, false);
[email protected]38d139d2011-07-14 00:38:436666 }
[email protected]38d139d2011-07-14 00:38:436667 }
6668 return error::kNoError;
6669}
6670
vmiuracd108592014-09-08 14:36:346671error::Error GLES2DecoderImpl::HandleDrawArrays(uint32 immediate_data_size,
6672 const void* cmd_data) {
6673 const cmds::DrawArrays& c = *static_cast<const cmds::DrawArrays*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:436674 return DoDrawArrays("glDrawArrays",
6675 false,
[email protected]c6aef902012-02-14 03:31:426676 static_cast<GLenum>(c.mode),
6677 static_cast<GLint>(c.first),
6678 static_cast<GLsizei>(c.count),
[email protected]ac6904d62014-07-30 12:00:106679 1);
[email protected]c6aef902012-02-14 03:31:426680}
6681
6682error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
vmiuracd108592014-09-08 14:36:346683 uint32 immediate_data_size,
6684 const void* cmd_data) {
6685 const gles2::cmds::DrawArraysInstancedANGLE& c =
6686 *static_cast<const gles2::cmds::DrawArraysInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:156687 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516688 LOCAL_SET_GL_ERROR(
6689 GL_INVALID_OPERATION,
6690 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426691 return error::kNoError;
6692 }
[email protected]ad84a3a2012-06-08 21:42:436693 return DoDrawArrays("glDrawArraysIntancedANGLE",
6694 true,
[email protected]c6aef902012-02-14 03:31:426695 static_cast<GLenum>(c.mode),
6696 static_cast<GLint>(c.first),
6697 static_cast<GLsizei>(c.count),
6698 static_cast<GLsizei>(c.primcount));
6699}
6700
[email protected]ad84a3a2012-06-08 21:42:436701error::Error GLES2DecoderImpl::DoDrawElements(
6702 const char* function_name,
6703 bool instanced,
6704 GLenum mode,
6705 GLsizei count,
6706 GLenum type,
6707 int32 offset,
6708 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226709 error::Error error = WillAccessBoundFramebufferForDraw();
6710 if (error != error::kNoError)
6711 return error;
[email protected]e259eb412012-10-13 05:47:246712 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:516713 LOCAL_SET_GL_ERROR(
6714 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296715 return error::kNoError;
6716 }
6717
[email protected]8eee29c2010-04-29 03:38:296718 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516719 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296720 return error::kNoError;
6721 }
6722 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516723 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296724 return error::kNoError;
6725 }
[email protected]9438b012010-06-15 22:55:056726 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516727 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296728 return error::kNoError;
6729 }
[email protected]9438b012010-06-15 22:55:056730 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516731 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296732 return error::kNoError;
6733 }
[email protected]c6aef902012-02-14 03:31:426734 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516735 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426736 return error::kNoError;
6737 }
[email protected]8eee29c2010-04-29 03:38:296738
[email protected]ad84a3a2012-06-08 21:42:436739 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276740 return error::kNoError;
6741 }
6742
[email protected]ac6904d62014-07-30 12:00:106743 if (count == 0 || primcount == 0) {
[email protected]6c788fb72010-08-26 02:16:316744 return error::kNoError;
6745 }
6746
[email protected]8eee29c2010-04-29 03:38:296747 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:086748 Buffer* element_array_buffer =
6749 state_.vertex_attrib_manager->element_array_buffer();
6750
6751 if (!element_array_buffer->GetMaxValueForRange(
6752 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:516753 LOCAL_SET_GL_ERROR(
6754 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296755 return error::kNoError;
6756 }
6757
[email protected]ac6904d62014-07-30 12:00:106758 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206759 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516760 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206761 return error::kNoError;
6762 }
[email protected]c13e1da62011-09-09 21:48:306763 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436764 if (!SimulateAttrib0(
6765 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306766 return error::kNoError;
6767 }
[email protected]8fbedc02010-11-18 18:43:406768 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436769 if (SimulateFixedAttribs(
6770 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6771 primcount)) {
[email protected]e56131d22013-07-28 16:14:116772 bool textures_set = !PrepareTexturesForRender();
[email protected]297ca1c2011-06-20 23:08:466773 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:086774 // TODO(gman): Refactor to hide these details in BufferManager or
6775 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:406776 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:086777 bool used_client_side_array = false;
6778 if (element_array_buffer->IsClientSideArray()) {
6779 used_client_side_array = true;
6780 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6781 indices = element_array_buffer->GetRange(offset, 0);
6782 }
6783
[email protected]00c2cf92014-03-14 00:08:376784 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:426785 if (!instanced) {
6786 glDrawElements(mode, count, type, indices);
6787 } else {
6788 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6789 }
[email protected]17cfbe0e2013-03-07 01:26:086790
6791 if (used_client_side_array) {
6792 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
6793 element_array_buffer->service_id());
6794 }
6795
[email protected]8fbedc02010-11-18 18:43:406796 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546797 RestoreStateForTextures();
[email protected]8fbedc02010-11-18 18:43:406798 }
6799 if (simulated_fixed_attribs) {
6800 RestoreStateForSimulatedFixedAttribs();
6801 }
[email protected]ba3176a2009-12-16 18:19:466802 }
[email protected]b1122982010-05-17 23:04:246803 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:236804 // We don't have to restore attrib 0 generic data at the end of this
6805 // function even if it is simulated. This is because we will simulate
6806 // it in each draw call, and attrib 0 generic data queries use cached
6807 // values instead of passing down to the underlying driver.
6808 RestoreStateForAttrib(0, false);
[email protected]b1122982010-05-17 23:04:246809 }
[email protected]96449d2c2009-11-25 00:01:326810 }
[email protected]f7a64ee2010-02-01 22:24:146811 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326812}
6813
vmiuracd108592014-09-08 14:36:346814error::Error GLES2DecoderImpl::HandleDrawElements(uint32 immediate_data_size,
6815 const void* cmd_data) {
6816 const gles2::cmds::DrawElements& c =
6817 *static_cast<const gles2::cmds::DrawElements*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:436818 return DoDrawElements("glDrawElements",
6819 false,
[email protected]c6aef902012-02-14 03:31:426820 static_cast<GLenum>(c.mode),
6821 static_cast<GLsizei>(c.count),
6822 static_cast<GLenum>(c.type),
6823 static_cast<int32>(c.index_offset),
[email protected]ac6904d62014-07-30 12:00:106824 1);
[email protected]c6aef902012-02-14 03:31:426825}
6826
6827error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
vmiuracd108592014-09-08 14:36:346828 uint32 immediate_data_size,
6829 const void* cmd_data) {
6830 const gles2::cmds::DrawElementsInstancedANGLE& c =
6831 *static_cast<const gles2::cmds::DrawElementsInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:156832 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516833 LOCAL_SET_GL_ERROR(
6834 GL_INVALID_OPERATION,
6835 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426836 return error::kNoError;
6837 }
[email protected]ad84a3a2012-06-08 21:42:436838 return DoDrawElements("glDrawElementsInstancedANGLE",
6839 true,
[email protected]c6aef902012-02-14 03:31:426840 static_cast<GLenum>(c.mode),
6841 static_cast<GLsizei>(c.count),
6842 static_cast<GLenum>(c.type),
6843 static_cast<int32>(c.index_offset),
6844 static_cast<GLsizei>(c.primcount));
6845}
6846
[email protected]269200b12010-11-18 22:53:066847GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:236848 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
6849 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:076850 Buffer* buffer = GetBuffer(buffer_id);
6851 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:036852 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516853 LOCAL_SET_GL_ERROR(
6854 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:236855 } else {
[email protected]b10492f2013-03-08 05:24:076856 if (!buffer->GetMaxValueForRange(
6857 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:036858 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516859 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:066860 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436861 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:236862 }
6863 }
6864 return max_vertex_accessed;
6865}
6866
[email protected]96449d2c2009-11-25 00:01:326867// Calls glShaderSource for the various versions of the ShaderSource command.
6868// Assumes that data / data_size points to a piece of memory that is in range
6869// of whatever context it came from (shared memory, immediate memory, bucket
6870// memory.)
[email protected]45bf5152010-02-12 00:11:316871error::Error GLES2DecoderImpl::ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036872 GLuint client_id, const char* data, uint32 data_size) {
[email protected]258a3313f2011-10-18 20:13:576873 std::string str(data, data + data_size);
[email protected]df37b9932013-03-08 05:21:426874 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
6875 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316876 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326877 }
[email protected]45bf5152010-02-12 00:11:316878 // Note: We don't actually call glShaderSource here. We wait until
6879 // the call to glCompileShader.
zmo576a0492014-09-13 01:12:326880 shader->set_source(str);
[email protected]f7a64ee2010-02-01 22:24:146881 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326882}
6883
[email protected]558847a2010-03-24 07:02:546884error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
vmiuracd108592014-09-08 14:36:346885 uint32 immediate_data_size,
6886 const void* cmd_data) {
6887 const gles2::cmds::ShaderSourceBucket& c =
6888 *static_cast<const gles2::cmds::ShaderSourceBucket*>(cmd_data);
[email protected]558847a2010-03-24 07:02:546889 Bucket* bucket = GetBucket(c.data_bucket_id);
6890 if (!bucket || bucket->size() == 0) {
6891 return error::kInvalidArguments;
6892 }
6893 return ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036894 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
[email protected]558847a2010-03-24 07:02:546895 bucket->size() - 1);
6896}
6897
[email protected]ae51d192010-04-27 00:48:036898void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:386899 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:426900 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
6901 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316902 return;
6903 }
[email protected]f57bb282010-11-12 00:51:346904 ShaderTranslator* translator = NULL;
[email protected]b1d2dcb2010-05-17 19:24:186905 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:426906 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]a550584e2010-09-17 18:01:456907 vertex_translator_.get() : fragment_translator_.get();
[email protected]de17df392010-04-23 21:09:416908 }
[email protected]de17df392010-04-23 21:09:416909
zmo576a0492014-09-13 01:12:326910 shader->DoCompile(
[email protected]b05955552014-02-06 18:41:186911 translator,
6912 feature_info_->feature_flags().angle_translated_shader_source ?
zmo576a0492014-09-13 01:12:326913 Shader::kANGLE : Shader::kGL);
vmiura8266ca72014-09-09 21:37:006914
6915 // CompileShader can be very slow. Exit command processing to allow for
6916 // context preemption and GPU watchdog checks.
6917 ExitCommandProcessingEarly();
6918}
[email protected]45bf5152010-02-12 00:11:316919
[email protected]ddd968b82010-03-02 00:44:296920void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:426921 GLuint shader_id, GLenum pname, GLint* params) {
6922 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
6923 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:296924 return;
6925 }
[email protected]8f1ccdac2010-05-19 21:01:486926 switch (pname) {
6927 case GL_SHADER_SOURCE_LENGTH:
zmo576a0492014-09-13 01:12:326928 *params = shader->source().size();
6929 if (*params)
6930 ++(*params);
[email protected]8f1ccdac2010-05-19 21:01:486931 return;
6932 case GL_COMPILE_STATUS:
zmo576a0492014-09-13 01:12:326933 *params = compile_shader_always_succeeds_ ? true : shader->valid();
[email protected]e5186162010-06-14 18:54:416934 return;
[email protected]8f1ccdac2010-05-19 21:01:486935 case GL_INFO_LOG_LENGTH:
zmo576a0492014-09-13 01:12:326936 *params = shader->log_info().size();
6937 if (*params)
6938 ++(*params);
[email protected]e5186162010-06-14 18:54:416939 return;
[email protected]d6a53e42011-10-05 00:09:366940 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
zmo576a0492014-09-13 01:12:326941 *params = shader->translated_source().size();
6942 if (*params)
6943 ++(*params);
[email protected]d6a53e42011-10-05 00:09:366944 return;
[email protected]8f1ccdac2010-05-19 21:01:486945 default:
6946 break;
[email protected]ddd968b82010-03-02 00:44:296947 }
[email protected]df37b9932013-03-08 05:21:426948 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:296949}
6950
vmiuracd108592014-09-08 14:36:346951error::Error GLES2DecoderImpl::HandleGetShaderSource(uint32 immediate_data_size,
6952 const void* cmd_data) {
6953 const gles2::cmds::GetShaderSource& c =
6954 *static_cast<const gles2::cmds::GetShaderSource*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:426955 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:036956 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6957 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426958 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
zmo576a0492014-09-13 01:12:326959 if (!shader || shader->source().empty()) {
[email protected]8eee29c2010-04-29 03:38:296960 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:296961 return error::kNoError;
6962 }
zmo576a0492014-09-13 01:12:326963 bucket->SetFromString(shader->source().c_str());
[email protected]ae51d192010-04-27 00:48:036964 return error::kNoError;
6965}
6966
[email protected]d6a53e42011-10-05 00:09:366967error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
6968 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:346969 const void* cmd_data) {
6970 const gles2::cmds::GetTranslatedShaderSourceANGLE& c =
6971 *static_cast<const gles2::cmds::GetTranslatedShaderSourceANGLE*>(
6972 cmd_data);
[email protected]df37b9932013-03-08 05:21:426973 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:366974 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6975 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426976 Shader* shader = GetShaderInfoNotProgram(
[email protected]caa13ed2014-02-17 11:29:206977 shader_id, "glGetTranslatedShaderSourceANGLE");
[email protected]df37b9932013-03-08 05:21:426978 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:366979 bucket->SetSize(0);
6980 return error::kNoError;
6981 }
6982
zmo576a0492014-09-13 01:12:326983 bucket->SetFromString(shader->translated_source().c_str());
[email protected]d6a53e42011-10-05 00:09:366984 return error::kNoError;
6985}
6986
[email protected]ae51d192010-04-27 00:48:036987error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
vmiuracd108592014-09-08 14:36:346988 uint32 immediate_data_size,
6989 const void* cmd_data) {
6990 const gles2::cmds::GetProgramInfoLog& c =
6991 *static_cast<const gles2::cmds::GetProgramInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:426992 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:586993 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6994 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426995 Program* program = GetProgramInfoNotShader(
6996 program_id, "glGetProgramInfoLog");
6997 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466998 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036999 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:317000 }
[email protected]df37b9932013-03-08 05:21:427001 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:037002 return error::kNoError;
7003}
7004
7005error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
vmiuracd108592014-09-08 14:36:347006 uint32 immediate_data_size,
7007 const void* cmd_data) {
7008 const gles2::cmds::GetShaderInfoLog& c =
7009 *static_cast<const gles2::cmds::GetShaderInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427010 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:587011 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7012 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427013 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
zmo576a0492014-09-13 01:12:327014 if (!shader) {
[email protected]9a14ae612011-08-08 17:51:467015 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:037016 return error::kNoError;
7017 }
zmo576a0492014-09-13 01:12:327018 bucket->SetFromString(shader->log_info().c_str());
[email protected]ae51d192010-04-27 00:48:037019 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327020}
7021
[email protected]d058bca2012-11-26 10:27:267022bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
7023 return state_.GetEnabled(cap);
7024}
7025
[email protected]1958e0e2010-04-22 05:17:157026bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:217027 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107028 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157029}
7030
7031bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:357032 const Framebuffer* framebuffer =
7033 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107034 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157035}
7036
7037bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:367038 // IsProgram is true for programs as soon as they are created, until they are
7039 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:357040 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:107041 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157042}
7043
7044bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:357045 const Renderbuffer* renderbuffer =
7046 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107047 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157048}
7049
7050bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:367051 // IsShader is true for shaders as soon as they are created, until they
7052 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:357053 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:107054 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157055}
7056
7057bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:497058 const TextureRef* texture_ref = GetTexture(client_id);
7059 return texture_ref && texture_ref->texture()->IsValid();
[email protected]ae51d192010-04-27 00:48:037060}
7061
7062void GLES2DecoderImpl::DoAttachShader(
7063 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:427064 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587065 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:427066 if (!program) {
[email protected]ae51d192010-04-27 00:48:037067 return;
[email protected]1958e0e2010-04-22 05:17:157068 }
[email protected]df37b9932013-03-08 05:21:427069 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
7070 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037071 return;
7072 }
[email protected]df37b9932013-03-08 05:21:427073 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517074 LOCAL_SET_GL_ERROR(
7075 GL_INVALID_OPERATION,
7076 "glAttachShader",
7077 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:317078 return;
7079 }
[email protected]df37b9932013-03-08 05:21:427080 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037081}
7082
7083void GLES2DecoderImpl::DoDetachShader(
7084 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:427085 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587086 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:427087 if (!program) {
[email protected]ae51d192010-04-27 00:48:037088 return;
7089 }
[email protected]df37b9932013-03-08 05:21:427090 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
7091 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037092 return;
7093 }
[email protected]df37b9932013-03-08 05:21:427094 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517095 LOCAL_SET_GL_ERROR(
7096 GL_INVALID_OPERATION,
7097 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:227098 return;
7099 }
[email protected]df37b9932013-03-08 05:21:427100 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037101}
7102
7103void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:427104 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587105 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:427106 if (!program) {
[email protected]ae51d192010-04-27 00:48:037107 return;
7108 }
[email protected]df37b9932013-03-08 05:21:427109 program->Validate();
[email protected]1958e0e2010-04-22 05:17:157110}
7111
[email protected]ac77603c72013-03-08 13:52:067112void GLES2DecoderImpl::GetVertexAttribHelper(
7113 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:247114 switch (pname) {
7115 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:067116 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:247117 if (buffer && !buffer->IsDeleted()) {
7118 GLuint client_id;
7119 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
7120 *params = client_id;
7121 }
7122 break;
7123 }
7124 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:067125 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:247126 break;
7127 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:067128 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:247129 break;
7130 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:067131 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:247132 break;
7133 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:067134 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:247135 break;
7136 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:067137 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:247138 break;
[email protected]c6aef902012-02-14 03:31:427139 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:067140 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:427141 break;
[email protected]ac77603c72013-03-08 13:52:067142 default:
7143 NOTREACHED();
7144 break;
7145 }
7146}
7147
[email protected]4c6f5462014-03-05 00:26:567148void GLES2DecoderImpl::DoGetTexParameterfv(
7149 GLenum target, GLenum pname, GLfloat* params) {
7150 InitTextureMaxAnisotropyIfNeeded(target, pname);
7151 glGetTexParameterfv(target, pname, params);
7152}
7153
7154void GLES2DecoderImpl::DoGetTexParameteriv(
7155 GLenum target, GLenum pname, GLint* params) {
7156 InitTextureMaxAnisotropyIfNeeded(target, pname);
7157 glGetTexParameteriv(target, pname, params);
7158}
7159
7160void GLES2DecoderImpl::InitTextureMaxAnisotropyIfNeeded(
7161 GLenum target, GLenum pname) {
7162 if (!workarounds().init_texture_max_anisotropy)
7163 return;
7164 if (pname != GL_TEXTURE_MAX_ANISOTROPY_EXT ||
7165 !validators_->texture_parameter.IsValid(pname)) {
7166 return;
7167 }
7168
7169 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
7170 &state_, target);
7171 if (!texture_ref) {
7172 LOCAL_SET_GL_ERROR(
7173 GL_INVALID_OPERATION,
7174 "glGetTexParamter{fi}v", "unknown texture for target");
7175 return;
7176 }
7177 Texture* texture = texture_ref->texture();
7178 texture->InitTextureMaxAnisotropyIfNeeded(target);
7179}
7180
[email protected]ac77603c72013-03-08 13:52:067181void GLES2DecoderImpl::DoGetVertexAttribfv(
7182 GLuint index, GLenum pname, GLfloat* params) {
7183 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7184 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517185 LOCAL_SET_GL_ERROR(
7186 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067187 return;
7188 }
7189 switch (pname) {
7190 case GL_CURRENT_VERTEX_ATTRIB: {
7191 const Vec4& value = state_.attrib_values[index];
7192 params[0] = value.v[0];
7193 params[1] = value.v[1];
7194 params[2] = value.v[2];
7195 params[3] = value.v[3];
7196 break;
7197 }
7198 default: {
7199 GLint value = 0;
7200 GetVertexAttribHelper(attrib, pname, &value);
7201 *params = static_cast<GLfloat>(value);
7202 break;
7203 }
7204 }
7205}
7206
7207void GLES2DecoderImpl::DoGetVertexAttribiv(
7208 GLuint index, GLenum pname, GLint* params) {
7209 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7210 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517211 LOCAL_SET_GL_ERROR(
7212 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067213 return;
7214 }
7215 switch (pname) {
[email protected]af6380962012-11-29 23:24:137216 case GL_CURRENT_VERTEX_ATTRIB: {
7217 const Vec4& value = state_.attrib_values[index];
7218 params[0] = static_cast<GLint>(value.v[0]);
7219 params[1] = static_cast<GLint>(value.v[1]);
7220 params[2] = static_cast<GLint>(value.v[2]);
7221 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:247222 break;
[email protected]af6380962012-11-29 23:24:137223 }
[email protected]b1122982010-05-17 23:04:247224 default:
[email protected]ac77603c72013-03-08 13:52:067225 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:247226 break;
7227 }
7228}
7229
[email protected]af6380962012-11-29 23:24:137230bool GLES2DecoderImpl::SetVertexAttribValue(
7231 const char* function_name, GLuint index, const GLfloat* value) {
7232 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:517233 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:137234 return false;
[email protected]b1122982010-05-17 23:04:247235 }
[email protected]af6380962012-11-29 23:24:137236 Vec4& v = state_.attrib_values[index];
7237 v.v[0] = value[0];
7238 v.v[1] = value[1];
7239 v.v[2] = value[2];
7240 v.v[3] = value[3];
7241 return true;
7242}
7243
7244void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
7245 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
7246 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
7247 glVertexAttrib1f(index, v0);
7248 }
[email protected]b1122982010-05-17 23:04:247249}
7250
7251void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:137252 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
7253 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
7254 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:247255 }
[email protected]b1122982010-05-17 23:04:247256}
7257
7258void GLES2DecoderImpl::DoVertexAttrib3f(
7259 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:137260 GLfloat v[4] = { v0, v1, v2, 1.0f, };
7261 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
7262 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:247263 }
[email protected]b1122982010-05-17 23:04:247264}
7265
7266void GLES2DecoderImpl::DoVertexAttrib4f(
7267 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:137268 GLfloat v[4] = { v0, v1, v2, v3, };
7269 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
7270 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:247271 }
[email protected]b1122982010-05-17 23:04:247272}
7273
7274void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137275 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
7276 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
7277 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:247278 }
[email protected]b1122982010-05-17 23:04:247279}
7280
7281void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137282 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
7283 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
7284 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:247285 }
[email protected]b1122982010-05-17 23:04:247286}
7287
7288void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137289 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
7290 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
7291 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:247292 }
[email protected]b1122982010-05-17 23:04:247293}
7294
7295void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137296 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
7297 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:247298 }
[email protected]b1122982010-05-17 23:04:247299}
7300
[email protected]f7a64ee2010-02-01 22:24:147301error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
vmiuracd108592014-09-08 14:36:347302 uint32 immediate_data_size,
7303 const void* cmd_data) {
7304 const gles2::cmds::VertexAttribPointer& c =
7305 *static_cast<const gles2::cmds::VertexAttribPointer*>(cmd_data);
[email protected]944b62f32012-09-27 02:20:467306
[email protected]7cd76fd2013-06-02 21:11:117307 if (!state_.bound_array_buffer.get() ||
7308 state_.bound_array_buffer->IsDeleted()) {
7309 if (state_.vertex_attrib_manager.get() ==
[email protected]81f20a622014-04-18 01:54:527310 state_.default_vertex_attrib_manager.get()) {
[email protected]ab09b612013-03-11 22:11:517311 LOCAL_SET_GL_ERROR(
7312 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:467313 return error::kNoError;
7314 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:517315 LOCAL_SET_GL_ERROR(
7316 GL_INVALID_VALUE,
7317 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:467318 return error::kNoError;
7319 }
[email protected]96449d2c2009-11-25 00:01:327320 }
[email protected]8eee29c2010-04-29 03:38:297321
7322 GLuint indx = c.indx;
7323 GLint size = c.size;
7324 GLenum type = c.type;
7325 GLboolean normalized = c.normalized;
7326 GLsizei stride = c.stride;
7327 GLsizei offset = c.offset;
7328 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:057329 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517330 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:297331 return error::kNoError;
7332 }
[email protected]9438b012010-06-15 22:55:057333 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:517334 LOCAL_SET_GL_ERROR(
7335 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:297336 return error::kNoError;
7337 }
7338 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517339 LOCAL_SET_GL_ERROR(
7340 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:297341 return error::kNoError;
7342 }
7343 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:517344 LOCAL_SET_GL_ERROR(
7345 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:297346 return error::kNoError;
7347 }
7348 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:517349 LOCAL_SET_GL_ERROR(
7350 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:297351 return error::kNoError;
7352 }
7353 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:517354 LOCAL_SET_GL_ERROR(
7355 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:297356 return error::kNoError;
7357 }
7358 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:317359 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]a07a23602014-08-05 11:36:127360 // component_size must be a power of two to use & as optimized modulo.
7361 DCHECK(GLES2Util::IsPOT(component_size));
7362 if (offset & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517363 LOCAL_SET_GL_ERROR(
7364 GL_INVALID_OPERATION,
7365 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:317366 return error::kNoError;
7367 }
[email protected]a07a23602014-08-05 11:36:127368 if (stride & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517369 LOCAL_SET_GL_ERROR(
7370 GL_INVALID_OPERATION,
7371 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:297372 return error::kNoError;
7373 }
[email protected]7cd76fd2013-06-02 21:11:117374 state_.vertex_attrib_manager
7375 ->SetAttribInfo(indx,
7376 state_.bound_array_buffer.get(),
7377 size,
7378 type,
7379 normalized,
7380 stride,
7381 stride != 0 ? stride : component_size * size,
7382 offset);
[email protected]8fbedc02010-11-18 18:43:407383 if (type != GL_FIXED) {
7384 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
7385 }
[email protected]f7a64ee2010-02-01 22:24:147386 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327387}
7388
[email protected]43410e92012-04-20 17:06:287389void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
7390 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:247391 state_.viewport_x = x;
7392 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:027393 state_.viewport_width = std::min(width, viewport_max_width_);
7394 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:287395 glViewport(x, y, width, height);
7396}
7397
[email protected]c6aef902012-02-14 03:31:427398error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
vmiuracd108592014-09-08 14:36:347399 uint32 immediate_data_size,
7400 const void* cmd_data) {
7401 const gles2::cmds::VertexAttribDivisorANGLE& c =
7402 *static_cast<const gles2::cmds::VertexAttribDivisorANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:157403 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517404 LOCAL_SET_GL_ERROR(
7405 GL_INVALID_OPERATION,
7406 "glVertexAttribDivisorANGLE", "function not available");
[email protected]cedee332014-05-23 07:07:537407 return error::kNoError;
[email protected]c6aef902012-02-14 03:31:427408 }
7409 GLuint index = c.index;
7410 GLuint divisor = c.divisor;
7411 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517412 LOCAL_SET_GL_ERROR(
7413 GL_INVALID_VALUE,
7414 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:427415 return error::kNoError;
7416 }
7417
[email protected]e259eb412012-10-13 05:47:247418 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:427419 index,
7420 divisor);
7421 glVertexAttribDivisorANGLE(index, divisor);
7422 return error::kNoError;
7423}
7424
[email protected]68586372013-12-11 01:27:597425template <typename pixel_data_type>
7426static void WriteAlphaData(
7427 void *pixels, uint32 row_count, uint32 channel_count,
7428 uint32 alpha_channel_index, uint32 unpadded_row_size,
7429 uint32 padded_row_size, pixel_data_type alpha_value) {
7430 DCHECK_GT(channel_count, 0U);
7431 DCHECK_EQ(unpadded_row_size % sizeof(pixel_data_type), 0U);
7432 uint32 unpadded_row_size_in_elements =
7433 unpadded_row_size / sizeof(pixel_data_type);
7434 DCHECK_EQ(padded_row_size % sizeof(pixel_data_type), 0U);
7435 uint32 padded_row_size_in_elements =
7436 padded_row_size / sizeof(pixel_data_type);
7437 pixel_data_type* dst =
7438 static_cast<pixel_data_type*>(pixels) + alpha_channel_index;
7439 for (uint32 yy = 0; yy < row_count; ++yy) {
7440 pixel_data_type* end = dst + unpadded_row_size_in_elements;
7441 for (pixel_data_type* d = dst; d < end; d += channel_count) {
7442 *d = alpha_value;
7443 }
7444 dst += padded_row_size_in_elements;
7445 }
7446}
7447
[email protected]5a36dc132013-07-23 23:17:557448void GLES2DecoderImpl::FinishReadPixels(
7449 const cmds::ReadPixels& c,
7450 GLuint buffer) {
7451 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels");
7452 GLsizei width = c.width;
7453 GLsizei height = c.height;
7454 GLenum format = c.format;
7455 GLenum type = c.type;
7456 typedef cmds::ReadPixels::Result Result;
7457 uint32 pixels_size;
7458 Result* result = NULL;
7459 if (c.result_shm_id != 0) {
7460 result = GetSharedMemoryAs<Result*>(
7461 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7462 if (!result) {
7463 if (buffer != 0) {
7464 glDeleteBuffersARB(1, &buffer);
7465 }
7466 return;
7467 }
7468 }
7469 GLES2Util::ComputeImageDataSizes(
7470 width, height, format, type, state_.pack_alignment, &pixels_size,
7471 NULL, NULL);
7472 void* pixels = GetSharedMemoryAs<void*>(
7473 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
7474 if (!pixels) {
7475 if (buffer != 0) {
7476 glDeleteBuffersARB(1, &buffer);
7477 }
7478 return;
7479 }
7480
7481 if (buffer != 0) {
7482 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
[email protected]e585f9e22013-08-27 02:50:337483 void* data;
7484 if (features().map_buffer_range) {
7485 data = glMapBufferRange(
7486 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT);
7487 } else {
7488 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
7489 }
[email protected]5a36dc132013-07-23 23:17:557490 memcpy(pixels, data, pixels_size);
7491 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't
7492 // have to restore the state.
7493 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
7494 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7495 glDeleteBuffersARB(1, &buffer);
7496 }
7497
7498 if (result != NULL) {
7499 *result = true;
7500 }
7501
7502 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7503 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7504 if ((channels_exist & 0x0008) == 0 &&
7505 workarounds().clear_alpha_in_readpixels) {
7506 // Set the alpha to 255 because some drivers are buggy in this regard.
7507 uint32 temp_size;
7508
7509 uint32 unpadded_row_size;
7510 uint32 padded_row_size;
7511 if (!GLES2Util::ComputeImageDataSizes(
7512 width, 2, format, type, state_.pack_alignment, &temp_size,
7513 &unpadded_row_size, &padded_row_size)) {
7514 return;
7515 }
[email protected]68586372013-12-11 01:27:597516
7517 uint32 channel_count = 0;
7518 uint32 alpha_channel = 0;
[email protected]5a36dc132013-07-23 23:17:557519 switch (format) {
7520 case GL_RGBA:
7521 case GL_BGRA_EXT:
[email protected]68586372013-12-11 01:27:597522 channel_count = 4;
7523 alpha_channel = 3;
[email protected]5a36dc132013-07-23 23:17:557524 break;
[email protected]68586372013-12-11 01:27:597525 case GL_ALPHA:
7526 channel_count = 1;
7527 alpha_channel = 0;
7528 break;
7529 }
7530
7531 if (channel_count > 0) {
7532 switch (type) {
7533 case GL_UNSIGNED_BYTE:
7534 WriteAlphaData<uint8>(
7535 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7536 padded_row_size, 0xFF);
7537 break;
7538 case GL_FLOAT:
7539 WriteAlphaData<float>(
7540 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7541 padded_row_size, 1.0f);
7542 break;
7543 case GL_HALF_FLOAT:
7544 WriteAlphaData<uint16>(
7545 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7546 padded_row_size, 0x3C00);
7547 break;
[email protected]5a36dc132013-07-23 23:17:557548 }
[email protected]5a36dc132013-07-23 23:17:557549 }
7550 }
7551}
7552
vmiuracd108592014-09-08 14:36:347553error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size,
7554 const void* cmd_data) {
7555 const gles2::cmds::ReadPixels& c =
7556 *static_cast<const gles2::cmds::ReadPixels*>(cmd_data);
[email protected]c959a09a2014-03-27 11:44:217557 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleReadPixels");
[email protected]c76fe672013-12-13 23:30:227558 error::Error fbo_error = WillAccessBoundFramebufferForRead();
7559 if (fbo_error != error::kNoError)
7560 return fbo_error;
[email protected]612d2f82009-12-08 20:49:317561 GLint x = c.x;
7562 GLint y = c.y;
7563 GLsizei width = c.width;
7564 GLsizei height = c.height;
7565 GLenum format = c.format;
7566 GLenum type = c.type;
[email protected]5a36dc132013-07-23 23:17:557567 GLboolean async = c.async;
[email protected]57f223832010-03-19 01:57:567568 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:517569 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:567570 return error::kNoError;
7571 }
[email protected]ed9f9cd2013-02-27 21:12:357572 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:187573 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347574 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247575 width, height, format, type, state_.pack_alignment, &pixels_size,
7576 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187577 return error::kOutOfBounds;
7578 }
[email protected]612d2f82009-12-08 20:49:317579 void* pixels = GetSharedMemoryAs<void*>(
7580 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:107581 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147582 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467583 }
[email protected]de43f082013-04-02 01:16:107584 Result* result = NULL;
7585 if (c.result_shm_id != 0) {
7586 result = GetSharedMemoryAs<Result*>(
7587 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7588 if (!result) {
7589 return error::kOutOfBounds;
7590 }
7591 }
[email protected]a51788e2010-02-24 21:54:257592
[email protected]9438b012010-06-15 22:55:057593 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517594 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:297595 return error::kNoError;
7596 }
[email protected]68586372013-12-11 01:27:597597 if (!validators_->read_pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517598 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:127599 return error::kNoError;
7600 }
[email protected]68586372013-12-11 01:27:597601 if ((format != GL_RGBA && format != GL_BGRA_EXT && format != GL_RGB &&
7602 format != GL_ALPHA) || type != GL_UNSIGNED_BYTE) {
7603 // format and type are acceptable enums but not guaranteed to be supported
7604 // for this framebuffer. Have to ask gl if they are valid.
7605 GLint preferred_format = 0;
7606 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &preferred_format);
7607 GLint preferred_type = 0;
7608 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &preferred_type);
7609 if (format != static_cast<GLenum>(preferred_format) ||
7610 type != static_cast<GLenum>(preferred_type)) {
7611 LOCAL_SET_GL_ERROR(
7612 GL_INVALID_OPERATION, "glReadPixels", "format and type incompatible "
7613 "with the current read framebuffer");
7614 return error::kNoError;
7615 }
7616 }
[email protected]57f223832010-03-19 01:57:567617 if (width == 0 || height == 0) {
7618 return error::kNoError;
7619 }
7620
[email protected]57f223832010-03-19 01:57:567621 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:307622 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:567623
[email protected]3aad1a32012-09-07 20:54:477624 int32 max_x;
7625 int32 max_y;
7626 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:517627 LOCAL_SET_GL_ERROR(
7628 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:147629 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:317630 }
[email protected]57f223832010-03-19 01:57:567631
[email protected]2ea5950d2014-07-09 18:20:347632 if (!CheckBoundReadFramebufferColorAttachment("glReadPixels")) {
7633 return error::kNoError;
7634 }
7635
[email protected]0d6bfdc2011-11-02 01:32:207636 if (!CheckBoundFramebuffersValid("glReadPixels")) {
7637 return error::kNoError;
7638 }
7639
[email protected]caa13ed2014-02-17 11:29:207640 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixels");
[email protected]a0b78dc2011-11-11 10:43:107641
7642 ScopedResolvedFrameBufferBinder binder(this, false, true);
7643
[email protected]d37231fa2010-04-09 21:16:027644 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:567645 // The user requested an out of range area. Get the results 1 line
7646 // at a time.
7647 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:347648 uint32 unpadded_row_size;
7649 uint32 padded_row_size;
7650 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247651 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:347652 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:517653 LOCAL_SET_GL_ERROR(
7654 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567655 return error::kNoError;
7656 }
7657
7658 GLint dest_x_offset = std::max(-x, 0);
7659 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:347660 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247661 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset,
7662 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:517663 LOCAL_SET_GL_ERROR(
7664 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567665 return error::kNoError;
7666 }
7667
7668 // Copy each row into the larger dest rect.
7669 int8* dst = static_cast<int8*>(pixels);
7670 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:027671 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:567672 GLint read_width = read_end_x - read_x;
7673 for (GLint yy = 0; yy < height; ++yy) {
7674 GLint ry = y + yy;
7675
7676 // Clear the row.
7677 memset(dst, 0, unpadded_row_size);
7678
7679 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:027680 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:567681 glReadPixels(
7682 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
7683 }
7684 dst += padded_row_size;
7685 }
7686 } else {
[email protected]5a36dc132013-07-23 23:17:557687 if (async && features().use_async_readpixels) {
7688 GLuint buffer;
7689 glGenBuffersARB(1, &buffer);
7690 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
7691 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, GL_STREAM_READ);
7692 GLenum error = glGetError();
7693 if (error == GL_NO_ERROR) {
7694 glReadPixels(x, y, width, height, format, type, 0);
7695 pending_readpixel_fences_.push(linked_ptr<FenceCallback>(
7696 new FenceCallback()));
7697 WaitForReadPixels(base::Bind(
7698 &GLES2DecoderImpl::FinishReadPixels,
7699 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr
7700 <GLES2DecoderImpl>(this),
7701 c, buffer));
7702 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7703 return error::kNoError;
[email protected]77bfe7442014-03-01 02:42:597704 } else {
7705 // On error, unbind pack buffer and fall through to sync readpixels
7706 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
[email protected]5a36dc132013-07-23 23:17:557707 }
7708 }
[email protected]57f223832010-03-19 01:57:567709 glReadPixels(x, y, width, height, format, type, pixels);
7710 }
[email protected]ab09b612013-03-11 22:11:517711 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:257712 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:107713 if (result != NULL) {
7714 *result = true;
7715 }
[email protected]5a36dc132013-07-23 23:17:557716 FinishReadPixels(c, 0);
[email protected]a51788e2010-02-24 21:54:257717 }
[email protected]4848b9f82011-03-10 18:37:567718
[email protected]f7a64ee2010-02-01 22:24:147719 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327720}
7721
vmiuracd108592014-09-08 14:36:347722error::Error GLES2DecoderImpl::HandlePixelStorei(uint32 immediate_data_size,
7723 const void* cmd_data) {
7724 const gles2::cmds::PixelStorei& c =
7725 *static_cast<const gles2::cmds::PixelStorei*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:197726 GLenum pname = c.pname;
7727 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:057728 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:517729 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:127730 return error::kNoError;
7731 }
[email protected]222471d2011-11-30 18:06:397732 switch (pname) {
7733 case GL_PACK_ALIGNMENT:
7734 case GL_UNPACK_ALIGNMENT:
7735 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:517736 LOCAL_SET_GL_ERROR(
[email protected]caa13ed2014-02-17 11:29:207737 GL_INVALID_VALUE, "glPixelStorei", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:397738 return error::kNoError;
7739 }
[email protected]164d6d52012-05-05 00:55:037740 break;
[email protected]0a1e9ad2012-05-04 21:13:037741 case GL_UNPACK_FLIP_Y_CHROMIUM:
7742 unpack_flip_y_ = (param != 0);
7743 return error::kNoError;
7744 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
7745 unpack_premultiply_alpha_ = (param != 0);
7746 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:177747 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
7748 unpack_unpremultiply_alpha_ = (param != 0);
7749 return error::kNoError;
[email protected]222471d2011-11-30 18:06:397750 default:
7751 break;
[email protected]b9849abf2009-11-25 19:13:197752 }
7753 glPixelStorei(pname, param);
7754 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:437755 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247756 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437757 break;
7758 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:427759 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:437760 break;
7761 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247762 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437763 break;
7764 default:
7765 // Validation should have prevented us from getting here.
7766 NOTREACHED();
7767 break;
[email protected]b9849abf2009-11-25 19:13:197768 }
[email protected]f7a64ee2010-02-01 22:24:147769 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197770}
7771
[email protected]1c75a3702011-11-11 14:15:287772error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
vmiuracd108592014-09-08 14:36:347773 uint32 immediate_data_size,
7774 const void* cmd_data) {
7775 const gles2::cmds::PostSubBufferCHROMIUM& c =
7776 *static_cast<const gles2::cmds::PostSubBufferCHROMIUM*>(cmd_data);
[email protected]43ed3a72012-05-30 22:55:387777 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]a36ed4832014-04-24 16:40:277778 {
7779 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
7780 }
[email protected]b381ee32014-03-22 02:43:437781 if (!supports_post_sub_buffer_) {
[email protected]ab09b612013-03-11 22:11:517782 LOCAL_SET_GL_ERROR(
7783 GL_INVALID_OPERATION,
7784 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:287785 return error::kNoError;
7786 }
[email protected]8f9b8dd2013-09-12 18:05:137787 bool is_tracing;
7788 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
7789 &is_tracing);
7790 if (is_tracing) {
7791 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
7792 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
7793 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
7794 is_offscreen ? offscreen_size_ : surface_->GetSize());
7795 }
[email protected]7794d512012-04-17 20:36:497796 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:287797 return error::kNoError;
[email protected]7794d512012-04-17 20:36:497798 } else {
7799 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:287800 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:497801 }
[email protected]1c75a3702011-11-11 14:15:287802}
7803
[email protected]957f0642014-04-09 16:50:017804error::Error GLES2DecoderImpl::HandleScheduleOverlayPlaneCHROMIUM(
7805 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:347806 const void* cmd_data) {
7807 const gles2::cmds::ScheduleOverlayPlaneCHROMIUM& c =
7808 *static_cast<const gles2::cmds::ScheduleOverlayPlaneCHROMIUM*>(cmd_data);
[email protected]d286ebbc2014-07-03 17:19:107809 TextureRef* ref = texture_manager()->GetTexture(c.overlay_texture_id);
7810 if (!ref) {
7811 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
7812 "glScheduleOverlayPlaneCHROMIUM",
7813 "unknown texture");
7814 return error::kNoError;
7815 }
7816 gfx::GLImage* image =
7817 ref->texture()->GetLevelImage(ref->texture()->target(), 0);
7818 if (!image) {
7819 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
7820 "glScheduleOverlayPlaneCHROMIUM",
7821 "unsupported texture format");
7822 return error::kNoError;
7823 }
7824 gfx::OverlayTransform transform = GetGFXOverlayTransform(c.plane_transform);
7825 if (transform == gfx::OVERLAY_TRANSFORM_INVALID) {
7826 LOCAL_SET_GL_ERROR(GL_INVALID_ENUM,
7827 "glScheduleOverlayPlaneCHROMIUM",
7828 "invalid transform enum");
7829 return error::kNoError;
7830 }
7831 if (!surface_->ScheduleOverlayPlane(
7832 c.plane_z_order,
7833 transform,
7834 image,
7835 gfx::Rect(c.bounds_x, c.bounds_y, c.bounds_width, c.bounds_height),
7836 gfx::RectF(c.uv_x, c.uv_y, c.uv_width, c.uv_height))) {
7837 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
7838 "glScheduleOverlayPlaneCHROMIUM",
7839 "failed to schedule overlay");
7840 }
[email protected]957f0642014-04-09 16:50:017841 return error::kNoError;
7842}
7843
[email protected]558847a2010-03-24 07:02:547844error::Error GLES2DecoderImpl::GetAttribLocationHelper(
7845 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7846 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577847 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517848 LOCAL_SET_GL_ERROR(
7849 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577850 return error::kNoError;
7851 }
[email protected]df37b9932013-03-08 05:21:427852 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587853 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:427854 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147855 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197856 }
[email protected]df37b9932013-03-08 05:21:427857 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517858 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437859 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257860 return error::kNoError;
7861 }
[email protected]b9849abf2009-11-25 19:13:197862 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547863 location_shm_id, location_shm_offset, sizeof(GLint));
7864 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147865 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197866 }
[email protected]558847a2010-03-24 07:02:547867 // Require the client to init this incase the context is lost and we are no
7868 // longer executing commands.
7869 if (*location != -1) {
7870 return error::kGenericError;
7871 }
[email protected]df37b9932013-03-08 05:21:427872 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147873 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197874}
7875
[email protected]558847a2010-03-24 07:02:547876error::Error GLES2DecoderImpl::HandleGetAttribLocation(
vmiuracd108592014-09-08 14:36:347877 uint32 immediate_data_size,
7878 const void* cmd_data) {
7879 const gles2::cmds::GetAttribLocation& c =
7880 *static_cast<const gles2::cmds::GetAttribLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:547881 Bucket* bucket = GetBucket(c.name_bucket_id);
7882 if (!bucket) {
7883 return error::kInvalidArguments;
7884 }
7885 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187886 if (!bucket->GetAsString(&name_str)) {
7887 return error::kInvalidArguments;
7888 }
[email protected]558847a2010-03-24 07:02:547889 return GetAttribLocationHelper(
7890 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7891}
7892
7893error::Error GLES2DecoderImpl::GetUniformLocationHelper(
7894 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7895 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577896 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517897 LOCAL_SET_GL_ERROR(
7898 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577899 return error::kNoError;
7900 }
[email protected]df37b9932013-03-08 05:21:427901 Program* program = GetProgramInfoNotShader(
[email protected]caa13ed2014-02-17 11:29:207902 client_id, "glGetUniformLocation");
[email protected]df37b9932013-03-08 05:21:427903 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147904 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197905 }
[email protected]df37b9932013-03-08 05:21:427906 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517907 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437908 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257909 return error::kNoError;
7910 }
[email protected]b9849abf2009-11-25 19:13:197911 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547912 location_shm_id, location_shm_offset, sizeof(GLint));
7913 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147914 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197915 }
[email protected]558847a2010-03-24 07:02:547916 // Require the client to init this incase the context is lost an we are no
7917 // longer executing commands.
7918 if (*location != -1) {
7919 return error::kGenericError;
7920 }
[email protected]df37b9932013-03-08 05:21:427921 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147922 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197923}
7924
[email protected]f7a64ee2010-02-01 22:24:147925error::Error GLES2DecoderImpl::HandleGetUniformLocation(
vmiuracd108592014-09-08 14:36:347926 uint32 immediate_data_size,
7927 const void* cmd_data) {
7928 const gles2::cmds::GetUniformLocation& c =
7929 *static_cast<const gles2::cmds::GetUniformLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:547930 Bucket* bucket = GetBucket(c.name_bucket_id);
7931 if (!bucket) {
7932 return error::kInvalidArguments;
7933 }
7934 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187935 if (!bucket->GetAsString(&name_str)) {
7936 return error::kInvalidArguments;
7937 }
[email protected]558847a2010-03-24 07:02:547938 return GetUniformLocationHelper(
7939 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197940}
7941
vmiuracd108592014-09-08 14:36:347942error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size,
7943 const void* cmd_data) {
7944 const gles2::cmds::GetString& c =
7945 *static_cast<const gles2::cmds::GetString*>(cmd_data);
[email protected]ddd968b82010-03-02 00:44:297946 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:057947 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:517948 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:297949 return error::kNoError;
7950 }
[email protected]959e9072013-09-20 16:58:387951 const char* str = reinterpret_cast<const char*>(glGetString(name));
[email protected]f0d74742011-10-03 16:31:047952 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:157953 switch (name) {
7954 case GL_VERSION:
7955 str = "OpenGL ES 2.0 Chromium";
7956 break;
7957 case GL_SHADING_LANGUAGE_VERSION:
7958 str = "OpenGL ES GLSL ES 1.0 Chromium";
7959 break;
[email protected]32939602012-05-09 06:25:167960 case GL_RENDERER:
[email protected]32939602012-05-09 06:25:167961 case GL_VENDOR:
[email protected]959e9072013-09-20 16:58:387962 // Return the unmasked VENDOR/RENDERER string for WebGL contexts.
7963 // They are used by WEBGL_debug_renderer_info.
7964 if (!force_webgl_glsl_validation_)
7965 str = "Chromium";
[email protected]32939602012-05-09 06:25:167966 break;
[email protected]1958e0e2010-04-22 05:17:157967 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:047968 {
[email protected]70dc60932013-06-04 03:33:497969 // For WebGL contexts, strip out the OES derivatives and
7970 // EXT frag depth extensions if they have not been enabled.
7971 if (force_webgl_glsl_validation_) {
[email protected]f0d74742011-10-03 16:31:047972 extensions = feature_info_->extensions();
[email protected]70dc60932013-06-04 03:33:497973 if (!derivatives_explicitly_enabled_) {
7974 size_t offset = extensions.find(kOESDerivativeExtension);
7975 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097976 extensions.replace(offset, arraysize(kOESDerivativeExtension),
[email protected]70dc60932013-06-04 03:33:497977 std::string());
7978 }
7979 }
7980 if (!frag_depth_explicitly_enabled_) {
7981 size_t offset = extensions.find(kEXTFragDepthExtension);
7982 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097983 extensions.replace(offset, arraysize(kEXTFragDepthExtension),
[email protected]70dc60932013-06-04 03:33:497984 std::string());
7985 }
[email protected]f0d74742011-10-03 16:31:047986 }
[email protected]aff39ac82013-06-08 04:53:137987 if (!draw_buffers_explicitly_enabled_) {
7988 size_t offset = extensions.find(kEXTDrawBuffersExtension);
7989 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097990 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension),
[email protected]aff39ac82013-06-08 04:53:137991 std::string());
7992 }
7993 }
[email protected]93c2fd82014-04-16 02:46:067994 if (!shader_texture_lod_explicitly_enabled_) {
7995 size_t offset = extensions.find(kEXTShaderTextureLodExtension);
7996 if (std::string::npos != offset) {
7997 extensions.replace(offset,
7998 arraysize(kEXTShaderTextureLodExtension),
7999 std::string());
8000 }
8001 }
[email protected]f0d74742011-10-03 16:31:048002 } else {
[email protected]6f5fac9d12012-06-26 21:02:458003 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:048004 }
[email protected]b381ee32014-03-22 02:43:438005 if (supports_post_sub_buffer_)
8006 extensions += " GL_CHROMIUM_post_sub_buffer";
[email protected]6f5fac9d12012-06-26 21:02:458007 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:048008 }
[email protected]1958e0e2010-04-22 05:17:158009 break;
8010 default:
[email protected]1958e0e2010-04-22 05:17:158011 break;
8012 }
[email protected]ddd968b82010-03-02 00:44:298013 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:158014 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:298015 return error::kNoError;
8016}
8017
vmiuracd108592014-09-08 14:36:348018error::Error GLES2DecoderImpl::HandleBufferData(uint32 immediate_data_size,
8019 const void* cmd_data) {
8020 const gles2::cmds::BufferData& c =
8021 *static_cast<const gles2::cmds::BufferData*>(cmd_data);
[email protected]0c86dbf2010-03-05 08:14:118022 GLenum target = static_cast<GLenum>(c.target);
8023 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
8024 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8025 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8026 GLenum usage = static_cast<GLenum>(c.usage);
8027 const void* data = NULL;
8028 if (data_shm_id != 0 || data_shm_offset != 0) {
8029 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
8030 if (!data) {
8031 return error::kOutOfBounds;
8032 }
8033 }
[email protected]0fbba3732013-07-17 15:40:138034 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:148035 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198036}
8037
[email protected]0c86dbf2010-03-05 08:14:118038void GLES2DecoderImpl::DoBufferSubData(
8039 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]0fbba3732013-07-17 15:40:138040 // Just delegate it. Some validation is actually done before this.
8041 buffer_manager()->ValidateAndDoBufferSubData(
8042 &state_, target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:198043}
8044
[email protected]0d6bfdc2011-11-02 01:32:208045bool GLES2DecoderImpl::ClearLevel(
8046 unsigned service_id,
8047 unsigned bind_target,
8048 unsigned target,
8049 int level,
[email protected]d8e6c9242014-02-20 16:56:258050 unsigned internal_format,
[email protected]0d6bfdc2011-11-02 01:32:208051 unsigned format,
8052 unsigned type,
8053 int width,
[email protected]4502e6492011-12-14 19:39:158054 int height,
8055 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:008056 uint32 channels = GLES2Util::GetChannelsForFormat(format);
[email protected]345ba902013-11-14 21:39:008057 if (feature_info_->feature_flags().angle_depth_texture &&
8058 (channels & GLES2Util::kDepth) != 0) {
[email protected]81375742012-06-08 00:04:008059 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
8060 // on depth formats.
8061 GLuint fb = 0;
8062 glGenFramebuffersEXT(1, &fb);
8063 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
8064
8065 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
8066 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
8067 GL_DEPTH_ATTACHMENT;
8068
8069 glFramebufferTexture2DEXT(
8070 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
8071 // ANGLE promises a depth only attachment ok.
8072 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
8073 GL_FRAMEBUFFER_COMPLETE) {
8074 return false;
8075 }
8076 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:478077 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
8078 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]81375742012-06-08 00:04:008079 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:458080 state_.SetDeviceDepthMask(GL_TRUE);
8081 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]81375742012-06-08 00:04:008082 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
8083
8084 RestoreClearState();
8085
8086 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:358087 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:008088 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
8089 GLuint fb_service_id =
8090 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
8091 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
8092 return true;
8093 }
8094
[email protected]45d15a62012-04-18 14:33:178095 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
8096
8097 uint32 size;
8098 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:348099 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248100 width, height, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:178101 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:208102 return false;
8103 }
[email protected]45d15a62012-04-18 14:33:178104
[email protected]a5d3dad2012-05-26 04:34:448105 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
8106
[email protected]45d15a62012-04-18 14:33:178107 int tile_height;
8108
8109 if (size > kMaxZeroSize) {
8110 if (kMaxZeroSize < padded_row_size) {
8111 // That'd be an awfully large texture.
8112 return false;
8113 }
8114 // We should never have a large total size with a zero row size.
8115 DCHECK_GT(padded_row_size, 0U);
8116 tile_height = kMaxZeroSize / padded_row_size;
8117 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248118 width, tile_height, format, type, state_.unpack_alignment, &size,
8119 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:178120 return false;
8121 }
[email protected]4502e6492011-12-14 19:39:158122 } else {
[email protected]45d15a62012-04-18 14:33:178123 tile_height = height;
8124 }
8125
8126 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:558127 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:178128 memset(zero.get(), 0, size);
8129 glBindTexture(bind_target, service_id);
8130
8131 GLint y = 0;
8132 while (y < height) {
8133 GLint h = y + tile_height > height ? height - y : tile_height;
8134 if (is_texture_immutable || h != height) {
8135 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
8136 } else {
[email protected]8f1d2aa2013-05-10 23:45:388137 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:258138 target, level, internal_format, width, h, 0, format, type,
8139 zero.get());
[email protected]45d15a62012-04-18 14:33:178140 }
8141 y += tile_height;
[email protected]4502e6492011-12-14 19:39:158142 }
[email protected]c986af502013-08-14 01:04:448143 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
8144 &state_, bind_target);
[email protected]02965c22013-03-09 02:40:078145 glBindTexture(bind_target, texture ? texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:208146 return true;
8147}
8148
[email protected]ad84a3a2012-06-08 21:42:438149namespace {
8150
8151const int kS3TCBlockWidth = 4;
8152const int kS3TCBlockHeight = 4;
8153const int kS3TCDXT1BlockSize = 8;
8154const int kS3TCDXT3AndDXT5BlockSize = 16;
8155
8156bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:518157 return (size == 1) ||
8158 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:438159}
8160
[email protected]8aec81ec2014-04-29 01:04:518161bool IsValidPVRTCSize(GLint level, GLsizei size) {
[email protected]a07a23602014-08-05 11:36:128162 return GLES2Util::IsPOT(size);
[email protected]8aec81ec2014-04-29 01:04:518163}
8164
[email protected]ad84a3a2012-06-08 21:42:438165} // anonymous namespace.
8166
8167bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
8168 const char* function_name,
8169 GLsizei width, GLsizei height, GLenum format, size_t size) {
8170 unsigned int bytes_required = 0;
8171
8172 switch (format) {
[email protected]8aec81ec2014-04-29 01:04:518173 case GL_ATC_RGB_AMD:
[email protected]ad84a3a2012-06-08 21:42:438174 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
[email protected]8aec81ec2014-04-29 01:04:518175 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8176 case GL_ETC1_RGB8_OES: {
[email protected]ad84a3a2012-06-08 21:42:438177 int num_blocks_across =
8178 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8179 int num_blocks_down =
8180 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8181 int num_blocks = num_blocks_across * num_blocks_down;
8182 bytes_required = num_blocks * kS3TCDXT1BlockSize;
8183 break;
8184 }
[email protected]8aec81ec2014-04-29 01:04:518185 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8186 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
[email protected]ad84a3a2012-06-08 21:42:438187 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8188 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8189 int num_blocks_across =
8190 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8191 int num_blocks_down =
8192 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8193 int num_blocks = num_blocks_across * num_blocks_down;
8194 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
8195 break;
8196 }
[email protected]8aec81ec2014-04-29 01:04:518197 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8198 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: {
8199 bytes_required = (std::max(width, 8) * std::max(height, 8) * 4 + 7)/8;
8200 break;
8201 }
8202 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8203 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8204 bytes_required = (std::max(width, 16) * std::max(height, 8) * 2 + 7)/8;
[email protected]2d3765b2012-10-03 00:31:078205 break;
8206 }
[email protected]ad84a3a2012-06-08 21:42:438207 default:
[email protected]ab09b612013-03-11 22:11:518208 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:438209 return false;
8210 }
8211
8212 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:518213 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438214 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
8215 return false;
8216 }
8217
8218 return true;
8219}
8220
8221bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
8222 const char* function_name,
8223 GLint level, GLsizei width, GLsizei height, GLenum format) {
8224 switch (format) {
8225 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8226 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8227 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8228 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8229 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:518230 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438231 GL_INVALID_OPERATION, function_name,
8232 "width or height invalid for level");
8233 return false;
8234 }
8235 return true;
8236 }
[email protected]8aec81ec2014-04-29 01:04:518237 case GL_ATC_RGB_AMD:
8238 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8239 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
8240 case GL_ETC1_RGB8_OES: {
[email protected]2d3765b2012-10-03 00:31:078241 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:518242 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078243 GL_INVALID_OPERATION, function_name,
8244 "width or height invalid for level");
8245 return false;
8246 }
8247 return true;
[email protected]8aec81ec2014-04-29 01:04:518248 }
8249 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8250 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8251 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8252 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8253 if (!IsValidPVRTCSize(level, width) ||
8254 !IsValidPVRTCSize(level, height)) {
8255 LOCAL_SET_GL_ERROR(
8256 GL_INVALID_OPERATION, function_name,
8257 "width or height invalid for level");
8258 return false;
8259 }
8260 return true;
8261 }
[email protected]ad84a3a2012-06-08 21:42:438262 default:
8263 return false;
8264 }
8265}
8266
8267bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
8268 const char* function_name,
8269 GLenum target, GLint level, GLint xoffset, GLint yoffset,
8270 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:358271 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:438272 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:518273 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438274 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
8275 return false;
8276 }
8277
8278 switch (format) {
8279 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8280 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8281 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8282 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8283 const int kBlockWidth = 4;
8284 const int kBlockHeight = 4;
8285 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:518286 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438287 GL_INVALID_OPERATION, function_name,
8288 "xoffset or yoffset not multiple of 4");
8289 return false;
8290 }
8291 GLsizei tex_width = 0;
8292 GLsizei tex_height = 0;
8293 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8294 width - xoffset > tex_width ||
8295 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:518296 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438297 GL_INVALID_OPERATION, function_name, "dimensions out of range");
8298 return false;
8299 }
8300 return ValidateCompressedTexDimensions(
8301 function_name, level, width, height, format);
8302 }
[email protected]8aec81ec2014-04-29 01:04:518303 case GL_ATC_RGB_AMD:
8304 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8305 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: {
8306 LOCAL_SET_GL_ERROR(
8307 GL_INVALID_OPERATION, function_name,
8308 "not supported for ATC textures");
8309 return false;
8310 }
[email protected]2d3765b2012-10-03 00:31:078311 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:518312 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078313 GL_INVALID_OPERATION, function_name,
[email protected]caa13ed2014-02-17 11:29:208314 "not supported for ECT1_RGB8_OES textures");
[email protected]2d3765b2012-10-03 00:31:078315 return false;
8316 }
[email protected]8aec81ec2014-04-29 01:04:518317 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8318 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8319 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8320 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8321 if ((xoffset != 0) || (yoffset != 0)) {
8322 LOCAL_SET_GL_ERROR(
8323 GL_INVALID_OPERATION, function_name,
8324 "xoffset and yoffset must be zero");
8325 return false;
8326 }
8327 GLsizei tex_width = 0;
8328 GLsizei tex_height = 0;
8329 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8330 width != tex_width ||
8331 height != tex_height) {
8332 LOCAL_SET_GL_ERROR(
8333 GL_INVALID_OPERATION, function_name,
8334 "dimensions must match existing texture level dimensions");
8335 return false;
8336 }
8337 return ValidateCompressedTexDimensions(
8338 function_name, level, width, height, format);
8339 }
[email protected]ad84a3a2012-06-08 21:42:438340 default:
8341 return false;
8342 }
8343}
8344
[email protected]a93bb842010-02-16 23:03:478345error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
8346 GLenum target,
8347 GLint level,
8348 GLenum internal_format,
8349 GLsizei width,
8350 GLsizei height,
8351 GLint border,
8352 GLsizei image_size,
8353 const void* data) {
[email protected]a93bb842010-02-16 23:03:478354 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:058355 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518356 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8357 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:298358 return error::kNoError;
8359 }
[email protected]9438b012010-06-15 22:55:058360 if (!validators_->compressed_texture_format.IsValid(
8361 internal_format)) {
[email protected]ab09b612013-03-11 22:11:518362 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538363 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:478364 return error::kNoError;
8365 }
[email protected]80eb6b52012-01-19 00:14:418366 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:478367 border != 0) {
[email protected]ab09b612013-03-11 22:11:518368 LOCAL_SET_GL_ERROR(
8369 GL_INVALID_VALUE,
8370 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:478371 return error::kNoError;
8372 }
[email protected]c986af502013-08-14 01:04:448373 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8374 &state_, target);
[email protected]370eaf12013-05-18 09:19:498375 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518376 LOCAL_SET_GL_ERROR(
8377 GL_INVALID_VALUE,
8378 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:478379 return error::kNoError;
8380 }
[email protected]370eaf12013-05-18 09:19:498381 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078382 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518383 LOCAL_SET_GL_ERROR(
8384 GL_INVALID_OPERATION,
8385 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:438386 return error::kNoError;
8387 }
8388
8389 if (!ValidateCompressedTexDimensions(
8390 "glCompressedTexImage2D", level, width, height, internal_format) ||
8391 !ValidateCompressedTexFuncData(
8392 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:178393 return error::kNoError;
8394 }
[email protected]968351b2011-12-20 08:26:518395
[email protected]7989c9e2013-01-23 06:39:268396 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:518397 LOCAL_SET_GL_ERROR(
8398 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:268399 return error::kNoError;
8400 }
8401
[email protected]02965c22013-03-09 02:40:078402 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448403 framebuffer_state_.clear_state_dirty = true;
[email protected]968351b2011-12-20 08:26:518404 }
8405
[email protected]40d90a22013-04-09 03:39:558406 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:478407 if (!data) {
8408 zero.reset(new int8[image_size]);
8409 memset(zero.get(), 0, image_size);
8410 data = zero.get();
8411 }
[email protected]ab09b612013-03-11 22:11:518412 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:478413 glCompressedTexImage2D(
8414 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:518415 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438416 if (error == GL_NO_ERROR) {
8417 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498418 texture_ref, target, level, internal_format,
8419 width, height, 1, border, 0, 0, true);
[email protected]cadde4a2010-07-31 17:10:438420 }
vmiura8266ca72014-09-09 21:37:008421
8422 // This may be a slow command. Exit command processing to allow for
8423 // context preemption and GPU watchdog checks.
8424 ExitCommandProcessingEarly();
[email protected]a93bb842010-02-16 23:03:478425 return error::kNoError;
8426}
8427
[email protected]f7a64ee2010-02-01 22:24:148428error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
vmiuracd108592014-09-08 14:36:348429 uint32 immediate_data_size,
8430 const void* cmd_data) {
8431 const gles2::cmds::CompressedTexImage2D& c =
8432 *static_cast<const gles2::cmds::CompressedTexImage2D*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:198433 GLenum target = static_cast<GLenum>(c.target);
8434 GLint level = static_cast<GLint>(c.level);
8435 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8436 GLsizei width = static_cast<GLsizei>(c.width);
8437 GLsizei height = static_cast<GLsizei>(c.height);
8438 GLint border = static_cast<GLint>(c.border);
8439 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
8440 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8441 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8442 const void* data = NULL;
8443 if (data_shm_id != 0 || data_shm_offset != 0) {
8444 data = GetSharedMemoryAs<const void*>(
8445 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:468446 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:148447 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198448 }
8449 }
[email protected]a93bb842010-02-16 23:03:478450 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:198451 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:198452}
8453
[email protected]b6140d02010-05-17 14:47:168454error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
vmiuracd108592014-09-08 14:36:348455 uint32 immediate_data_size,
8456 const void* cmd_data) {
8457 const gles2::cmds::CompressedTexImage2DBucket& c =
8458 *static_cast<const gles2::cmds::CompressedTexImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:168459 GLenum target = static_cast<GLenum>(c.target);
8460 GLint level = static_cast<GLint>(c.level);
8461 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8462 GLsizei width = static_cast<GLsizei>(c.width);
8463 GLsizei height = static_cast<GLsizei>(c.height);
8464 GLint border = static_cast<GLint>(c.border);
8465 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288466 if (!bucket) {
8467 return error::kInvalidArguments;
8468 }
8469 uint32 data_size = bucket->size();
8470 GLsizei imageSize = data_size;
8471 const void* data = bucket->GetData(0, data_size);
8472 if (!data) {
8473 return error::kInvalidArguments;
8474 }
[email protected]b6140d02010-05-17 14:47:168475 return DoCompressedTexImage2D(
8476 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:288477 imageSize, data);
[email protected]b6140d02010-05-17 14:47:168478}
8479
8480error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
8481 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:348482 const void* cmd_data) {
8483 const gles2::cmds::CompressedTexSubImage2DBucket& c =
8484 *static_cast<const gles2::cmds::CompressedTexSubImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:168485 GLenum target = static_cast<GLenum>(c.target);
8486 GLint level = static_cast<GLint>(c.level);
8487 GLint xoffset = static_cast<GLint>(c.xoffset);
8488 GLint yoffset = static_cast<GLint>(c.yoffset);
8489 GLsizei width = static_cast<GLsizei>(c.width);
8490 GLsizei height = static_cast<GLsizei>(c.height);
8491 GLenum format = static_cast<GLenum>(c.format);
8492 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288493 if (!bucket) {
8494 return error::kInvalidArguments;
8495 }
[email protected]b6140d02010-05-17 14:47:168496 uint32 data_size = bucket->size();
8497 GLsizei imageSize = data_size;
8498 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:288499 if (!data) {
8500 return error::kInvalidArguments;
8501 }
[email protected]9438b012010-06-15 22:55:058502 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518503 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:538504 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:168505 return error::kNoError;
8506 }
[email protected]9438b012010-06-15 22:55:058507 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518508 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8509 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:058510 return error::kNoError;
8511 }
[email protected]b6140d02010-05-17 14:47:168512 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518513 LOCAL_SET_GL_ERROR(
8514 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:168515 return error::kNoError;
8516 }
8517 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518518 LOCAL_SET_GL_ERROR(
8519 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:168520 return error::kNoError;
8521 }
8522 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:518523 LOCAL_SET_GL_ERROR(
8524 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:168525 return error::kNoError;
8526 }
[email protected]cadde4a2010-07-31 17:10:438527 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:168528 target, level, xoffset, yoffset, width, height, format, imageSize, data);
8529 return error::kNoError;
8530}
8531
vmiuracd108592014-09-08 14:36:348532error::Error GLES2DecoderImpl::HandleTexImage2D(uint32 immediate_data_size,
8533 const void* cmd_data) {
8534 const gles2::cmds::TexImage2D& c =
8535 *static_cast<const gles2::cmds::TexImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:138536 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D",
8537 "width", c.width, "height", c.height);
[email protected]c986af502013-08-14 01:04:448538 // Set as failed for now, but if it successed, this will be set to not failed.
8539 texture_state_.tex_image_2d_failed = true;
[email protected]b9849abf2009-11-25 19:13:198540 GLenum target = static_cast<GLenum>(c.target);
8541 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:448542 // TODO(kloveless): Change TexImage2D command to use unsigned integer
8543 // for internalformat.
8544 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:198545 GLsizei width = static_cast<GLsizei>(c.width);
8546 GLsizei height = static_cast<GLsizei>(c.height);
8547 GLint border = static_cast<GLint>(c.border);
8548 GLenum format = static_cast<GLenum>(c.format);
8549 GLenum type = static_cast<GLenum>(c.type);
8550 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
8551 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:188552 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:348553 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248554 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
[email protected]3458a64a2012-04-10 17:39:348555 NULL)) {
[email protected]a76b0052010-03-05 00:33:188556 return error::kOutOfBounds;
8557 }
[email protected]b9849abf2009-11-25 19:13:198558 const void* pixels = NULL;
8559 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
8560 pixels = GetSharedMemoryAs<const void*>(
8561 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:468562 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:148563 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198564 }
8565 }
[email protected]f598f422012-12-07 08:30:038566
[email protected]c986af502013-08-14 01:04:448567 TextureManager::DoTextImage2DArguments args = {
8568 target, level, internal_format, width, height, border, format, type,
8569 pixels, pixels_size};
8570 texture_manager()->ValidateAndDoTexImage2D(
8571 &texture_state_, &state_, &framebuffer_state_, args);
vmiura8266ca72014-09-09 21:37:008572
8573 // This may be a slow command. Exit command processing to allow for
8574 // context preemption and GPU watchdog checks.
8575 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:038576 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198577}
8578
[email protected]cadde4a2010-07-31 17:10:438579void GLES2DecoderImpl::DoCompressedTexSubImage2D(
8580 GLenum target,
8581 GLint level,
8582 GLint xoffset,
8583 GLint yoffset,
8584 GLsizei width,
8585 GLsizei height,
8586 GLenum format,
8587 GLsizei image_size,
8588 const void * data) {
[email protected]c986af502013-08-14 01:04:448589 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8590 &state_, target);
[email protected]370eaf12013-05-18 09:19:498591 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518592 LOCAL_SET_GL_ERROR(
8593 GL_INVALID_OPERATION,
8594 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438595 return;
8596 }
[email protected]370eaf12013-05-18 09:19:498597 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438598 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:528599 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078600 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518601 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528602 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438603 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:528604 return;
8605 }
8606 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:518607 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528608 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438609 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:528610 return;
8611 }
[email protected]02965c22013-03-09 02:40:078612 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528613 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518614 LOCAL_SET_GL_ERROR(
8615 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438616 return;
8617 }
[email protected]ad84a3a2012-06-08 21:42:438618
8619 if (!ValidateCompressedTexFuncData(
8620 "glCompressedTexSubImage2D", width, height, format, image_size) ||
8621 !ValidateCompressedTexSubDimensions(
8622 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:078623 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:438624 return;
8625 }
8626
8627
[email protected]0d6bfdc2011-11-02 01:32:208628 // Note: There is no need to deal with texture cleared tracking here
8629 // because the validation above means you can only get here if the level
8630 // is already a matching compressed format and in that case
8631 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:438632 glCompressedTexSubImage2D(
8633 target, level, xoffset, yoffset, width, height, format, image_size, data);
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]cadde4a2010-07-31 17:10:438638}
8639
[email protected]6e288612010-12-21 20:45:038640static void Clip(
8641 GLint start, GLint range, GLint sourceRange,
8642 GLint* out_start, GLint* out_range) {
8643 DCHECK(out_start);
8644 DCHECK(out_range);
8645 if (start < 0) {
8646 range += start;
8647 start = 0;
8648 }
8649 GLint end = start + range;
8650 if (end > sourceRange) {
8651 range -= end - sourceRange;
8652 }
8653 *out_start = start;
8654 *out_range = range;
8655}
8656
[email protected]cadde4a2010-07-31 17:10:438657void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:448658 GLenum target,
8659 GLint level,
8660 GLenum internal_format,
8661 GLint x,
8662 GLint y,
8663 GLsizei width,
8664 GLsizei height,
8665 GLint border) {
[email protected]09e17272012-11-30 10:30:448666 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:448667 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8668 &state_, target);
[email protected]370eaf12013-05-18 09:19:498669 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518670 LOCAL_SET_GL_ERROR(
8671 GL_INVALID_OPERATION,
8672 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438673 return;
8674 }
[email protected]370eaf12013-05-18 09:19:498675 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078676 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518677 LOCAL_SET_GL_ERROR(
8678 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]cedee332014-05-23 07:07:538679 return;
[email protected]97dc7cbe2011-12-06 17:26:178680 }
[email protected]80eb6b52012-01-19 00:14:418681 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:188682 border != 0) {
[email protected]ab09b612013-03-11 22:11:518683 LOCAL_SET_GL_ERROR(
8684 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:188685 return;
8686 }
[email protected]17a961192014-02-14 15:20:528687 if (!texture_manager()->ValidateFormatAndTypeCombination(
8688 state_.GetErrorState(), "glCopyTexImage2D", internal_format,
8689 GL_UNSIGNED_BYTE)) {
[email protected]81375742012-06-08 00:04:008690 return;
8691 }
[email protected]f5719fb2010-08-04 18:27:188692
[email protected]9edc6b22010-12-23 02:00:268693 // Check we have compatible formats.
8694 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8695 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8696 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
8697
8698 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518699 LOCAL_SET_GL_ERROR(
8700 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268701 return;
8702 }
8703
[email protected]81375742012-06-08 00:04:008704 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518705 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008706 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:268707 "glCopyTexImage2D", "can not be used with depth or stencil textures");
8708 return;
8709 }
8710
8711 uint32 estimated_size = 0;
8712 if (!GLES2Util::ComputeImageDataSizes(
8713 width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment,
8714 &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518715 LOCAL_SET_GL_ERROR(
8716 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:268717 return;
8718 }
8719
8720 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:518721 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:008722 return;
8723 }
8724
[email protected]2ea5950d2014-07-09 18:20:348725 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexImage2D")) {
8726 return;
8727 }
8728
[email protected]a0b78dc2011-11-11 10:43:108729 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
8730 return;
8731 }
8732
[email protected]ab09b612013-03-11 22:11:518733 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:278734 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038735 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:268736
[email protected]02965c22013-03-09 02:40:078737 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448738 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:468739 }
8740
[email protected]9edc6b22010-12-23 02:00:268741 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:038742 GLint copyX = 0;
8743 GLint copyY = 0;
8744 GLint copyWidth = 0;
8745 GLint copyHeight = 0;
8746 Clip(x, width, size.width(), &copyX, &copyWidth);
8747 Clip(y, height, size.height(), &copyY, &copyHeight);
8748
8749 if (copyX != x ||
8750 copyY != y ||
8751 copyWidth != width ||
8752 copyHeight != height) {
8753 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:208754 if (!ClearLevel(
[email protected]02965c22013-03-09 02:40:078755 texture->service_id(), texture->target(),
[email protected]d8e6c9242014-02-20 16:56:258756 target, level, internal_format, internal_format, GL_UNSIGNED_BYTE,
8757 width, height, texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:518758 LOCAL_SET_GL_ERROR(
8759 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:038760 return;
8761 }
[email protected]6e288612010-12-21 20:45:038762 if (copyHeight > 0 && copyWidth > 0) {
8763 GLint dx = copyX - x;
8764 GLint dy = copyY - y;
8765 GLint destX = dx;
8766 GLint destY = dy;
[email protected]00c2cf92014-03-14 00:08:378767 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038768 glCopyTexSubImage2D(target, level,
8769 destX, destY, copyX, copyY,
8770 copyWidth, copyHeight);
8771 }
8772 } else {
[email protected]00c2cf92014-03-14 00:08:378773 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038774 glCopyTexImage2D(target, level, internal_format,
8775 copyX, copyY, copyWidth, copyHeight, border);
8776 }
[email protected]ab09b612013-03-11 22:11:518777 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438778 if (error == GL_NO_ERROR) {
8779 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498780 texture_ref, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:208781 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:438782 }
vmiura8266ca72014-09-09 21:37:008783
8784 // This may be a slow command. Exit command processing to allow for
8785 // context preemption and GPU watchdog checks.
8786 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:438787}
8788
8789void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:448790 GLenum target,
8791 GLint level,
8792 GLint xoffset,
8793 GLint yoffset,
8794 GLint x,
8795 GLint y,
8796 GLsizei width,
8797 GLsizei height) {
[email protected]09e17272012-11-30 10:30:448798 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:448799 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8800 &state_, target);
[email protected]370eaf12013-05-18 09:19:498801 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518802 LOCAL_SET_GL_ERROR(
8803 GL_INVALID_OPERATION,
8804 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438805 return;
8806 }
[email protected]370eaf12013-05-18 09:19:498807 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438808 GLenum type = 0;
8809 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:078810 if (!texture->GetLevelType(target, level, &type, &format) ||
8811 !texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528812 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518813 LOCAL_SET_GL_ERROR(
8814 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438815 return;
8816 }
[email protected]85a4ac22013-05-31 01:58:478817 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518818 LOCAL_SET_GL_ERROR(
8819 GL_INVALID_OPERATION,
8820 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598821 return;
8822 }
[email protected]9edc6b22010-12-23 02:00:268823
8824 // Check we have compatible formats.
8825 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8826 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8827 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
8828
[email protected]2d3765b2012-10-03 00:31:078829 if (!channels_needed ||
8830 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518831 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438832 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268833 return;
8834 }
8835
[email protected]81375742012-06-08 00:04:008836 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518837 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008838 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438839 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:008840 return;
8841 }
8842
[email protected]2ea5950d2014-07-09 18:20:348843 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexSubImage2D")) {
8844 return;
8845 }
8846
[email protected]a0b78dc2011-11-11 10:43:108847 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
8848 return;
8849 }
8850
[email protected]de26b3c2011-08-03 21:54:278851 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038852 gfx::Size size = GetBoundReadFrameBufferSize();
8853 GLint copyX = 0;
8854 GLint copyY = 0;
8855 GLint copyWidth = 0;
8856 GLint copyHeight = 0;
8857 Clip(x, width, size.width(), &copyX, &copyWidth);
8858 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:208859
[email protected]370eaf12013-05-18 09:19:498860 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, level)) {
[email protected]ab09b612013-03-11 22:11:518861 LOCAL_SET_GL_ERROR(
8862 GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big");
[email protected]0d6bfdc2011-11-02 01:32:208863 return;
8864 }
8865
[email protected]6e288612010-12-21 20:45:038866 if (copyX != x ||
8867 copyY != y ||
8868 copyWidth != width ||
8869 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:208870 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:038871 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:348872 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248873 width, height, format, type, state_.unpack_alignment, &pixels_size,
8874 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518875 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438876 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:038877 return;
8878 }
[email protected]40d90a22013-04-09 03:39:558879 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:038880 memset(zero.get(), 0, pixels_size);
[email protected]00c2cf92014-03-14 00:08:378881 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038882 glTexSubImage2D(
8883 target, level, xoffset, yoffset, width, height,
8884 format, type, zero.get());
8885 }
[email protected]0d6bfdc2011-11-02 01:32:208886
[email protected]6e288612010-12-21 20:45:038887 if (copyHeight > 0 && copyWidth > 0) {
8888 GLint dx = copyX - x;
8889 GLint dy = copyY - y;
8890 GLint destX = xoffset + dx;
8891 GLint destY = yoffset + dy;
[email protected]00c2cf92014-03-14 00:08:378892 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038893 glCopyTexSubImage2D(target, level,
8894 destX, destY, copyX, copyY,
8895 copyWidth, copyHeight);
8896 }
vmiura8266ca72014-09-09 21:37:008897
8898 // This may be a slow command. Exit command processing to allow for
8899 // context preemption and GPU watchdog checks.
8900 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:438901}
8902
[email protected]f598f422012-12-07 08:30:038903bool GLES2DecoderImpl::ValidateTexSubImage2D(
8904 error::Error* error,
8905 const char* function_name,
8906 GLenum target,
8907 GLint level,
8908 GLint xoffset,
8909 GLint yoffset,
8910 GLsizei width,
8911 GLsizei height,
8912 GLenum format,
8913 GLenum type,
8914 const void * data) {
8915 (*error) = error::kNoError;
8916 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518917 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:038918 return false;
8919 }
8920 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518921 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:038922 return false;
8923 }
8924 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518925 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:038926 return false;
8927 }
[email protected]c986af502013-08-14 01:04:448928 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8929 &state_, target);
[email protected]370eaf12013-05-18 09:19:498930 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518931 LOCAL_SET_GL_ERROR(
8932 GL_INVALID_OPERATION,
8933 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:038934 return false;
[email protected]cadde4a2010-07-31 17:10:438935 }
[email protected]370eaf12013-05-18 09:19:498936 Texture* texture = texture_ref->texture();
[email protected]df6cf1ad2011-01-29 01:20:528937 GLenum current_type = 0;
8938 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078939 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518940 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:038941 GL_INVALID_OPERATION, function_name, "level does not exist.");
8942 return false;
[email protected]df6cf1ad2011-01-29 01:20:528943 }
[email protected]17a961192014-02-14 15:20:528944 if (!texture_manager()->ValidateTextureParameters(state_.GetErrorState(),
8945 function_name, format, type, internal_format, level)) {
[email protected]f598f422012-12-07 08:30:038946 return false;
[email protected]df6cf1ad2011-01-29 01:20:528947 }
8948 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:518949 LOCAL_SET_GL_ERROR(
8950 GL_INVALID_OPERATION,
8951 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:038952 return false;
[email protected]df6cf1ad2011-01-29 01:20:528953 }
[email protected]85a4ac22013-05-31 01:58:478954 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518955 LOCAL_SET_GL_ERROR(
8956 GL_INVALID_OPERATION,
8957 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598958 return false;
8959 }
[email protected]02965c22013-03-09 02:40:078960 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528961 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518962 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:038963 return false;
[email protected]cadde4a2010-07-31 17:10:438964 }
[email protected]81375742012-06-08 00:04:008965 if ((GLES2Util::GetChannelsForFormat(format) &
8966 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518967 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008968 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038969 function_name, "can not supply data for depth or stencil textures");
8970 return false;
[email protected]81375742012-06-08 00:04:008971 }
[email protected]f598f422012-12-07 08:30:038972 if (data == NULL) {
8973 (*error) = error::kOutOfBounds;
8974 return false;
8975 }
8976 return true;
8977}
[email protected]81375742012-06-08 00:04:008978
[email protected]f598f422012-12-07 08:30:038979error::Error GLES2DecoderImpl::DoTexSubImage2D(
8980 GLenum target,
8981 GLint level,
8982 GLint xoffset,
8983 GLint yoffset,
8984 GLsizei width,
8985 GLsizei height,
8986 GLenum format,
8987 GLenum type,
8988 const void * data) {
8989 error::Error error = error::kNoError;
8990 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
8991 xoffset, yoffset, width, height, format, type, data)) {
8992 return error;
8993 }
[email protected]c986af502013-08-14 01:04:448994 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8995 &state_, target);
[email protected]370eaf12013-05-18 09:19:498996 Texture* texture = texture_ref->texture();
[email protected]4502e6492011-12-14 19:39:158997 GLsizei tex_width = 0;
8998 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:078999 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:159000 DCHECK(ok);
9001 if (xoffset != 0 || yoffset != 0 ||
9002 width != tex_width || height != tex_height) {
[email protected]370eaf12013-05-18 09:19:499003 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
9004 target, level)) {
[email protected]ab09b612013-03-11 22:11:519005 LOCAL_SET_GL_ERROR(
9006 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:039007 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:309008 }
[email protected]c986af502013-08-14 01:04:449009 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:159010 glTexSubImage2D(
9011 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:039012 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:209013 }
[email protected]4502e6492011-12-14 19:39:159014
[email protected]345ba902013-11-14 21:39:009015 if (!texture_state_.texsubimage2d_faster_than_teximage2d &&
[email protected]c986af502013-08-14 01:04:449016 !texture->IsImmutable()) {
9017 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]d8e6c9242014-02-20 16:56:259018 GLenum internal_format;
9019 GLenum tex_type;
9020 texture->GetLevelType(target, level, &tex_type, &internal_format);
9021 // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need
9022 // to look it up.
[email protected]8f1d2aa2013-05-10 23:45:389023 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:259024 target, level, internal_format, width, height, 0, format, type, data);
[email protected]4502e6492011-12-14 19:39:159025 } else {
[email protected]c986af502013-08-14 01:04:449026 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:159027 glTexSubImage2D(
9028 target, level, xoffset, yoffset, width, height, format, type, data);
9029 }
[email protected]370eaf12013-05-18 09:19:499030 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
vmiura8266ca72014-09-09 21:37:009031
9032 // This may be a slow command. Exit command processing to allow for
9033 // context preemption and GPU watchdog checks.
9034 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:039035 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:439036}
9037
vmiuracd108592014-09-08 14:36:349038error::Error GLES2DecoderImpl::HandleTexSubImage2D(uint32 immediate_data_size,
9039 const void* cmd_data) {
9040 const gles2::cmds::TexSubImage2D& c =
9041 *static_cast<const gles2::cmds::TexSubImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:139042 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage2D",
9043 "width", c.width, "height", c.height);
[email protected]b493ee622011-04-13 23:52:009044 GLboolean internal = static_cast<GLboolean>(c.internal);
[email protected]c986af502013-08-14 01:04:449045 if (internal == GL_TRUE && texture_state_.tex_image_2d_failed)
[email protected]b493ee622011-04-13 23:52:009046 return error::kNoError;
9047
9048 GLenum target = static_cast<GLenum>(c.target);
9049 GLint level = static_cast<GLint>(c.level);
9050 GLint xoffset = static_cast<GLint>(c.xoffset);
9051 GLint yoffset = static_cast<GLint>(c.yoffset);
9052 GLsizei width = static_cast<GLsizei>(c.width);
9053 GLsizei height = static_cast<GLsizei>(c.height);
9054 GLenum format = static_cast<GLenum>(c.format);
9055 GLenum type = static_cast<GLenum>(c.type);
9056 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:349057 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:249058 width, height, format, type, state_.unpack_alignment, &data_size,
9059 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:009060 return error::kOutOfBounds;
9061 }
9062 const void* pixels = GetSharedMemoryAs<const void*>(
9063 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:039064 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:009065 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:009066}
9067
[email protected]f7a64ee2010-02-01 22:24:149068error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
vmiuracd108592014-09-08 14:36:349069 uint32 immediate_data_size,
9070 const void* cmd_data) {
9071 const gles2::cmds::GetVertexAttribPointerv& c =
9072 *static_cast<const gles2::cmds::GetVertexAttribPointerv*>(cmd_data);
[email protected]8bf5a3e2010-01-29 04:21:369073 GLuint index = static_cast<GLuint>(c.index);
9074 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:359075 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:259076 Result* result = GetSharedMemoryAs<Result*>(
9077 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:369078 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:149079 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:369080 }
[email protected]07d0cc82010-02-17 04:51:409081 // Check that the client initialized the result.
9082 if (result->size != 0) {
9083 return error::kInvalidArguments;
9084 }
[email protected]9438b012010-06-15 22:55:059085 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:519086 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9087 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:149088 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369089 }
[email protected]3916c97e2010-02-25 03:20:509090 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:519091 LOCAL_SET_GL_ERROR(
9092 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:149093 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369094 }
[email protected]0bfd9882010-02-05 23:02:259095 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:089096 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:359097 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:149098 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329099}
9100
[email protected]f7b85372010-02-03 01:11:379101bool GLES2DecoderImpl::GetUniformSetup(
[email protected]df37b9932013-03-08 05:21:429102 GLuint program_id, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:379103 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:129104 error::Error* error, GLint* real_location,
9105 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:109106 DCHECK(error);
9107 DCHECK(service_id);
9108 DCHECK(result_pointer);
9109 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:129110 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:379111 *error = error::kNoError;
9112 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:259113 SizedResult<GLint>* result;
9114 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9115 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
9116 if (!result) {
[email protected]f7b85372010-02-03 01:11:379117 *error = error::kOutOfBounds;
9118 return false;
9119 }
[email protected]0bfd9882010-02-05 23:02:259120 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:379121 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:259122 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:429123 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
9124 if (!program) {
[email protected]ae51d192010-04-27 00:48:039125 return false;
9126 }
[email protected]df37b9932013-03-08 05:21:429127 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:379128 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:519129 LOCAL_SET_GL_ERROR(
9130 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:379131 return false;
9132 }
[email protected]df37b9932013-03-08 05:21:429133 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:369134 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:359135 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:429136 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:129137 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:369138 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:379139 // No such location.
[email protected]ab09b612013-03-11 22:11:519140 LOCAL_SET_GL_ERROR(
9141 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:379142 return false;
9143 }
[email protected]43c2f1f2011-03-25 18:35:369144 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:509145 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:379146 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:519147 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:379148 return false;
9149 }
[email protected]0bfd9882010-02-05 23:02:259150 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9151 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
9152 if (!result) {
[email protected]f7b85372010-02-03 01:11:379153 *error = error::kOutOfBounds;
9154 return false;
9155 }
[email protected]0bfd9882010-02-05 23:02:259156 result->size = size;
[email protected]939e7362010-05-13 20:49:109157 *result_type = type;
[email protected]f7b85372010-02-03 01:11:379158 return true;
9159}
9160
vmiuracd108592014-09-08 14:36:349161error::Error GLES2DecoderImpl::HandleGetUniformiv(uint32 immediate_data_size,
9162 const void* cmd_data) {
9163 const gles2::cmds::GetUniformiv& c =
9164 *static_cast<const gles2::cmds::GetUniformiv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379165 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339166 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379167 GLuint service_id;
[email protected]939e7362010-05-13 20:49:109168 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:129169 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379170 Error error;
[email protected]0bfd9882010-02-05 23:02:259171 void* result;
[email protected]f7b85372010-02-03 01:11:379172 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:129173 program, fake_location, c.params_shm_id, c.params_shm_offset,
9174 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:259175 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:129176 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:359177 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:379178 }
9179 return error;
[email protected]96449d2c2009-11-25 00:01:329180}
9181
vmiuracd108592014-09-08 14:36:349182error::Error GLES2DecoderImpl::HandleGetUniformfv(uint32 immediate_data_size,
9183 const void* cmd_data) {
9184 const gles2::cmds::GetUniformfv& c =
9185 *static_cast<const gles2::cmds::GetUniformfv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379186 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339187 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379188 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:129189 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379190 Error error;
[email protected]ed9f9cd2013-02-27 21:12:359191 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:109192 Result* result;
9193 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:379194 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:129195 program, fake_location, c.params_shm_id, c.params_shm_offset,
9196 &error, &real_location, &service_id,
9197 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:109198 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
9199 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
9200 GLsizei num_values = result->GetNumResults();
[email protected]40d90a22013-04-09 03:39:559201 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:129202 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:109203 GLfloat* dst = result->GetData();
9204 for (GLsizei ii = 0; ii < num_values; ++ii) {
9205 dst[ii] = (temp[ii] != 0);
9206 }
9207 } else {
[email protected]1b0a6752012-02-22 03:44:129208 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:109209 }
[email protected]f7b85372010-02-03 01:11:379210 }
9211 return error;
[email protected]96449d2c2009-11-25 00:01:329212}
9213
[email protected]f7a64ee2010-02-01 22:24:149214error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
vmiuracd108592014-09-08 14:36:349215 uint32 immediate_data_size,
9216 const void* cmd_data) {
9217 const gles2::cmds::GetShaderPrecisionFormat& c =
9218 *static_cast<const gles2::cmds::GetShaderPrecisionFormat*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259219 GLenum shader_type = static_cast<GLenum>(c.shadertype);
9220 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:359221 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:259222 Result* result = GetSharedMemoryAs<Result*>(
9223 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9224 if (!result) {
9225 return error::kOutOfBounds;
9226 }
[email protected]07d0cc82010-02-17 04:51:409227 // Check that the client initialized the result.
9228 if (result->success != 0) {
9229 return error::kInvalidArguments;
9230 }
[email protected]9438b012010-06-15 22:55:059231 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:519232 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539233 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:299234 return error::kNoError;
9235 }
[email protected]9438b012010-06-15 22:55:059236 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:519237 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539238 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:299239 return error::kNoError;
9240 }
9241
9242 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:409243
[email protected]46c86752013-05-21 05:08:399244 GLint range[2] = { 0, 0 };
[email protected]d8bc3ec2013-03-07 06:28:409245 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:219246 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:409247
9248 result->min_range = range[0];
9249 result->max_range = range[1];
9250 result->precision = precision;
9251
[email protected]f7a64ee2010-02-01 22:24:149252 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329253}
9254
[email protected]f7a64ee2010-02-01 22:24:149255error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
vmiuracd108592014-09-08 14:36:349256 uint32 immediate_data_size,
9257 const void* cmd_data) {
9258 const gles2::cmds::GetAttachedShaders& c =
9259 *static_cast<const gles2::cmds::GetAttachedShaders*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259260 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:429261 GLuint program_id = static_cast<GLuint>(c.program);
9262 Program* program = GetProgramInfoNotShader(
9263 program_id, "glGetAttachedShaders");
9264 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259265 return error::kNoError;
9266 }
[email protected]ed9f9cd2013-02-27 21:12:359267 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:259268 uint32 max_count = Result::ComputeMaxResults(result_size);
9269 Result* result = GetSharedMemoryAs<Result*>(
9270 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
9271 if (!result) {
9272 return error::kOutOfBounds;
9273 }
[email protected]07d0cc82010-02-17 04:51:409274 // Check that the client initialized the result.
9275 if (result->size != 0) {
9276 return error::kInvalidArguments;
9277 }
[email protected]0bfd9882010-02-05 23:02:259278 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:039279 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:429280 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:259281 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:039282 if (!shader_manager()->GetClientId(result->GetData()[ii],
9283 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:259284 NOTREACHED();
9285 return error::kGenericError;
9286 }
9287 }
9288 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:149289 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329290}
9291
[email protected]f7a64ee2010-02-01 22:24:149292error::Error GLES2DecoderImpl::HandleGetActiveUniform(
vmiuracd108592014-09-08 14:36:349293 uint32 immediate_data_size,
9294 const void* cmd_data) {
9295 const gles2::cmds::GetActiveUniform& c =
9296 *static_cast<const gles2::cmds::GetActiveUniform*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429297 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:259298 GLuint index = c.index;
9299 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:359300 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:259301 Result* result = GetSharedMemoryAs<Result*>(
9302 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9303 if (!result) {
9304 return error::kOutOfBounds;
9305 }
[email protected]07d0cc82010-02-17 04:51:409306 // Check that the client initialized the result.
9307 if (result->success != 0) {
9308 return error::kInvalidArguments;
9309 }
[email protected]df37b9932013-03-08 05:21:429310 Program* program = GetProgramInfoNotShader(
9311 program_id, "glGetActiveUniform");
9312 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259313 return error::kNoError;
9314 }
[email protected]ed9f9cd2013-02-27 21:12:359315 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:429316 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:259317 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:519318 LOCAL_SET_GL_ERROR(
9319 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:259320 return error::kNoError;
9321 }
9322 result->success = 1; // true.
9323 result->size = uniform_info->size;
9324 result->type = uniform_info->type;
9325 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:299326 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:149327 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329328}
9329
vmiuracd108592014-09-08 14:36:349330error::Error GLES2DecoderImpl::HandleGetActiveAttrib(uint32 immediate_data_size,
9331 const void* cmd_data) {
9332 const gles2::cmds::GetActiveAttrib& c =
9333 *static_cast<const gles2::cmds::GetActiveAttrib*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429334 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:259335 GLuint index = c.index;
9336 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:359337 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:259338 Result* result = GetSharedMemoryAs<Result*>(
9339 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9340 if (!result) {
9341 return error::kOutOfBounds;
9342 }
[email protected]07d0cc82010-02-17 04:51:409343 // Check that the client initialized the result.
9344 if (result->success != 0) {
9345 return error::kInvalidArguments;
9346 }
[email protected]df37b9932013-03-08 05:21:429347 Program* program = GetProgramInfoNotShader(
9348 program_id, "glGetActiveAttrib");
9349 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259350 return error::kNoError;
9351 }
[email protected]ed9f9cd2013-02-27 21:12:359352 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:429353 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:259354 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:519355 LOCAL_SET_GL_ERROR(
9356 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:259357 return error::kNoError;
9358 }
9359 result->success = 1; // true.
9360 result->size = attrib_info->size;
9361 result->type = attrib_info->type;
9362 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:299363 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:149364 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329365}
9366
vmiuracd108592014-09-08 14:36:349367error::Error GLES2DecoderImpl::HandleShaderBinary(uint32 immediate_data_size,
9368 const void* cmd_data) {
[email protected]b273e432010-04-12 17:23:589369#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:519370 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:589371 return error::kNoError;
9372#else
9373 GLsizei n = static_cast<GLsizei>(c.n);
9374 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:519375 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:589376 return error::kNoError;
9377 }
9378 GLsizei length = static_cast<GLsizei>(c.length);
9379 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:519380 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:589381 return error::kNoError;
9382 }
9383 uint32 data_size;
9384 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
9385 return error::kOutOfBounds;
9386 }
9387 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
9388 c.shaders_shm_id, c.shaders_shm_offset, data_size);
9389 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
9390 const void* binary = GetSharedMemoryAs<const void*>(
9391 c.binary_shm_id, c.binary_shm_offset, length);
9392 if (shaders == NULL || binary == NULL) {
9393 return error::kOutOfBounds;
9394 }
[email protected]0782b14b2014-05-24 13:04:169395 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]b273e432010-04-12 17:23:589396 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:429397 Shader* shader = GetShader(shaders[ii]);
9398 if (!shader) {
[email protected]ab09b612013-03-11 22:11:519399 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:589400 return error::kNoError;
9401 }
[email protected]df37b9932013-03-08 05:21:429402 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:589403 }
9404 // TODO(gman): call glShaderBinary
9405 return error::kNoError;
9406#endif
9407}
9408
[email protected]6d792ee12013-05-15 00:40:569409void GLES2DecoderImpl::DoSwapBuffers() {
[email protected]64ace852011-05-19 21:49:499410 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:089411
[email protected]64ace852011-05-19 21:49:499412 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:429413 // TRACE_EVENT for gpu tests:
9414 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:429415 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:429416 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
9417 "width", (is_offscreen ? offscreen_size_.width() :
9418 surface_->GetSize().width()));
[email protected]6d792ee12013-05-15 00:40:569419 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
[email protected]64ace852011-05-19 21:49:499420 "offscreen", is_offscreen,
9421 "frame", this_frame_number);
[email protected]b2e92592014-01-10 15:47:159422 {
[email protected]a36ed4832014-04-24 16:40:279423 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
[email protected]b2e92592014-01-10 15:47:159424 }
9425
[email protected]8f9b8dd2013-09-12 18:05:139426 bool is_tracing;
9427 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
9428 &is_tracing);
9429 if (is_tracing) {
9430 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
9431 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
9432 is_offscreen ? offscreen_size_ : surface_->GetSize());
9433 }
9434
[email protected]6217d392010-03-25 22:08:359435 // If offscreen then don't actually SwapBuffers to the display. Just copy
9436 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:499437 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:319438 TRACE_EVENT2("gpu", "Offscreen",
9439 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:539440 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
9441 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
9442 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
9443 // fix this.
[email protected]62e155e2012-10-23 22:43:159444 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:539445 offscreen_saved_frame_buffer_->Create();
9446 glFinish();
9447 }
9448
9449 // Allocate the offscreen saved color texture.
9450 DCHECK(offscreen_saved_color_format_);
9451 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:099452 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:539453
9454 offscreen_saved_frame_buffer_->AttachRenderTexture(
9455 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:059456 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
9457 if (offscreen_saved_frame_buffer_->CheckStatus() !=
9458 GL_FRAMEBUFFER_COMPLETE) {
9459 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
9460 << "because offscreen saved FBO was incomplete.";
[email protected]6d792ee12013-05-15 00:40:569461 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
9462 return;
[email protected]f0cfe752013-01-14 01:09:059463 }
[email protected]1fb8c482011-08-31 01:01:539464
[email protected]f0cfe752013-01-14 01:09:059465 // Clear the offscreen color texture.
9466 // TODO(piman): Is this still necessary?
9467 {
9468 ScopedFrameBufferBinder binder(this,
9469 offscreen_saved_frame_buffer_->id());
9470 glClearColor(0, 0, 0, 0);
[email protected]454157e2014-05-03 02:49:459471 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
9472 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f0cfe752013-01-14 01:09:059473 glClear(GL_COLOR_BUFFER_BIT);
9474 RestoreClearState();
9475 }
[email protected]1fb8c482011-08-31 01:01:539476 }
9477
9478 UpdateParentTextureInfo();
9479 }
9480
[email protected]f0cfe752013-01-14 01:09:059481 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
[email protected]6d792ee12013-05-15 00:40:569482 return;
[email protected]ab09b612013-03-11 22:11:519483 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:309484 "GLES2DecoderImpl::DoSwapBuffers", GetErrorState());
[email protected]6217d392010-03-25 22:08:359485
[email protected]34ff8b0c2010-10-01 20:06:029486 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:139487 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:279488 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]b86b14982010-10-11 18:45:489489 } else {
[email protected]069944672012-04-25 20:52:239490 ScopedFrameBufferBinder binder(this,
9491 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:139492
[email protected]069944672012-04-25 20:52:239493 if (offscreen_target_buffer_preserved_) {
9494 // Copy the target frame buffer to the saved offscreen texture.
9495 offscreen_saved_color_texture_->Copy(
9496 offscreen_saved_color_texture_->size(),
9497 offscreen_saved_color_format_);
9498 } else {
9499 // Flip the textures in the parent context via the texture manager.
9500 if (!!offscreen_saved_color_texture_info_.get())
[email protected]370eaf12013-05-18 09:19:499501 offscreen_saved_color_texture_info_->texture()->
[email protected]069944672012-04-25 20:52:239502 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:569503
[email protected]069944672012-04-25 20:52:239504 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
9505 offscreen_target_frame_buffer_->AttachRenderTexture(
9506 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:489507 }
[email protected]069944672012-04-25 20:52:239508
9509 // Ensure the side effects of the copy are visible to the parent
9510 // context. There is no need to do this for ANGLE because it uses a
9511 // single D3D device for all contexts.
[email protected]f42f05b2013-11-15 21:46:189512 if (!feature_info_->feature_flags().is_angle)
[email protected]069944672012-04-25 20:52:239513 glFlush();
[email protected]0c8c9d22010-06-25 17:36:399514 }
[email protected]6217d392010-03-25 22:08:359515 } else {
[email protected]f62a5ab2011-05-23 20:34:159516 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:019517 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]6d792ee12013-05-15 00:40:569518 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]d0498742010-09-20 20:27:019519 }
[email protected]6217d392010-03-25 22:08:359520 }
vmiura8266ca72014-09-09 21:37:009521
9522 // This may be a slow command. Exit command processing to allow for
9523 // context preemption and GPU watchdog checks.
9524 ExitCommandProcessingEarly();
[email protected]6217d392010-03-25 22:08:359525}
9526
[email protected]d4239852011-08-12 04:51:229527error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
vmiuracd108592014-09-08 14:36:349528 uint32 immediate_data_size,
9529 const void* cmd_data) {
9530 const gles2::cmds::EnableFeatureCHROMIUM& c =
9531 *static_cast<const gles2::cmds::EnableFeatureCHROMIUM*>(cmd_data);
[email protected]b1d2dcb2010-05-17 19:24:189532 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289533 if (!bucket || bucket->size() == 0) {
9534 return error::kInvalidArguments;
9535 }
[email protected]ed9f9cd2013-02-27 21:12:359536 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:189537 Result* result = GetSharedMemoryAs<Result*>(
9538 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9539 if (!result) {
9540 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:109541 }
[email protected]b1d2dcb2010-05-17 19:24:189542 // Check that the client initialized the result.
9543 if (*result != 0) {
9544 return error::kInvalidArguments;
9545 }
9546 std::string feature_str;
9547 if (!bucket->GetAsString(&feature_str)) {
9548 return error::kInvalidArguments;
9549 }
9550
9551 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:229552 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:189553 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:229554 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
[email protected]8fbedc02010-11-18 18:43:409555 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
9556 // TODO(gman): decide how to remove the need for this const_cast.
9557 // I could make validators_ non const but that seems bad as this is the only
9558 // place it is needed. I could make some special friend class of validators
9559 // just to allow this to set them. That seems silly. I could refactor this
9560 // code to use the extension mechanism or the initialization attributes to
9561 // turn this feature on. Given that the only real point of this is to make
9562 // the conformance tests pass and given that there is lots of real work that
9563 // needs to be done it seems like refactoring for one to one of those
9564 // methods is a very low priority.
9565 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:049566 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
9567 force_webgl_glsl_validation_ = true;
9568 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:189569 } else {
9570 return error::kNoError;
9571 }
9572
9573 *result = 1; // true.
9574 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:109575}
9576
[email protected]c2f8c8402010-12-06 18:07:249577error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
9578 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:349579 const void* cmd_data) {
9580 const gles2::cmds::GetRequestableExtensionsCHROMIUM& c =
9581 *static_cast<const gles2::cmds::GetRequestableExtensionsCHROMIUM*>(
9582 cmd_data);
[email protected]c2f8c8402010-12-06 18:07:249583 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:359584 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]956aec52013-09-05 15:41:199585 info->Initialize(disallowed_features_);
[email protected]c2f8c8402010-12-06 18:07:249586 bucket->SetFromString(info->extensions().c_str());
9587 return error::kNoError;
9588}
9589
9590error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
vmiuracd108592014-09-08 14:36:349591 uint32 immediate_data_size,
9592 const void* cmd_data) {
9593 const gles2::cmds::RequestExtensionCHROMIUM& c =
9594 *static_cast<const gles2::cmds::RequestExtensionCHROMIUM*>(cmd_data);
[email protected]c2f8c8402010-12-06 18:07:249595 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289596 if (!bucket || bucket->size() == 0) {
9597 return error::kInvalidArguments;
9598 }
[email protected]c2f8c8402010-12-06 18:07:249599 std::string feature_str;
9600 if (!bucket->GetAsString(&feature_str)) {
9601 return error::kInvalidArguments;
9602 }
9603
[email protected]4b7eba92013-01-08 02:23:569604 bool desire_webgl_glsl_validation =
9605 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
9606 bool desire_standard_derivatives = false;
[email protected]70dc60932013-06-04 03:33:499607 bool desire_frag_depth = false;
[email protected]aff39ac82013-06-08 04:53:139608 bool desire_draw_buffers = false;
[email protected]93c2fd82014-04-16 02:46:069609 bool desire_shader_texture_lod = false;
[email protected]4b7eba92013-01-08 02:23:569610 if (force_webgl_glsl_validation_) {
9611 desire_standard_derivatives =
9612 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]70dc60932013-06-04 03:33:499613 desire_frag_depth =
9614 feature_str.find("GL_EXT_frag_depth") != std::string::npos;
[email protected]aff39ac82013-06-08 04:53:139615 desire_draw_buffers =
9616 feature_str.find("GL_EXT_draw_buffers") != std::string::npos;
[email protected]93c2fd82014-04-16 02:46:069617 desire_shader_texture_lod =
9618 feature_str.find("GL_EXT_shader_texture_lod") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:049619 }
9620
[email protected]4b7eba92013-01-08 02:23:569621 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
[email protected]70dc60932013-06-04 03:33:499622 desire_standard_derivatives != derivatives_explicitly_enabled_ ||
[email protected]aff39ac82013-06-08 04:53:139623 desire_frag_depth != frag_depth_explicitly_enabled_ ||
9624 desire_draw_buffers != draw_buffers_explicitly_enabled_) {
[email protected]70dc60932013-06-04 03:33:499625 force_webgl_glsl_validation_ |= desire_webgl_glsl_validation;
9626 derivatives_explicitly_enabled_ |= desire_standard_derivatives;
9627 frag_depth_explicitly_enabled_ |= desire_frag_depth;
[email protected]aff39ac82013-06-08 04:53:139628 draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
[email protected]93c2fd82014-04-16 02:46:069629 shader_texture_lod_explicitly_enabled_ |= desire_shader_texture_lod;
[email protected]c2f8c8402010-12-06 18:07:249630 InitializeShaderTranslator();
9631 }
9632
[email protected]302ce6d2011-07-07 23:28:119633 UpdateCapabilities();
9634
[email protected]c2f8c8402010-12-06 18:07:249635 return error::kNoError;
9636}
9637
[email protected]372e0412011-06-28 16:08:569638error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
vmiuracd108592014-09-08 14:36:349639 uint32 immediate_data_size,
9640 const void* cmd_data) {
9641 const gles2::cmds::GetMultipleIntegervCHROMIUM& c =
9642 *static_cast<const gles2::cmds::GetMultipleIntegervCHROMIUM*>(cmd_data);
[email protected]372e0412011-06-28 16:08:569643 GLuint count = c.count;
9644 uint32 pnames_size;
9645 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
9646 return error::kOutOfBounds;
9647 }
9648 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>(
9649 c.pnames_shm_id, c.pnames_shm_offset, pnames_size);
9650 if (pnames == NULL) {
9651 return error::kOutOfBounds;
9652 }
9653
9654 // We have to copy them since we use them twice so the client
9655 // can't change them between the time we validate them and the time we use
9656 // them.
[email protected]40d90a22013-04-09 03:39:559657 scoped_ptr<GLenum[]> enums(new GLenum[count]);
[email protected]372e0412011-06-28 16:08:569658 memcpy(enums.get(), pnames, pnames_size);
9659
9660 // Count up the space needed for the result.
9661 uint32 num_results = 0;
9662 for (GLuint ii = 0; ii < count; ++ii) {
9663 uint32 num = util_.GLGetNumValuesReturned(enums[ii]);
9664 if (num == 0) {
[email protected]ab09b612013-03-11 22:11:519665 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]caa13ed2014-02-17 11:29:209666 "glGetMultipleCHROMIUM", enums[ii], "pname");
[email protected]372e0412011-06-28 16:08:569667 return error::kNoError;
9668 }
9669 // Num will never be more than 4.
9670 DCHECK_LE(num, 4u);
[email protected]3aad1a32012-09-07 20:54:479671 if (!SafeAddUint32(num_results, num, &num_results)) {
[email protected]372e0412011-06-28 16:08:569672 return error::kOutOfBounds;
9673 }
9674 }
9675
9676 uint32 result_size = 0;
9677 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) {
9678 return error::kOutOfBounds;
9679 }
9680
9681 if (result_size != static_cast<uint32>(c.size)) {
[email protected]ab09b612013-03-11 22:11:519682 LOCAL_SET_GL_ERROR(
9683 GL_INVALID_VALUE,
[email protected]caa13ed2014-02-17 11:29:209684 "glGetMultipleCHROMIUM", "bad size GL_INVALID_VALUE");
[email protected]372e0412011-06-28 16:08:569685 return error::kNoError;
9686 }
9687
9688 GLint* results = GetSharedMemoryAs<GLint*>(
9689 c.results_shm_id, c.results_shm_offset, result_size);
9690 if (results == NULL) {
9691 return error::kOutOfBounds;
9692 }
9693
9694 // Check the results have been cleared in case the context was lost.
9695 for (uint32 ii = 0; ii < num_results; ++ii) {
9696 if (results[ii]) {
9697 return error::kInvalidArguments;
9698 }
9699 }
9700
9701 // Get each result.
9702 GLint* start = results;
9703 for (GLuint ii = 0; ii < count; ++ii) {
9704 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:269705 if (!state_.GetStateAsGLint(enums[ii], results, &num_written) &&
[email protected]f63b1232012-10-31 07:03:539706 !GetHelper(enums[ii], results, &num_written)) {
[email protected]b0ce0982013-05-13 18:51:489707 DoGetIntegerv(enums[ii], results);
[email protected]372e0412011-06-28 16:08:569708 }
9709 results += num_written;
9710 }
9711
9712 // Just to verify. Should this be a DCHECK?
9713 if (static_cast<uint32>(results - start) != num_results) {
9714 return error::kOutOfBounds;
9715 }
9716
9717 return error::kNoError;
9718}
9719
[email protected]2318d342011-07-11 22:27:429720error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
vmiuracd108592014-09-08 14:36:349721 uint32 immediate_data_size,
9722 const void* cmd_data) {
9723 const gles2::cmds::GetProgramInfoCHROMIUM& c =
9724 *static_cast<const gles2::cmds::GetProgramInfoCHROMIUM*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429725 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:429726 uint32 bucket_id = c.bucket_id;
9727 Bucket* bucket = CreateBucket(bucket_id);
9728 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:429729 Program* program = NULL;
9730 program = GetProgram(program_id);
9731 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:469732 return error::kNoError;
[email protected]2318d342011-07-11 22:27:429733 }
[email protected]df37b9932013-03-08 05:21:429734 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:429735 return error::kNoError;
9736}
9737
[email protected]38d139d2011-07-14 00:38:439738error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
9739 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:439740 case GL_NO_ERROR:
9741 // TODO(kbr): improve the precision of the error code in this case.
9742 // Consider delegating to context for error code if MakeCurrent fails.
9743 return error::kUnknown;
9744 case GL_GUILTY_CONTEXT_RESET_ARB:
9745 return error::kGuilty;
9746 case GL_INNOCENT_CONTEXT_RESET_ARB:
9747 return error::kInnocent;
9748 case GL_UNKNOWN_CONTEXT_RESET_ARB:
9749 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:439750 }
9751
9752 NOTREACHED();
9753 return error::kUnknown;
9754}
9755
9756bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:099757 if (reset_status_ != GL_NO_ERROR) {
9758 return true;
9759 }
[email protected]706b69f2012-07-27 04:59:309760 if (context_->WasAllocatedUsingRobustnessExtension()) {
9761 GLenum status = GL_NO_ERROR;
9762 if (has_robustness_extension_)
9763 status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:439764 if (status != GL_NO_ERROR) {
9765 // The graphics card was reset. Signal a lost context to the application.
9766 reset_status_ = status;
[email protected]93a7d98f2013-07-11 00:04:229767 reset_by_robustness_extension_ = true;
[email protected]38d139d2011-07-14 00:38:439768 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:099769 << " context lost via ARB/EXT_robustness. Reset status = "
9770 << GLES2Util::GetStringEnum(status);
[email protected]38d139d2011-07-14 00:38:439771 return true;
9772 }
9773 }
9774 return false;
9775}
9776
[email protected]93a7d98f2013-07-11 00:04:229777bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() {
9778 return WasContextLost() && reset_by_robustness_extension_;
9779}
9780
[email protected]c4485aad62012-12-17 10:19:099781void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
9782 // Only loses the context once.
9783 if (reset_status_ != GL_NO_ERROR) {
9784 return;
9785 }
9786
9787 // Marks this context as lost.
9788 reset_status_ = reset_status;
9789 current_decoder_error_ = error::kLostContext;
[email protected]c4485aad62012-12-17 10:19:099790}
9791
[email protected]b096d032013-03-08 03:08:019792error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:349793 uint32 immediate_data_size,
9794 const void* cmd_data) {
[email protected]b096d032013-03-08 03:08:019795 return error::kUnknownCommand;
9796}
9797
[email protected]840a7e462013-02-27 01:29:519798error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:349799 uint32 immediate_data_size,
9800 const void* cmd_data) {
9801 const gles2::cmds::WaitSyncPointCHROMIUM& c =
9802 *static_cast<const gles2::cmds::WaitSyncPointCHROMIUM*>(cmd_data);
[email protected]00c2cf92014-03-14 00:08:379803 group_->mailbox_manager()->PullTextureUpdates();
[email protected]840a7e462013-02-27 01:29:519804 if (wait_sync_point_callback_.is_null())
9805 return error::kNoError;
9806
9807 return wait_sync_point_callback_.Run(c.sync_point) ?
9808 error::kNoError : error::kDeferCommandUntilLater;
9809}
9810
[email protected]5dfc457b2013-12-13 11:13:079811error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM(
vmiuracd108592014-09-08 14:36:349812 uint32 immediate_data_size,
9813 const void* cmd_data) {
[email protected]5dfc457b2013-12-13 11:13:079814 if (surface_->DeferDraws())
9815 return error::kDeferCommandUntilLater;
9816 if (!surface_->SetBackbufferAllocation(false))
9817 return error::kLostContext;
9818 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
9819 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
9820 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
9821 return error::kNoError;
9822}
9823
[email protected]882ba1e22012-03-08 19:02:539824bool GLES2DecoderImpl::GenQueriesEXTHelper(
9825 GLsizei n, const GLuint* client_ids) {
9826 for (GLsizei ii = 0; ii < n; ++ii) {
9827 if (query_manager_->GetQuery(client_ids[ii])) {
9828 return false;
9829 }
9830 }
[email protected]4eea7e62014-04-22 21:14:439831 query_manager_->GenQueries(n, client_ids);
[email protected]882ba1e22012-03-08 19:02:539832 return true;
9833}
9834
9835void GLES2DecoderImpl::DeleteQueriesEXTHelper(
9836 GLsizei n, const GLuint* client_ids) {
9837 for (GLsizei ii = 0; ii < n; ++ii) {
9838 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
9839 if (query && !query->IsDeleted()) {
[email protected]8ebd46c2014-01-08 12:06:139840 ContextState::QueryMap::iterator it =
9841 state_.current_queries.find(query->target());
9842 if (it != state_.current_queries.end())
9843 state_.current_queries.erase(it);
9844
[email protected]c45f1972012-03-14 07:27:369845 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:539846 }
[email protected]4eea7e62014-04-22 21:14:439847 query_manager_->RemoveQuery(client_ids[ii]);
[email protected]882ba1e22012-03-08 19:02:539848 }
9849}
9850
[email protected]22e3f552012-03-13 01:54:199851bool GLES2DecoderImpl::ProcessPendingQueries() {
9852 if (query_manager_.get() == NULL) {
9853 return false;
9854 }
[email protected]c45f1972012-03-14 07:27:369855 if (!query_manager_->ProcessPendingQueries()) {
[email protected]22e3f552012-03-13 01:54:199856 current_decoder_error_ = error::kOutOfBounds;
9857 }
9858 return query_manager_->HavePendingQueries();
9859}
9860
[email protected]5a36dc132013-07-23 23:17:559861// Note that if there are no pending readpixels right now,
9862// this function will call the callback immediately.
9863void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) {
9864 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) {
9865 pending_readpixel_fences_.back()->callbacks.push_back(callback);
9866 } else {
9867 callback.Run();
9868 }
9869}
9870
9871void GLES2DecoderImpl::ProcessPendingReadPixels() {
9872 while (!pending_readpixel_fences_.empty() &&
9873 pending_readpixel_fences_.front()->fence->HasCompleted()) {
9874 std::vector<base::Closure> callbacks =
9875 pending_readpixel_fences_.front()->callbacks;
9876 pending_readpixel_fences_.pop();
9877 for (size_t i = 0; i < callbacks.size(); i++) {
9878 callbacks[i].Run();
9879 }
9880 }
9881}
9882
[email protected]2b1767cf2013-03-16 09:25:059883bool GLES2DecoderImpl::HasMoreIdleWork() {
[email protected]5a36dc132013-07-23 23:17:559884 return !pending_readpixel_fences_.empty() ||
9885 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059886}
9887
9888void GLES2DecoderImpl::PerformIdleWork() {
[email protected]5a36dc132013-07-23 23:17:559889 ProcessPendingReadPixels();
[email protected]b68b100752013-06-05 08:34:489890 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
[email protected]2b1767cf2013-03-16 09:25:059891 return;
[email protected]b68b100752013-06-05 08:34:489892 async_pixel_transfer_manager_->ProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059893 ProcessFinishedAsyncTransfers();
9894}
9895
vmiuracd108592014-09-08 14:36:349896error::Error GLES2DecoderImpl::HandleBeginQueryEXT(uint32 immediate_data_size,
9897 const void* cmd_data) {
9898 const gles2::cmds::BeginQueryEXT& c =
9899 *static_cast<const gles2::cmds::BeginQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:539900 GLenum target = static_cast<GLenum>(c.target);
9901 GLuint client_id = static_cast<GLuint>(c.id);
9902 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
9903 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
9904
[email protected]c45f1972012-03-14 07:27:369905 switch (target) {
9906 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:559907 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]5537605d2013-08-27 05:22:319908 case GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM:
9909 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:009910 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:369911 break;
[email protected]6a25ae422014-04-17 23:48:279912 case GL_COMMANDS_COMPLETED_CHROMIUM:
9913 if (!features().chromium_sync_query) {
9914 LOCAL_SET_GL_ERROR(
9915 GL_INVALID_OPERATION, "glBeginQueryEXT",
9916 "not enabled for commands completed queries");
9917 return error::kNoError;
9918 }
9919 break;
[email protected]c45f1972012-03-14 07:27:369920 default:
[email protected]62e155e2012-10-23 22:43:159921 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:519922 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:009923 GL_INVALID_OPERATION, "glBeginQueryEXT",
9924 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:369925 return error::kNoError;
9926 }
9927 break;
[email protected]882ba1e22012-03-08 19:02:539928 }
9929
[email protected]8ebd46c2014-01-08 12:06:139930 if (state_.current_queries.find(target) != state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:519931 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439932 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:539933 return error::kNoError;
9934 }
9935
9936 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:519937 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:539938 return error::kNoError;
9939 }
9940
9941 QueryManager::Query* query = query_manager_->GetQuery(client_id);
9942 if (!query) {
[email protected]4eea7e62014-04-22 21:14:439943 if (!query_manager_->IsValidQuery(client_id)) {
9944 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
9945 "glBeginQueryEXT",
9946 "id not made by glGenQueriesEXT");
9947 return error::kNoError;
9948 }
[email protected]c45f1972012-03-14 07:27:369949 query = query_manager_->CreateQuery(
9950 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:539951 }
9952
[email protected]c45f1972012-03-14 07:27:369953 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:519954 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439955 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:539956 return error::kNoError;
9957 } else if (query->shm_id() != sync_shm_id ||
9958 query->shm_offset() != sync_shm_offset) {
9959 DLOG(ERROR) << "Shared memory used by query not the same as before";
9960 return error::kInvalidArguments;
9961 }
9962
[email protected]c45f1972012-03-14 07:27:369963 if (!query_manager_->BeginQuery(query)) {
9964 return error::kOutOfBounds;
9965 }
[email protected]882ba1e22012-03-08 19:02:539966
[email protected]8ebd46c2014-01-08 12:06:139967 state_.current_queries[target] = query;
[email protected]882ba1e22012-03-08 19:02:539968 return error::kNoError;
9969}
9970
vmiuracd108592014-09-08 14:36:349971error::Error GLES2DecoderImpl::HandleEndQueryEXT(uint32 immediate_data_size,
9972 const void* cmd_data) {
9973 const gles2::cmds::EndQueryEXT& c =
9974 *static_cast<const gles2::cmds::EndQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:539975 GLenum target = static_cast<GLenum>(c.target);
9976 uint32 submit_count = static_cast<GLuint>(c.submit_count);
[email protected]8ebd46c2014-01-08 12:06:139977 ContextState::QueryMap::iterator it = state_.current_queries.find(target);
[email protected]882ba1e22012-03-08 19:02:539978
[email protected]8ebd46c2014-01-08 12:06:139979 if (it == state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:519980 LOCAL_SET_GL_ERROR(
9981 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:539982 return error::kNoError;
9983 }
[email protected]882ba1e22012-03-08 19:02:539984
[email protected]8ebd46c2014-01-08 12:06:139985 QueryManager::Query* query = it->second.get();
9986 if (!query_manager_->EndQuery(query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:369987 return error::kOutOfBounds;
9988 }
9989
[email protected]fe8d73c2013-02-16 22:37:329990 query_manager_->ProcessPendingTransferQueries();
9991
[email protected]8ebd46c2014-01-08 12:06:139992 state_.current_queries.erase(it);
[email protected]882ba1e22012-03-08 19:02:539993 return error::kNoError;
9994}
9995
[email protected]944b62f32012-09-27 02:20:469996bool GLES2DecoderImpl::GenVertexArraysOESHelper(
9997 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469998 for (GLsizei ii = 0; ii < n; ++ii) {
9999 if (GetVertexAttribManager(client_ids[ii])) {
10000 return false;
10001 }
10002 }
[email protected]ab4fd7282012-10-12 16:25:5710003
[email protected]62e155e2012-10-23 22:43:1510004 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:5710005 // Emulated VAO
10006 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:4810007 CreateVertexAttribManager(client_ids[ii], 0, true);
[email protected]ab4fd7282012-10-12 16:25:5710008 }
10009 } else {
[email protected]40d90a22013-04-09 03:39:5510010 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:5710011
10012 glGenVertexArraysOES(n, service_ids.get());
10013 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:4810014 CreateVertexAttribManager(client_ids[ii], service_ids[ii], true);
[email protected]ab4fd7282012-10-12 16:25:5710015 }
[email protected]944b62f32012-09-27 02:20:4610016 }
[email protected]ab4fd7282012-10-12 16:25:5710017
[email protected]944b62f32012-09-27 02:20:4610018 return true;
10019}
10020
10021void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
10022 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:4610023 for (GLsizei ii = 0; ii < n; ++ii) {
10024 VertexAttribManager* vao =
10025 GetVertexAttribManager(client_ids[ii]);
10026 if (vao && !vao->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:1110027 if (state_.vertex_attrib_manager.get() == vao) {
[email protected]242c9822014-04-15 21:36:1110028 DoBindVertexArrayOES(0);
[email protected]944b62f32012-09-27 02:20:4610029 }
10030 RemoveVertexAttribManager(client_ids[ii]);
10031 }
10032 }
10033}
10034
10035void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:4610036 VertexAttribManager* vao = NULL;
[email protected]944b62f32012-09-27 02:20:4610037 if (client_id != 0) {
10038 vao = GetVertexAttribManager(client_id);
10039 if (!vao) {
10040 // Unlike most Bind* methods, the spec explicitly states that VertexArray
10041 // only allows names that have been previously generated. As such, we do
10042 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:5110043 LOCAL_SET_GL_ERROR(
10044 GL_INVALID_OPERATION,
10045 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:4610046 current_decoder_error_ = error::kNoError;
10047 return;
[email protected]944b62f32012-09-27 02:20:4610048 }
[email protected]944b62f32012-09-27 02:20:4610049 } else {
[email protected]81f20a622014-04-18 01:54:5210050 vao = state_.default_vertex_attrib_manager.get();
[email protected]944b62f32012-09-27 02:20:4610051 }
10052
[email protected]ab4fd7282012-10-12 16:25:5710053 // Only set the VAO state if it's changed
[email protected]7cd76fd2013-06-02 21:11:1110054 if (state_.vertex_attrib_manager.get() != vao) {
[email protected]e259eb412012-10-13 05:47:2410055 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:1510056 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:5710057 EmulateVertexArrayState();
10058 } else {
[email protected]da364812014-05-09 21:39:4810059 GLuint service_id = vao->service_id();
[email protected]ab4fd7282012-10-12 16:25:5710060 glBindVertexArrayOES(service_id);
10061 }
10062 }
10063}
10064
10065// Used when OES_vertex_array_object isn't natively supported
10066void GLES2DecoderImpl::EmulateVertexArrayState() {
10067 // Setup the Vertex attribute state
10068 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
[email protected]3fc38e22014-05-30 00:13:2310069 RestoreStateForAttrib(vv, true);
[email protected]ab4fd7282012-10-12 16:25:5710070 }
10071
10072 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:2110073 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:2410074 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:5710075 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
10076 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:4610077}
10078
10079bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:4610080 const VertexAttribManager* vao =
10081 GetVertexAttribManager(client_id);
10082 return vao && vao->IsValid() && !vao->IsDeleted();
10083}
10084
[email protected]e51bdf32011-11-23 22:21:4610085#if defined(OS_MACOSX)
10086void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
10087 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
10088 texture_id);
10089 if (it != texture_to_io_surface_map_.end()) {
10090 // Found a previous IOSurface bound to this texture; release it.
[email protected]c3a6b4a2014-06-04 09:25:5310091 IOSurfaceRef surface = it->second;
[email protected]e51bdf32011-11-23 22:21:4610092 CFRelease(surface);
10093 texture_to_io_surface_map_.erase(it);
10094 }
10095}
10096#endif
10097
10098void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
10099 GLenum target, GLsizei width, GLsizei height,
10100 GLuint io_surface_id, GLuint plane) {
10101#if defined(OS_MACOSX)
10102 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:5110103 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310104 GL_INVALID_OPERATION,
10105 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:4610106 return;
10107 }
10108
[email protected]e51bdf32011-11-23 22:21:4610109 if (target != GL_TEXTURE_RECTANGLE_ARB) {
10110 // This might be supported in the future, and if we could require
10111 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
10112 // could delete a lot of code. For now, perform strict validation so we
10113 // know what's going on.
[email protected]ab09b612013-03-11 22:11:5110114 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4610115 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310116 "glTexImageIOSurface2DCHROMIUM",
10117 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:4610118 return;
10119 }
10120
[email protected]09d50362012-10-18 20:54:3710121 // Default target might be conceptually valid, but disallow it to avoid
10122 // accidents.
[email protected]c986af502013-08-14 01:04:4410123 TextureRef* texture_ref =
10124 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910125 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110126 LOCAL_SET_GL_ERROR(
10127 GL_INVALID_OPERATION,
10128 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:4610129 return;
10130 }
[email protected]e51bdf32011-11-23 22:21:4610131
10132 // Look up the new IOSurface. Note that because of asynchrony
10133 // between processes this might fail; during live resizing the
10134 // plugin process might allocate and release an IOSurface before
10135 // this process gets a chance to look it up. Hold on to any old
10136 // IOSurface in this case.
[email protected]c3a6b4a2014-06-04 09:25:5310137 IOSurfaceRef surface = IOSurfaceLookup(io_surface_id);
[email protected]e51bdf32011-11-23 22:21:4610138 if (!surface) {
[email protected]ab09b612013-03-11 22:11:5110139 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310140 GL_INVALID_OPERATION,
10141 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:4610142 return;
10143 }
10144
10145 // Release any IOSurface previously bound to this texture.
[email protected]370eaf12013-05-18 09:19:4910146 ReleaseIOSurfaceForTexture(texture_ref->service_id());
[email protected]e51bdf32011-11-23 22:21:4610147
10148 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
10149 texture_to_io_surface_map_.insert(
[email protected]370eaf12013-05-18 09:19:4910150 std::make_pair(texture_ref->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:4610151
10152 CGLContextObj context =
10153 static_cast<CGLContextObj>(context_->GetHandle());
10154
[email protected]c3a6b4a2014-06-04 09:25:5310155 CGLError err = CGLTexImageIOSurface2D(
[email protected]e51bdf32011-11-23 22:21:4610156 context,
10157 target,
10158 GL_RGBA,
10159 width,
10160 height,
10161 GL_BGRA,
10162 GL_UNSIGNED_INT_8_8_8_8_REV,
10163 surface,
10164 plane);
10165
10166 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:5110167 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4610168 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310169 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:4610170 return;
10171 }
10172
10173 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910174 texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:4610175 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
10176
10177#else
[email protected]ab09b612013-03-11 22:11:5110178 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310179 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:4610180#endif
10181}
10182
[email protected]97dc7cbe2011-12-06 17:26:1710183static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
10184 switch (internalformat) {
10185 case GL_RGB565:
10186 return GL_RGB;
10187 case GL_RGBA4:
10188 return GL_RGBA;
10189 case GL_RGB5_A1:
10190 return GL_RGBA;
10191 case GL_RGB8_OES:
10192 return GL_RGB;
10193 case GL_RGBA8_OES:
10194 return GL_RGBA;
10195 case GL_LUMINANCE8_ALPHA8_EXT:
10196 return GL_LUMINANCE_ALPHA;
10197 case GL_LUMINANCE8_EXT:
10198 return GL_LUMINANCE;
10199 case GL_ALPHA8_EXT:
10200 return GL_ALPHA;
10201 case GL_RGBA32F_EXT:
10202 return GL_RGBA;
10203 case GL_RGB32F_EXT:
10204 return GL_RGB;
10205 case GL_ALPHA32F_EXT:
10206 return GL_ALPHA;
10207 case GL_LUMINANCE32F_EXT:
10208 return GL_LUMINANCE;
10209 case GL_LUMINANCE_ALPHA32F_EXT:
10210 return GL_LUMINANCE_ALPHA;
10211 case GL_RGBA16F_EXT:
10212 return GL_RGBA;
10213 case GL_RGB16F_EXT:
10214 return GL_RGB;
10215 case GL_ALPHA16F_EXT:
10216 return GL_ALPHA;
10217 case GL_LUMINANCE16F_EXT:
10218 return GL_LUMINANCE;
10219 case GL_LUMINANCE_ALPHA16F_EXT:
10220 return GL_LUMINANCE_ALPHA;
10221 case GL_BGRA8_EXT:
10222 return GL_BGRA_EXT;
10223 default:
10224 return GL_NONE;
10225 }
10226}
10227
[email protected]43410e92012-04-20 17:06:2810228void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:0310229 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
[email protected]a4a6bdd12013-04-19 20:46:5410230 GLenum internal_format, GLenum dest_type) {
[email protected]1e24dc7f2014-04-14 02:40:0810231 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM");
10232
[email protected]370eaf12013-05-18 09:19:4910233 TextureRef* dest_texture_ref = GetTexture(dest_id);
10234 TextureRef* source_texture_ref = GetTexture(source_id);
[email protected]43410e92012-04-20 17:06:2810235
[email protected]370eaf12013-05-18 09:19:4910236 if (!source_texture_ref || !dest_texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110237 LOCAL_SET_GL_ERROR(
10238 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:2810239 return;
10240 }
10241
10242 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110243 LOCAL_SET_GL_ERROR(
10244 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:2810245 return;
10246 }
10247
[email protected]370eaf12013-05-18 09:19:4910248 Texture* source_texture = source_texture_ref->texture();
10249 Texture* dest_texture = dest_texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0710250 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:2510251 (source_texture->target() != GL_TEXTURE_2D &&
[email protected]041d463f2014-04-30 05:38:3410252 source_texture->target() != GL_TEXTURE_RECTANGLE_ARB &&
10253 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
[email protected]3ecc1052013-09-26 08:59:0010254 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
10255 "glCopyTextureCHROMIUM",
10256 "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:0310257 return;
10258 }
10259
[email protected]43410e92012-04-20 17:06:2810260 int source_width, source_height, dest_width, dest_height;
[email protected]43410e92012-04-20 17:06:2810261
[email protected]3e0dfd72014-02-21 06:28:4110262 gfx::GLImage* image =
10263 source_texture->GetLevelImage(source_texture->target(), 0);
10264 if (image) {
[email protected]7bffe9e12014-01-27 23:02:5510265 gfx::Size size = image->GetSize();
[email protected]377976552013-05-14 23:32:5610266 source_width = size.width();
10267 source_height = size.height();
10268 if (source_width <= 0 || source_height <= 0) {
10269 LOCAL_SET_GL_ERROR(
10270 GL_INVALID_VALUE,
[email protected]7bffe9e12014-01-27 23:02:5510271 "glCopyTextureChromium", "invalid image size");
[email protected]377976552013-05-14 23:32:5610272 return;
10273 }
[email protected]3ecc1052013-09-26 08:59:0010274 } else {
10275 if (!source_texture->GetLevelSize(
10276 source_texture->target(), 0, &source_width, &source_height)) {
10277 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
10278 "glCopyTextureChromium",
10279 "source texture has no level 0");
10280 return;
10281 }
10282
10283 // Check that this type of texture is allowed.
10284 if (!texture_manager()->ValidForTarget(
10285 source_texture->target(), level, source_width, source_height, 1)) {
10286 LOCAL_SET_GL_ERROR(
10287 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions");
10288 return;
10289 }
[email protected]377976552013-05-14 23:32:5610290 }
10291
[email protected]04b5b37d2014-02-07 02:11:5110292 // Clear the source texture if necessary.
10293 if (!texture_manager()->ClearTextureLevel(
10294 this, source_texture_ref, source_texture->target(), 0)) {
10295 LOCAL_SET_GL_ERROR(
10296 GL_OUT_OF_MEMORY, "glCopyTextureCHROMIUM", "dimensions too big");
10297 return;
10298 }
10299
[email protected]a6e3d282014-08-22 22:20:4410300 GLenum source_type = 0;
10301 GLenum source_internal_format = 0;
10302 source_texture->GetLevelType(
10303 source_texture->target(), 0, &source_type, &source_internal_format);
10304
10305 // The destination format should be GL_RGB, or GL_RGBA. GL_ALPHA,
10306 // GL_LUMINANCE, and GL_LUMINANCE_ALPHA are not supported because they are not
10307 // renderable on some platforms.
reveman6b0fbe42014-09-04 00:55:0310308 bool valid_dest_format = internal_format == GL_RGB ||
10309 internal_format == GL_RGBA ||
10310 internal_format == GL_BGRA_EXT;
[email protected]a6e3d282014-08-22 22:20:4410311 bool valid_source_format = source_internal_format == GL_ALPHA ||
10312 source_internal_format == GL_RGB ||
10313 source_internal_format == GL_RGBA ||
10314 source_internal_format == GL_LUMINANCE ||
10315 source_internal_format == GL_LUMINANCE_ALPHA ||
10316 source_internal_format == GL_BGRA_EXT;
10317 if (!valid_source_format || !valid_dest_format) {
10318 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10319 "glCopyTextureCHROMIUM",
10320 "invalid internal format");
10321 return;
10322 }
10323
[email protected]cf6b8f62012-05-25 21:43:3710324 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
10325 // needed because it takes 10s of milliseconds to initialize.
10326 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:5110327 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:3710328 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:2710329 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:3710330 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:5110331 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:3710332 return;
10333 }
10334
[email protected]efc87712014-07-09 00:22:4710335 GLenum dest_type_previous = dest_type;
10336 GLenum dest_internal_format = internal_format;
[email protected]02965c22013-03-09 02:40:0710337 bool dest_level_defined = dest_texture->GetLevelSize(
10338 GL_TEXTURE_2D, level, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:2810339
[email protected]0a1e9ad2012-05-04 21:13:0310340 if (dest_level_defined) {
[email protected]a4a6bdd12013-04-19 20:46:5410341 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous,
[email protected]02965c22013-03-09 02:40:0710342 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:0310343 }
10344
10345 // Resize the destination texture to the dimensions of the source texture.
10346 if (!dest_level_defined || dest_width != source_width ||
10347 dest_height != source_height ||
[email protected]a4a6bdd12013-04-19 20:46:5410348 dest_internal_format != internal_format ||
10349 dest_type_previous != dest_type) {
[email protected]43410e92012-04-20 17:06:2810350 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:5110351 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:0710352 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
[email protected]8f1d2aa2013-05-10 23:45:3810353 glTexImage2D(
[email protected]43410e92012-04-20 17:06:2810354 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:0310355 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:5110356 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:0310357 if (error != GL_NO_ERROR) {
[email protected]2b10c02d2014-01-29 16:43:0210358 RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D);
[email protected]43410e92012-04-20 17:06:2810359 return;
[email protected]0a1e9ad2012-05-04 21:13:0310360 }
[email protected]43410e92012-04-20 17:06:2810361
10362 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910363 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:0310364 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:2510365 } else {
[email protected]02965c22013-03-09 02:40:0710366 texture_manager()->SetLevelCleared(
[email protected]370eaf12013-05-18 09:19:4910367 dest_texture_ref, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:2810368 }
10369
[email protected]00c2cf92014-03-14 00:08:3710370 ScopedModifyPixels modify(dest_texture_ref);
[email protected]91c94eb2013-10-22 10:32:5410371
revemance8fbe82014-09-05 02:19:5210372 // Try using GLImage::CopyTexImage when possible.
10373 bool unpack_premultiply_alpha_change =
10374 unpack_premultiply_alpha_ ^ unpack_unpremultiply_alpha_;
10375 if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change && !level) {
10376 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
10377 if (image->CopyTexImage(GL_TEXTURE_2D))
10378 return;
10379 }
10380
10381 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
10382
[email protected]5394a4102013-04-18 05:41:3710383 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
10384 // before presenting.
10385 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
10386 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
10387 // instead of using default matrix crbug.com/226218.
10388 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
10389 0.0f, 1.0f, 0.0f, 0.0f,
10390 0.0f, 0.0f, 1.0f, 0.0f,
10391 0.0f, 0.0f, 0.0f, 1.0f};
10392 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
10393 this,
10394 source_texture->target(),
[email protected]5394a4102013-04-18 05:41:3710395 source_texture->service_id(),
[email protected]90f7d30d2014-08-13 02:51:5710396 dest_texture->service_id(),
10397 level,
10398 source_width,
10399 source_height,
[email protected]5394a4102013-04-18 05:41:3710400 unpack_flip_y_,
10401 unpack_premultiply_alpha_,
10402 unpack_unpremultiply_alpha_,
10403 default_matrix);
10404 } else {
[email protected]90f7d30d2014-08-13 02:51:5710405 copy_texture_CHROMIUM_->DoCopyTexture(this,
10406 source_texture->target(),
10407 source_texture->service_id(),
10408 source_internal_format,
10409 dest_texture->service_id(),
10410 level,
10411 internal_format,
10412 source_width,
10413 source_height,
10414 unpack_flip_y_,
10415 unpack_premultiply_alpha_,
10416 unpack_unpremultiply_alpha_);
[email protected]5394a4102013-04-18 05:41:3710417 }
[email protected]91c94eb2013-10-22 10:32:5410418
10419 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
[email protected]43410e92012-04-20 17:06:2810420}
10421
[email protected]97dc7cbe2011-12-06 17:26:1710422static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
10423 switch (internalformat) {
10424 case GL_RGB565:
10425 return GL_UNSIGNED_SHORT_5_6_5;
10426 case GL_RGBA4:
10427 return GL_UNSIGNED_SHORT_4_4_4_4;
10428 case GL_RGB5_A1:
10429 return GL_UNSIGNED_SHORT_5_5_5_1;
10430 case GL_RGB8_OES:
10431 return GL_UNSIGNED_BYTE;
10432 case GL_RGBA8_OES:
10433 return GL_UNSIGNED_BYTE;
10434 case GL_LUMINANCE8_ALPHA8_EXT:
10435 return GL_UNSIGNED_BYTE;
10436 case GL_LUMINANCE8_EXT:
10437 return GL_UNSIGNED_BYTE;
10438 case GL_ALPHA8_EXT:
10439 return GL_UNSIGNED_BYTE;
10440 case GL_RGBA32F_EXT:
10441 return GL_FLOAT;
10442 case GL_RGB32F_EXT:
10443 return GL_FLOAT;
10444 case GL_ALPHA32F_EXT:
10445 return GL_FLOAT;
10446 case GL_LUMINANCE32F_EXT:
10447 return GL_FLOAT;
10448 case GL_LUMINANCE_ALPHA32F_EXT:
10449 return GL_FLOAT;
10450 case GL_RGBA16F_EXT:
10451 return GL_HALF_FLOAT_OES;
10452 case GL_RGB16F_EXT:
10453 return GL_HALF_FLOAT_OES;
10454 case GL_ALPHA16F_EXT:
10455 return GL_HALF_FLOAT_OES;
10456 case GL_LUMINANCE16F_EXT:
10457 return GL_HALF_FLOAT_OES;
10458 case GL_LUMINANCE_ALPHA16F_EXT:
10459 return GL_HALF_FLOAT_OES;
10460 case GL_BGRA8_EXT:
10461 return GL_UNSIGNED_BYTE;
10462 default:
10463 return GL_NONE;
10464 }
10465}
10466
10467void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:4410468 GLenum target,
10469 GLint levels,
10470 GLenum internal_format,
10471 GLsizei width,
10472 GLsizei height) {
[email protected]67f929422014-05-17 15:33:1310473 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT",
10474 "width", width, "height", height);
[email protected]80eb6b52012-01-19 00:14:4110475 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]3ecc1052013-09-26 08:59:0010476 TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:5110477 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310478 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:1710479 return;
10480 }
[email protected]c986af502013-08-14 01:04:4410481 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10482 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910483 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110484 LOCAL_SET_GL_ERROR(
10485 GL_INVALID_OPERATION,
10486 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:1710487 return;
10488 }
[email protected]370eaf12013-05-18 09:19:4910489 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0710490 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:4410491 framebuffer_state_.clear_state_dirty = true;
[email protected]97dc7cbe2011-12-06 17:26:1710492 }
[email protected]02965c22013-03-09 02:40:0710493 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:5110494 LOCAL_SET_GL_ERROR(
10495 GL_INVALID_OPERATION,
10496 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:1710497 return;
10498 }
[email protected]7989c9e2013-01-23 06:39:2610499
10500 GLenum format = ExtractFormatFromStorageFormat(internal_format);
10501 GLenum type = ExtractTypeFromStorageFormat(internal_format);
10502
10503 {
10504 GLsizei level_width = width;
10505 GLsizei level_height = height;
10506 uint32 estimated_size = 0;
10507 for (int ii = 0; ii < levels; ++ii) {
10508 uint32 level_size = 0;
10509 if (!GLES2Util::ComputeImageDataSizes(
10510 level_width, level_height, format, type, state_.unpack_alignment,
10511 &estimated_size, NULL, NULL) ||
10512 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5110513 LOCAL_SET_GL_ERROR(
10514 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:2610515 return;
10516 }
10517 level_width = std::max(1, level_width >> 1);
10518 level_height = std::max(1, level_height >> 1);
10519 }
10520 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5110521 LOCAL_SET_GL_ERROR(
10522 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2610523 return;
10524 }
10525 }
10526
[email protected]ab09b612013-03-11 22:11:5110527 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]8f1d2aa2013-05-10 23:45:3810528 glTexStorage2DEXT(target, levels, internal_format, width, height);
[email protected]ab09b612013-03-11 22:11:5110529 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:1710530 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:1510531 GLsizei level_width = width;
10532 GLsizei level_height = height;
10533 for (int ii = 0; ii < levels; ++ii) {
10534 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910535 texture_ref, target, ii, format,
10536 level_width, level_height, 1, 0, format, type, false);
[email protected]4502e6492011-12-14 19:39:1510537 level_width = std::max(1, level_width >> 1);
10538 level_height = std::max(1, level_height >> 1);
10539 }
[email protected]02965c22013-03-09 02:40:0710540 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:1710541 }
[email protected]97dc7cbe2011-12-06 17:26:1710542}
[email protected]e51bdf32011-11-23 22:21:4610543
[email protected]78b514b2012-05-01 21:50:5910544error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
vmiuracd108592014-09-08 14:36:3410545 uint32 immediate_data_size,
10546 const void* cmd_data) {
[email protected]baed42c2013-10-01 05:06:3510547 return error::kUnknownCommand;
[email protected]78b514b2012-05-01 21:50:5910548}
10549
10550void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3710551 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0210552 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3210553 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3710554 "mailbox[0]", static_cast<unsigned char>(data[0]));
10555
[email protected]43f253da2014-06-10 17:51:2210556 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10557 &state_, target);
10558 ProduceTextureRef("glProduceTextureCHROMIUM", texture_ref, target, data);
10559}
10560
10561void GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM(GLuint client_id,
10562 GLenum target, const GLbyte* data) {
10563 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM",
10564 "context", logger_.GetLogPrefix(),
10565 "mailbox[0]", static_cast<unsigned char>(data[0]));
10566
10567 ProduceTextureRef("glProduceTextureDirectCHROMIUM", GetTexture(client_id),
10568 target, data);
10569}
10570
10571void GLES2DecoderImpl::ProduceTextureRef(std::string func_name,
10572 TextureRef* texture_ref, GLenum target, const GLbyte* data) {
[email protected]64ba52f2014-02-15 14:22:3710573 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
[email protected]43f253da2014-06-10 17:51:2210574 DLOG_IF(ERROR, !mailbox.Verify()) << func_name << " was passed a "
[email protected]64ba52f2014-02-15 14:22:3710575 "mailbox that was not generated by "
10576 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0210577
[email protected]370eaf12013-05-18 09:19:4910578 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110579 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2210580 GL_INVALID_OPERATION, func_name.c_str(), "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5910581 return;
10582 }
10583
[email protected]62e65f02013-05-29 22:28:1010584 Texture* produced = texture_manager()->Produce(texture_ref);
10585 if (!produced) {
[email protected]ab09b612013-03-11 22:11:5110586 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2210587 GL_INVALID_OPERATION, func_name.c_str(), "invalid texture");
10588 return;
10589 }
10590
10591 if (produced->target() != target) {
10592 LOCAL_SET_GL_ERROR(
10593 GL_INVALID_OPERATION, func_name.c_str(), "invalid target");
[email protected]78b514b2012-05-01 21:50:5910594 return;
10595 }
10596
[email protected]64ba52f2014-02-15 14:22:3710597 group_->mailbox_manager()->ProduceTexture(target, mailbox, produced);
[email protected]78b514b2012-05-01 21:50:5910598}
10599
10600void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3710601 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0210602 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3210603 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3710604 "mailbox[0]", static_cast<unsigned char>(data[0]));
10605 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
10606 DLOG_IF(ERROR, !mailbox.Verify()) << "ConsumeTextureCHROMIUM was passed a "
10607 "mailbox that was not generated by "
10608 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0210609
[email protected]62e65f02013-05-29 22:28:1010610 scoped_refptr<TextureRef> texture_ref =
[email protected]c986af502013-08-14 01:04:4410611 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]7cd76fd2013-06-02 21:11:1110612 if (!texture_ref.get()) {
10613 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10614 "glConsumeTextureCHROMIUM",
10615 "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5910616 return;
10617 }
[email protected]62e65f02013-05-29 22:28:1010618 GLuint client_id = texture_ref->client_id();
10619 if (!client_id) {
10620 LOCAL_SET_GL_ERROR(
10621 GL_INVALID_OPERATION,
10622 "glConsumeTextureCHROMIUM", "unknown texture for target");
10623 return;
10624 }
[email protected]64ba52f2014-02-15 14:22:3710625 Texture* texture = group_->mailbox_manager()->ConsumeTexture(target, mailbox);
[email protected]62e65f02013-05-29 22:28:1010626 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5110627 LOCAL_SET_GL_ERROR(
10628 GL_INVALID_OPERATION,
10629 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:5910630 return;
10631 }
[email protected]62e65f02013-05-29 22:28:1010632 if (texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:5110633 LOCAL_SET_GL_ERROR(
10634 GL_INVALID_OPERATION,
[email protected]62e65f02013-05-29 22:28:1010635 "glConsumeTextureCHROMIUM", "invalid target");
[email protected]78b514b2012-05-01 21:50:5910636 return;
10637 }
[email protected]62e65f02013-05-29 22:28:1010638
10639 DeleteTexturesHelper(1, &client_id);
10640 texture_ref = texture_manager()->Consume(client_id, texture);
10641 glBindTexture(target, texture_ref->service_id());
10642
10643 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
10644 unit.bind_target = target;
10645 switch (target) {
10646 case GL_TEXTURE_2D:
10647 unit.bound_texture_2d = texture_ref;
10648 break;
10649 case GL_TEXTURE_CUBE_MAP:
10650 unit.bound_texture_cube_map = texture_ref;
10651 break;
10652 case GL_TEXTURE_EXTERNAL_OES:
10653 unit.bound_texture_external_oes = texture_ref;
10654 break;
10655 case GL_TEXTURE_RECTANGLE_ARB:
10656 unit.bound_texture_rectangle_arb = texture_ref;
10657 break;
10658 default:
10659 NOTREACHED(); // Validation should prevent us getting here.
10660 break;
10661 }
[email protected]78b514b2012-05-01 21:50:5910662}
10663
[email protected]43f253da2014-06-10 17:51:2210664error::Error GLES2DecoderImpl::HandleCreateAndConsumeTextureCHROMIUMImmediate(
10665 uint32_t immediate_data_size,
vmiuracd108592014-09-08 14:36:3410666 const void* cmd_data) {
10667 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate& c =
10668 *static_cast<
10669 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate*>(
10670 cmd_data);
[email protected]43f253da2014-06-10 17:51:2210671 GLenum target = static_cast<GLenum>(c.target);
10672 uint32_t data_size;
10673 if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
10674 return error::kOutOfBounds;
10675 }
10676 if (data_size > immediate_data_size) {
10677 return error::kOutOfBounds;
10678 }
10679 const GLbyte* mailbox =
10680 GetImmediateDataAs<const GLbyte*>(c, data_size, immediate_data_size);
10681 if (!validators_->texture_bind_target.IsValid(target)) {
10682 LOCAL_SET_GL_ERROR_INVALID_ENUM(
10683 "glCreateAndConsumeTextureCHROMIUM", target, "target");
10684 return error::kNoError;
10685 }
10686 if (mailbox == NULL) {
10687 return error::kOutOfBounds;
10688 }
10689 uint32_t client_id = c.client_id;
10690 DoCreateAndConsumeTextureCHROMIUM(target, mailbox, client_id);
10691 return error::kNoError;
10692}
10693
10694void GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM(GLenum target,
10695 const GLbyte* data, GLuint client_id) {
10696 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM",
10697 "context", logger_.GetLogPrefix(),
10698 "mailbox[0]", static_cast<unsigned char>(data[0]));
10699 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
10700 DLOG_IF(ERROR, !mailbox.Verify()) << "CreateAndConsumeTextureCHROMIUM was "
10701 "passed a mailbox that was not "
10702 "generated by GenMailboxCHROMIUM.";
10703
10704 TextureRef* texture_ref = GetTexture(client_id);
10705 if (texture_ref) {
10706 LOCAL_SET_GL_ERROR(
10707 GL_INVALID_OPERATION,
10708 "glCreateAndConsumeTextureCHROMIUM", "client id already in use");
10709 return;
10710 }
10711 Texture* texture = group_->mailbox_manager()->ConsumeTexture(target, mailbox);
10712 if (!texture) {
10713 LOCAL_SET_GL_ERROR(
10714 GL_INVALID_OPERATION,
10715 "glCreateAndConsumeTextureCHROMIUM", "invalid mailbox name");
10716 return;
10717 }
10718 if (texture->target() != target) {
10719 LOCAL_SET_GL_ERROR(
10720 GL_INVALID_OPERATION,
10721 "glCreateAndConsumeTextureCHROMIUM", "invalid target");
10722 return;
10723 }
10724
10725 IdAllocatorInterface* id_allocator =
10726 group_->GetIdAllocator(id_namespaces::kTextures);
10727 id_allocator->MarkAsUsed(client_id);
10728
10729 texture_ref = texture_manager()->Consume(client_id, texture);
10730}
10731
[email protected]d2a0e1a2012-08-12 02:25:0110732void GLES2DecoderImpl::DoInsertEventMarkerEXT(
10733 GLsizei length, const GLchar* marker) {
10734 if (!marker) {
10735 marker = "";
10736 }
10737 debug_marker_manager_.SetMarker(
10738 length ? std::string(marker, length) : std::string(marker));
10739}
10740
10741void GLES2DecoderImpl::DoPushGroupMarkerEXT(
10742 GLsizei length, const GLchar* marker) {
10743 if (!marker) {
10744 marker = "";
10745 }
[email protected]cac16542014-01-15 17:53:5110746 std::string name = length ? std::string(marker, length) : std::string(marker);
10747 debug_marker_manager_.PushGroup(name);
10748 gpu_tracer_->Begin(name, kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0110749}
10750
10751void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
10752 debug_marker_manager_.PopGroup();
[email protected]cac16542014-01-15 17:53:5110753 gpu_tracer_->End(kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0110754}
10755
[email protected]09d50362012-10-18 20:54:3710756void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
10757 GLenum target, GLint image_id) {
10758 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3710759
[email protected]bc26e8d2014-01-29 00:40:3010760 if (target == GL_TEXTURE_CUBE_MAP) {
10761 LOCAL_SET_GL_ERROR(
10762 GL_INVALID_ENUM,
10763 "glBindTexImage2DCHROMIUM", "invalid target");
10764 return;
10765 }
10766
[email protected]09d50362012-10-18 20:54:3710767 // Default target might be conceptually valid, but disallow it to avoid
10768 // accidents.
[email protected]c986af502013-08-14 01:04:4410769 TextureRef* texture_ref =
10770 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910771 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110772 LOCAL_SET_GL_ERROR(
10773 GL_INVALID_OPERATION,
10774 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710775 return;
10776 }
10777
10778 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10779 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110780 LOCAL_SET_GL_ERROR(
10781 GL_INVALID_OPERATION,
10782 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710783 return;
10784 }
10785
[email protected]b8160812013-04-09 00:41:0410786 {
10787 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010788 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2610789 if (!gl_image->BindTexImage(target)) {
[email protected]b8160812013-04-09 00:41:0410790 LOCAL_SET_GL_ERROR(
10791 GL_INVALID_OPERATION,
10792 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
10793 return;
10794 }
[email protected]09d50362012-10-18 20:54:3710795 }
10796
10797 gfx::Size size = gl_image->GetSize();
10798 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910799 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:3710800 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]370eaf12013-05-18 09:19:4910801 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:3710802}
10803
10804void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
10805 GLenum target, GLint image_id) {
10806 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3710807
10808 // Default target might be conceptually valid, but disallow it to avoid
10809 // accidents.
[email protected]c986af502013-08-14 01:04:4410810 TextureRef* texture_ref =
10811 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910812 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110813 LOCAL_SET_GL_ERROR(
10814 GL_INVALID_OPERATION,
10815 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710816 return;
10817 }
10818
10819 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10820 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110821 LOCAL_SET_GL_ERROR(
10822 GL_INVALID_OPERATION,
10823 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710824 return;
10825 }
10826
10827 // Do nothing when image is not currently bound.
[email protected]370eaf12013-05-18 09:19:4910828 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3710829 return;
10830
[email protected]b8160812013-04-09 00:41:0410831 {
10832 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010833 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2610834 gl_image->ReleaseTexImage(target);
[email protected]b8160812013-04-09 00:41:0410835 }
[email protected]09d50362012-10-18 20:54:3710836
10837 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910838 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:3710839 GL_RGBA, GL_UNSIGNED_BYTE, false);
10840}
[email protected]d2a0e1a2012-08-12 02:25:0110841
[email protected]94307712012-11-16 23:26:1110842error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
vmiuracd108592014-09-08 14:36:3410843 uint32 immediate_data_size,
10844 const void* cmd_data) {
10845 const gles2::cmds::TraceBeginCHROMIUM& c =
10846 *static_cast<const gles2::cmds::TraceBeginCHROMIUM*>(cmd_data);
[email protected]94307712012-11-16 23:26:1110847 Bucket* bucket = GetBucket(c.bucket_id);
10848 if (!bucket || bucket->size() == 0) {
10849 return error::kInvalidArguments;
10850 }
10851 std::string command_name;
10852 if (!bucket->GetAsString(&command_name)) {
10853 return error::kInvalidArguments;
10854 }
[email protected]fb97b662013-02-20 23:02:1410855 TRACE_EVENT_COPY_ASYNC_BEGIN0("gpu", command_name.c_str(), this);
[email protected]cac16542014-01-15 17:53:5110856 if (!gpu_tracer_->Begin(command_name, kTraceCHROMIUM)) {
[email protected]ab09b612013-03-11 22:11:5110857 LOCAL_SET_GL_ERROR(
10858 GL_INVALID_OPERATION,
10859 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1410860 return error::kNoError;
10861 }
[email protected]94307712012-11-16 23:26:1110862 return error::kNoError;
10863}
10864
10865void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
[email protected]fb97b662013-02-20 23:02:1410866 if (gpu_tracer_->CurrentName().empty()) {
[email protected]ab09b612013-03-11 22:11:5110867 LOCAL_SET_GL_ERROR(
10868 GL_INVALID_OPERATION,
10869 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1110870 return;
10871 }
[email protected]fb97b662013-02-20 23:02:1410872 TRACE_EVENT_COPY_ASYNC_END0("gpu", gpu_tracer_->CurrentName().c_str(), this);
[email protected]cac16542014-01-15 17:53:5110873 gpu_tracer_->End(kTraceCHROMIUM);
[email protected]94307712012-11-16 23:26:1110874}
10875
[email protected]2f143d482013-03-14 18:04:4910876void GLES2DecoderImpl::DoDrawBuffersEXT(
10877 GLsizei count, const GLenum* bufs) {
10878 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
10879 LOCAL_SET_GL_ERROR(
10880 GL_INVALID_VALUE,
10881 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
10882 return;
10883 }
10884
10885 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
10886 if (framebuffer) {
10887 for (GLsizei i = 0; i < count; ++i) {
10888 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
10889 bufs[i] != GL_NONE) {
10890 LOCAL_SET_GL_ERROR(
10891 GL_INVALID_OPERATION,
10892 "glDrawBuffersEXT",
10893 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
10894 return;
10895 }
10896 }
10897 glDrawBuffersARB(count, bufs);
10898 framebuffer->SetDrawBuffers(count, bufs);
10899 } else { // backbuffer
10900 if (count > 1 ||
10901 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
10902 LOCAL_SET_GL_ERROR(
10903 GL_INVALID_OPERATION,
10904 "glDrawBuffersEXT",
10905 "more than one buffer or bufs not GL_NONE or GL_BACK");
10906 return;
10907 }
10908 GLenum mapped_buf = bufs[0];
10909 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
10910 bufs[0] == GL_BACK) {
10911 mapped_buf = GL_COLOR_ATTACHMENT0;
10912 }
10913 glDrawBuffersARB(count, &mapped_buf);
10914 group_->set_draw_buffer(bufs[0]);
10915 }
10916}
10917
[email protected]a6a09f852014-05-23 13:05:0310918void GLES2DecoderImpl::DoLoseContextCHROMIUM(GLenum current, GLenum other) {
10919 group_->LoseContexts(other);
10920 reset_status_ = current;
10921 current_decoder_error_ = error::kLostContext;
10922}
10923
kkinnunen337d59632014-08-26 10:19:5710924void GLES2DecoderImpl::DoMatrixLoadfCHROMIUM(GLenum matrix_mode,
10925 const GLfloat* matrix) {
10926 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
10927 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
10928 if (!features().chromium_path_rendering) {
10929 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10930 "glMatrixLoadfCHROMIUM",
10931 "function not available");
10932 return;
10933 }
10934
10935 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
10936 ? state_.projection_matrix
10937 : state_.modelview_matrix;
10938 memcpy(target_matrix, matrix, sizeof(GLfloat) * 16);
10939 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
10940 // since the values of the _NV and _CHROMIUM tokens match.
10941 glMatrixLoadfEXT(matrix_mode, matrix);
10942}
10943
10944void GLES2DecoderImpl::DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode) {
10945 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
10946 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
10947
10948 if (!features().chromium_path_rendering) {
10949 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10950 "glMatrixLoadIdentityCHROMIUM",
10951 "function not available");
10952 return;
10953 }
10954
10955 static GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
10956 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
10957 0.0f, 0.0f, 0.0f, 1.0f};
10958
10959 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
10960 ? state_.projection_matrix
10961 : state_.modelview_matrix;
10962 memcpy(target_matrix, kIdentityMatrix, sizeof(kIdentityMatrix));
10963 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
10964 // since the values of the _NV and _CHROMIUM tokens match.
10965 glMatrixLoadIdentityEXT(matrix_mode);
10966}
10967
[email protected]32145a92012-12-17 09:01:5910968bool GLES2DecoderImpl::ValidateAsyncTransfer(
10969 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:4710970 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:5910971 GLenum target,
10972 GLint level,
10973 const void * data) {
10974 // We only support async uploads to 2D textures for now.
10975 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110976 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5910977 return false;
10978 }
10979 // We only support uploads to level zero for now.
10980 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5110981 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5910982 return false;
10983 }
10984 // A transfer buffer must be bound, even for asyncTexImage2D.
10985 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5110986 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5910987 return false;
10988 }
10989 // We only support one async transfer in progress.
[email protected]85a4ac22013-05-31 01:58:4710990 if (!texture_ref ||
10991 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5110992 LOCAL_SET_GL_ERROR(
10993 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910994 function_name, "transfer already in progress");
10995 return false;
10996 }
10997 return true;
10998}
10999
[email protected]e3c4a9ab2014-03-31 09:07:0211000base::Closure GLES2DecoderImpl::AsyncUploadTokenCompletionClosure(
11001 uint32 async_upload_token,
11002 uint32 sync_data_shm_id,
11003 uint32 sync_data_shm_offset) {
11004 scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_data_shm_id);
Daniel Cheng3d7ce9f2014-08-26 00:26:2511005 if (!buffer.get() ||
11006 !buffer->GetDataAddress(sync_data_shm_offset, sizeof(AsyncUploadSync)))
[email protected]e3c4a9ab2014-03-31 09:07:0211007 return base::Closure();
11008
11009 AsyncMemoryParams mem_params(buffer,
11010 sync_data_shm_offset,
11011 sizeof(AsyncUploadSync));
11012
11013 scoped_refptr<AsyncUploadTokenCompletionObserver> observer(
11014 new AsyncUploadTokenCompletionObserver(async_upload_token));
11015
11016 return base::Bind(
11017 &AsyncPixelTransferManager::AsyncNotifyCompletion,
11018 base::Unretained(GetAsyncPixelTransferManager()),
11019 mem_params,
11020 observer);
11021}
11022
[email protected]69023942012-11-30 19:57:1611023error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411024 uint32 immediate_data_size,
11025 const void* cmd_data) {
11026 const gles2::cmds::AsyncTexImage2DCHROMIUM& c =
11027 *static_cast<const gles2::cmds::AsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1611028 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1611029 GLenum target = static_cast<GLenum>(c.target);
11030 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:4411031 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]69023942012-11-30 19:57:1611032 GLsizei width = static_cast<GLsizei>(c.width);
11033 GLsizei height = static_cast<GLsizei>(c.height);
11034 GLint border = static_cast<GLint>(c.border);
11035 GLenum format = static_cast<GLenum>(c.format);
11036 GLenum type = static_cast<GLenum>(c.type);
11037 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
11038 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
11039 uint32 pixels_size;
[email protected]e3c4a9ab2014-03-31 09:07:0211040 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
11041 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
11042 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
11043
11044 base::ScopedClosureRunner scoped_completion_callback;
11045 if (async_upload_token) {
11046 base::Closure completion_closure =
11047 AsyncUploadTokenCompletionClosure(async_upload_token,
11048 sync_data_shm_id,
11049 sync_data_shm_offset);
11050 if (completion_closure.is_null())
11051 return error::kInvalidArguments;
11052
11053 scoped_completion_callback.Reset(completion_closure);
11054 }
[email protected]32145a92012-12-17 09:01:5911055
11056 // TODO(epenner): Move this and copies of this memory validation
11057 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1611058 if (!GLES2Util::ComputeImageDataSizes(
11059 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
11060 NULL)) {
11061 return error::kOutOfBounds;
11062 }
11063 const void* pixels = NULL;
11064 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
11065 pixels = GetSharedMemoryAs<const void*>(
11066 pixels_shm_id, pixels_shm_offset, pixels_size);
11067 if (!pixels) {
11068 return error::kOutOfBounds;
11069 }
11070 }
11071
[email protected]c986af502013-08-14 01:04:4411072 TextureManager::DoTextImage2DArguments args = {
11073 target, level, internal_format, width, height, border, format, type,
11074 pixels, pixels_size};
11075 TextureRef* texture_ref;
[email protected]32145a92012-12-17 09:01:5911076 // All the normal glTexSubImage2D validation.
[email protected]c986af502013-08-14 01:04:4411077 if (!texture_manager()->ValidateTexImage2D(
11078 &state_, "glAsyncTexImage2DCHROMIUM", args, &texture_ref)) {
[email protected]32145a92012-12-17 09:01:5911079 return error::kNoError;
11080 }
11081
11082 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4911083 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5911084 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4711085 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5911086 return error::kNoError;
11087
11088 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0711089 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5111090 LOCAL_SET_GL_ERROR(
11091 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5911092 "glAsyncTexImage2DCHROMIUM", "already defined");
11093 return error::kNoError;
11094 }
11095
[email protected]7989c9e2013-01-23 06:39:2611096 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5111097 LOCAL_SET_GL_ERROR(
11098 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2611099 return error::kNoError;
11100 }
11101
[email protected]5b3a8e02013-03-13 05:36:4411102 // Setup the parameters.
[email protected]8f1d2aa2013-05-10 23:45:3811103 AsyncTexImage2DParams tex_params = {
11104 target, level, static_cast<GLenum>(internal_format),
11105 width, height, border, format, type};
[email protected]c8021e02014-03-27 06:10:1211106 AsyncMemoryParams mem_params(
11107 GetSharedMemoryBuffer(c.pixels_shm_id), c.pixels_shm_offset, pixels_size);
[email protected]32145a92012-12-17 09:01:5911108
[email protected]5b3a8e02013-03-13 05:36:4411109 // Set up the async state if needed, and make the texture
11110 // immutable so the async state stays valid. The level info
11111 // is set up lazily when the transfer completes.
[email protected]896425e2013-06-12 17:27:1811112 AsyncPixelTransferDelegate* delegate =
11113 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref,
11114 tex_params);
[email protected]5b3a8e02013-03-13 05:36:4411115 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5911116
[email protected]896425e2013-06-12 17:27:1811117 delegate->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4411118 tex_params,
11119 mem_params,
11120 base::Bind(&TextureManager::SetLevelInfoFromParams,
[email protected]370eaf12013-05-18 09:19:4911121 // The callback is only invoked if the transfer delegate still
11122 // exists, which implies through manager->texture_ref->state
[email protected]5b3a8e02013-03-13 05:36:4411123 // ownership that both of these pointers are valid.
11124 base::Unretained(texture_manager()),
[email protected]370eaf12013-05-18 09:19:4911125 base::Unretained(texture_ref),
[email protected]5b3a8e02013-03-13 05:36:4411126 tex_params));
[email protected]f598f422012-12-07 08:30:0311127 return error::kNoError;
[email protected]69023942012-11-30 19:57:1611128}
11129
11130error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411131 uint32 immediate_data_size,
11132 const void* cmd_data) {
11133 const gles2::cmds::AsyncTexSubImage2DCHROMIUM& c =
11134 *static_cast<const gles2::cmds::AsyncTexSubImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1611135 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1611136 GLenum target = static_cast<GLenum>(c.target);
11137 GLint level = static_cast<GLint>(c.level);
11138 GLint xoffset = static_cast<GLint>(c.xoffset);
11139 GLint yoffset = static_cast<GLint>(c.yoffset);
11140 GLsizei width = static_cast<GLsizei>(c.width);
11141 GLsizei height = static_cast<GLsizei>(c.height);
11142 GLenum format = static_cast<GLenum>(c.format);
11143 GLenum type = static_cast<GLenum>(c.type);
[email protected]e3c4a9ab2014-03-31 09:07:0211144 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
11145 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
11146 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
11147
11148 base::ScopedClosureRunner scoped_completion_callback;
11149 if (async_upload_token) {
11150 base::Closure completion_closure =
11151 AsyncUploadTokenCompletionClosure(async_upload_token,
11152 sync_data_shm_id,
11153 sync_data_shm_offset);
11154 if (completion_closure.is_null())
11155 return error::kInvalidArguments;
11156
11157 scoped_completion_callback.Reset(completion_closure);
11158 }
[email protected]32145a92012-12-17 09:01:5911159
11160 // TODO(epenner): Move this and copies of this memory validation
11161 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1611162 uint32 data_size;
11163 if (!GLES2Util::ComputeImageDataSizes(
11164 width, height, format, type, state_.unpack_alignment, &data_size,
11165 NULL, NULL)) {
11166 return error::kOutOfBounds;
11167 }
11168 const void* pixels = GetSharedMemoryAs<const void*>(
11169 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5911170
11171 // All the normal glTexSubImage2D validation.
11172 error::Error error = error::kNoError;
11173 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
11174 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
11175 return error;
[email protected]69023942012-11-30 19:57:1611176 }
11177
[email protected]32145a92012-12-17 09:01:5911178 // Extra async validation.
[email protected]c986af502013-08-14 01:04:4411179 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11180 &state_, target);
[email protected]370eaf12013-05-18 09:19:4911181 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5911182 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4711183 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5911184 return error::kNoError;
11185
11186 // Guarantee async textures are always 'cleared' as follows:
11187 // - AsyncTexImage2D can not redefine an existing texture
11188 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
11189 // - AsyncTexSubImage2D clears synchronously if not already cleared.
11190 // - Textures become immutable after an async call.
11191 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0711192 if (!texture->SafeToRenderFrom()) {
[email protected]370eaf12013-05-18 09:19:4911193 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
11194 target, level)) {
[email protected]ab09b612013-03-11 22:11:5111195 LOCAL_SET_GL_ERROR(
11196 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2511197 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5911198 return error::kNoError;
11199 }
11200 }
11201
[email protected]5b3a8e02013-03-13 05:36:4411202 // Setup the parameters.
[email protected]2a7568a2013-05-09 23:12:0311203 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
[email protected]32145a92012-12-17 09:01:5911204 width, height, format, type};
[email protected]c8021e02014-03-27 06:10:1211205 AsyncMemoryParams mem_params(
11206 GetSharedMemoryBuffer(c.data_shm_id), c.data_shm_offset, data_size);
[email protected]896425e2013-06-12 17:27:1811207 AsyncPixelTransferDelegate* delegate =
11208 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
11209 if (!delegate) {
[email protected]5b3a8e02013-03-13 05:36:4411210 // TODO(epenner): We may want to enforce exclusive use
11211 // of async APIs in which case this should become an error,
11212 // (the texture should have been async defined).
[email protected]2a7568a2013-05-09 23:12:0311213 AsyncTexImage2DParams define_params = {target, level,
[email protected]5b3a8e02013-03-13 05:36:4411214 0, 0, 0, 0, 0, 0};
11215 texture->GetLevelSize(target, level, &define_params.width,
11216 &define_params.height);
11217 texture->GetLevelType(target, level, &define_params.type,
11218 &define_params.internal_format);
11219 // Set up the async state if needed, and make the texture
11220 // immutable so the async state stays valid.
[email protected]896425e2013-06-12 17:27:1811221 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate(
[email protected]85a4ac22013-05-31 01:58:4711222 texture_ref, define_params);
[email protected]5b3a8e02013-03-13 05:36:4411223 texture->SetImmutable(true);
11224 }
11225
[email protected]896425e2013-06-12 17:27:1811226 delegate->AsyncTexSubImage2D(tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5911227 return error::kNoError;
[email protected]69023942012-11-30 19:57:1611228}
11229
[email protected]a00c1f742013-03-05 17:02:1611230error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411231 uint32 immediate_data_size,
11232 const void* cmd_data) {
11233 const gles2::cmds::WaitAsyncTexImage2DCHROMIUM& c =
11234 *static_cast<const gles2::cmds::WaitAsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]a00c1f742013-03-05 17:02:1611235 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
11236 GLenum target = static_cast<GLenum>(c.target);
11237
11238 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5111239 LOCAL_SET_GL_ERROR(
11240 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1611241 return error::kNoError;
11242 }
[email protected]c986af502013-08-14 01:04:4411243 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11244 &state_, target);
[email protected]370eaf12013-05-18 09:19:4911245 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111246 LOCAL_SET_GL_ERROR(
11247 GL_INVALID_OPERATION,
11248 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1611249 return error::kNoError;
11250 }
[email protected]896425e2013-06-12 17:27:1811251 AsyncPixelTransferDelegate* delegate =
11252 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
11253 if (!delegate) {
[email protected]370eaf12013-05-18 09:19:4911254 LOCAL_SET_GL_ERROR(
11255 GL_INVALID_OPERATION,
11256 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
11257 return error::kNoError;
11258 }
[email protected]896425e2013-06-12 17:27:1811259 delegate->WaitForTransferCompletion();
[email protected]69a8701e2013-03-07 21:31:0911260 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1611261 return error::kNoError;
11262}
11263
[email protected]e3c4a9ab2014-03-31 09:07:0211264error::Error GLES2DecoderImpl::HandleWaitAllAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411265 uint32 immediate_data_size,
11266 const void* data) {
[email protected]e3c4a9ab2014-03-31 09:07:0211267 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
11268
11269 GetAsyncPixelTransferManager()->WaitAllAsyncTexImage2D();
11270 ProcessFinishedAsyncTransfers();
11271 return error::kNoError;
11272}
11273
[email protected]91c94eb2013-10-22 10:32:5411274void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer(
11275 TextureRef* texture_ref) {
11276 Texture* texture = texture_ref->texture();
11277 DoDidUseTexImageIfNeeded(texture, texture->target());
11278}
11279
[email protected]828a3932014-04-02 14:43:1311280void GLES2DecoderImpl::OnOutOfMemoryError() {
11281 if (lose_context_when_out_of_memory_) {
11282 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB);
11283 LoseContext(GL_GUILTY_CONTEXT_RESET_ARB);
11284 }
11285}
11286
[email protected]96449d2c2009-11-25 00:01:3211287// Include the auto-generated part of this file. We split this because it means
11288// we can easily edit the non-auto generated parts right here in this file
11289// instead of having to edit some template or the code generator.
11290#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
11291
11292} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2511293} // namespace gpu