blob: 6253cc8926112765af5d5e6094e9ae71d628564a [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
mohan.reddy5e1b8952014-10-08 01:38:17514 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,
mohan.reddy5e1b8952014-10-08 01:38:17566 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,
mohan.reddy5e1b8952014-10-08 01:38:17571 int* entries_processed) override;
vmiura8266ca72014-09-09 21:37:00572
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.
mohan.reddy5e1b8952014-10-08 01:38:17580 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,
mohan.reddy5e1b8952014-10-08 01:38:17588 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(
mohan.reddy5e1b8952014-10-08 01:38:17591 const scoped_refptr<gfx::GLSurface>& surface) override;
592 virtual void ProduceFrontBuffer(const Mailbox& mailbox) override;
593 virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) override;
[email protected]9a5afa432011-07-22 18:16:39594 void UpdateParentTextureInfo();
mohan.reddy5e1b8952014-10-08 01:38:17595 virtual bool MakeCurrent() override;
596 virtual GLES2Util* GetGLES2Util() override { return &util_; }
597 virtual gfx::GLContext* GetGLContext() override { return context_.get(); }
598 virtual ContextGroup* GetContextGroup() override { return group_.get(); }
599 virtual Capabilities GetCapabilities() override;
600 virtual void RestoreState(const ContextState* prev_state) override;
[email protected]29a4d902013-02-26 20:18:06601
mohan.reddy5e1b8952014-10-08 01:38:17602 virtual void RestoreActiveTexture() const override {
[email protected]29a4d902013-02-26 20:18:06603 state_.RestoreActiveTexture();
604 }
[email protected]5baa86bc2014-01-16 04:33:16605 virtual void RestoreAllTextureUnitBindings(
mohan.reddy5e1b8952014-10-08 01:38:17606 const ContextState* prev_state) const override {
[email protected]5baa86bc2014-01-16 04:33:16607 state_.RestoreAllTextureUnitBindings(prev_state);
[email protected]217004512013-05-10 21:25:55608 }
[email protected]4b2d2b262014-03-21 22:05:27609 virtual void RestoreActiveTextureUnitBinding(
mohan.reddy5e1b8952014-10-08 01:38:17610 unsigned int target) const override {
[email protected]4b2d2b262014-03-21 22:05:27611 state_.RestoreActiveTextureUnitBinding(target);
612 }
mohan.reddy5e1b8952014-10-08 01:38:17613 virtual void RestoreBufferBindings() const override {
[email protected]29a4d902013-02-26 20:18:06614 state_.RestoreBufferBindings();
615 }
mohan.reddy5e1b8952014-10-08 01:38:17616 virtual void RestoreGlobalState() const override {
[email protected]88ba52f2014-04-09 12:39:34617 state_.RestoreGlobalState(NULL);
[email protected]29a4d902013-02-26 20:18:06618 }
mohan.reddy5e1b8952014-10-08 01:38:17619 virtual void RestoreProgramBindings() const override {
[email protected]29a4d902013-02-26 20:18:06620 state_.RestoreProgramBindings();
621 }
mohan.reddy5e1b8952014-10-08 01:38:17622 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 }
mohan.reddy5e1b8952014-10-08 01:38:17625 virtual void RestoreFramebufferBindings() const override;
626 virtual void RestoreRenderbufferBindings() override;
627 virtual void RestoreTextureState(unsigned service_id) const override;
[email protected]29a4d902013-02-26 20:18:06628
mohan.reddy5e1b8952014-10-08 01:38:17629 virtual void ClearAllAttributes() const override;
630 virtual void RestoreAllAttributes() const override;
[email protected]cd2ef752014-02-12 23:16:03631
mohan.reddy5e1b8952014-10-08 01:38:17632 virtual QueryManager* GetQueryManager() override {
[email protected]b8e97b62012-09-30 15:09:00633 return query_manager_.get();
634 }
mohan.reddy5e1b8952014-10-08 01:38:17635 virtual VertexArrayManager* GetVertexArrayManager() override {
[email protected]944b62f32012-09-27 02:20:46636 return vertex_array_manager_.get();
637 }
mohan.reddy5e1b8952014-10-08 01:38:17638 virtual ImageManager* GetImageManager() override {
[email protected]b63f1d62014-07-18 15:40:59639 return image_manager_.get();
640 }
mohan.reddy5e1b8952014-10-08 01:38:17641 virtual bool ProcessPendingQueries() override;
642 virtual bool HasMoreIdleWork() override;
643 virtual void PerformIdleWork() override;
[email protected]43f28f832010-02-03 02:28:48644
mohan.reddy5e1b8952014-10-08 01:38:17645 virtual void WaitForReadPixels(base::Closure callback) override;
[email protected]5a36dc132013-07-23 23:17:55646
[email protected]9d37f062011-11-22 01:24:52647 virtual void SetResizeCallback(
mohan.reddy5e1b8952014-10-08 01:38:17648 const base::Callback<void(gfx::Size, float)>& callback) override;
[email protected]22f320a2011-08-30 01:17:00649
mohan.reddy5e1b8952014-10-08 01:38:17650 virtual Logger* GetLogger() override;
[email protected]cac16542014-01-15 17:53:51651
mohan.reddy5e1b8952014-10-08 01:38:17652 virtual void BeginDecoding() override;
653 virtual void EndDecoding() override;
[email protected]cac16542014-01-15 17:53:51654
mohan.reddy5e1b8952014-10-08 01:38:17655 virtual ErrorState* GetErrorState() override;
656 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(
mohan.reddy5e1b8952014-10-08 01:38:17659 const ShaderCacheCallback& callback) override;
[email protected]840a7e462013-02-27 01:29:51660 virtual void SetWaitSyncPointCallback(
mohan.reddy5e1b8952014-10-08 01:38:17661 const WaitSyncPointCallback& callback) override;
[email protected]22f320a2011-08-30 01:17:00662
[email protected]85a4ac22013-05-31 01:58:47663 virtual AsyncPixelTransferManager*
mohan.reddy5e1b8952014-10-08 01:38:17664 GetAsyncPixelTransferManager() override;
665 virtual void ResetAsyncPixelTransferManagerForTest() override;
[email protected]498b5c072013-06-04 19:30:07666 virtual void SetAsyncPixelTransferManagerForTest(
mohan.reddy5e1b8952014-10-08 01:38:17667 AsyncPixelTransferManager* manager) override;
668 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,
mohan.reddy5e1b8952014-10-08 01:38:17672 uint32* service_texture_id) override;
[email protected]43f28f832010-02-03 02:28:48673
mohan.reddy5e1b8952014-10-08 01:38:17674 virtual uint32 GetTextureUploadCount() override;
675 virtual base::TimeDelta GetTotalTextureUploadTime() override;
676 virtual base::TimeDelta GetTotalProcessingCommandsTime() override;
677 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
mohan.reddy5e1b8952014-10-08 01:38:17693 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(
mohan.reddy5e1b8952014-10-08 01:38:17697 TextureRef* texture) override;
[email protected]91c94eb2013-10-22 10:32:54698
[email protected]828a3932014-04-02 14:43:13699 // Overriden from ErrorStateClient.
mohan.reddy5e1b8952014-10-08 01:38:17700 virtual void OnOutOfMemoryError() override;
[email protected]828a3932014-04-02 14:43:13701
[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,
mohan.reddy5e1b8952014-10-08 01:38:171167 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
zmo383512cf2014-10-14 00:11:001184 // Check that the currently bound read framebuffer's color image
1185 // isn't the target texture of the glCopyTex{Sub}Image2D.
1186 bool FormsTextureCopyingFeedbackLoop(TextureRef* texture, GLint level);
1187
[email protected]0d6bfdc2011-11-02 01:32:201188 // Check if a framebuffer meets our requirements.
1189 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351190 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201191 GLenum target,
1192 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271193
[email protected]939e7362010-05-13 20:49:101194 // Checks if the current program exists and is valid. If not generates the
1195 // appropriate GL error. Returns true if the current program is in a usable
1196 // state.
1197 bool CheckCurrentProgram(const char* function_name);
1198
1199 // Checks if the current program exists and is valid and that location is not
1200 // -1. If the current program is not valid generates the appropriate GL
1201 // error. Returns true if the current program is in a usable state and
1202 // location is not -1.
1203 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1204
zmof9a81360f2014-10-17 00:06:141205 // Checks if the current program samples a texture that is also the color
1206 // image of the current bound framebuffer, i.e., the source and destination
1207 // of the draw operation are the same.
1208 bool CheckDrawingFeedbackLoops();
1209
[email protected]939e7362010-05-13 20:49:101210 // Gets the type of a uniform for a location in the current program. Sets GL
1211 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361212 // program is valid and the location exists. Adjusts count so it
1213 // does not overflow the uniform.
[email protected]9b1f1b52014-03-12 10:40:131214 bool PrepForSetUniformByLocation(GLint fake_location,
1215 const char* function_name,
1216 Program::UniformApiType api_type,
1217 GLint* real_location,
1218 GLenum* type,
1219 GLsizei* count);
[email protected]939e7362010-05-13 20:49:101220
[email protected]b177ae22011-11-01 03:29:111221 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021222 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111223
[email protected]b273e432010-04-12 17:23:581224 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1225 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1226
[email protected]ac77603c72013-03-08 13:52:061227 // Helper for glGetVertexAttrib
1228 void GetVertexAttribHelper(
1229 const VertexAttrib* attrib, GLenum pname, GLint* param);
1230
[email protected]96449d2c2009-11-25 00:01:321231 // Wrapper for glCreateProgram
[email protected]ae51d192010-04-27 00:48:031232 bool CreateProgramHelper(GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321233
1234 // Wrapper for glCreateShader
[email protected]ae51d192010-04-27 00:48:031235 bool CreateShaderHelper(GLenum type, GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321236
[email protected]3916c97e2010-02-25 03:20:501237 // Wrapper for glActiveTexture
1238 void DoActiveTexture(GLenum texture_unit);
1239
[email protected]ae51d192010-04-27 00:48:031240 // Wrapper for glAttachShader
1241 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1242
[email protected]96449d2c2009-11-25 00:01:321243 // Wrapper for glBindBuffer since we need to track the current targets.
1244 void DoBindBuffer(GLenum target, GLuint buffer);
1245
[email protected]86093972010-03-11 00:13:561246 // Wrapper for glBindFramebuffer since we need to track the current targets.
1247 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1248
1249 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1250 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1251
[email protected]a93bb842010-02-16 23:03:471252 // Wrapper for glBindTexture since we need to track the current targets.
1253 void DoBindTexture(GLenum target, GLuint texture);
1254
[email protected]944b62f32012-09-27 02:20:461255 // Wrapper for glBindVertexArrayOES
1256 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571257 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461258
[email protected]49cabed2013-11-13 18:15:181259 // Wrapper for glBlitFramebufferCHROMIUM.
1260 void DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301261 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1262 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1263 GLbitfield mask, GLenum filter);
1264
[email protected]36cef8ce2010-03-16 07:34:451265 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111266 void DoBufferSubData(
1267 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1268
[email protected]36cef8ce2010-03-16 07:34:451269 // Wrapper for glCheckFramebufferStatus
1270 GLenum DoCheckFramebufferStatus(GLenum target);
1271
[email protected]3a03a8f2011-03-19 00:51:271272 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081273 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271274
[email protected]88a61bf2012-10-27 13:00:421275 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421276 void DoDepthRangef(GLclampf znear, GLclampf zfar);
[email protected]b04e24c2013-01-08 18:35:251277 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281278
[email protected]45bf5152010-02-12 00:11:311279 // Wrapper for glCompileShader.
1280 void DoCompileShader(GLuint shader);
1281
[email protected]ae51d192010-04-27 00:48:031282 // Wrapper for glDetachShader
1283 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1284
[email protected]3a2e7c7b2010-08-06 01:12:281285 // Wrapper for glDisable
1286 void DoDisable(GLenum cap);
1287
[email protected]07f54fcc2009-12-22 02:46:301288 // Wrapper for glDisableVertexAttribArray.
1289 void DoDisableVertexAttribArray(GLuint index);
1290
[email protected]60f22d32012-12-12 00:31:581291 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1292 // attachments.
1293 void DoDiscardFramebufferEXT(GLenum target,
1294 GLsizei numAttachments,
1295 const GLenum* attachments);
1296
[email protected]3a2e7c7b2010-08-06 01:12:281297 // Wrapper for glEnable
1298 void DoEnable(GLenum cap);
1299
[email protected]07f54fcc2009-12-22 02:46:301300 // Wrapper for glEnableVertexAttribArray.
1301 void DoEnableVertexAttribArray(GLuint index);
1302
[email protected]882ba1e22012-03-08 19:02:531303 // Wrapper for glFinish.
1304 void DoFinish();
1305
1306 // Wrapper for glFlush.
1307 void DoFlush();
1308
[email protected]36cef8ce2010-03-16 07:34:451309 // Wrapper for glFramebufferRenderbufffer.
1310 void DoFramebufferRenderbuffer(
1311 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1312 GLuint renderbuffer);
1313
1314 // Wrapper for glFramebufferTexture2D.
1315 void DoFramebufferTexture2D(
1316 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1317 GLint level);
1318
[email protected]7d3c36e2013-07-12 14:13:161319 // Wrapper for glFramebufferTexture2DMultisampleEXT.
1320 void DoFramebufferTexture2DMultisample(
1321 GLenum target, GLenum attachment, GLenum textarget,
1322 GLuint texture, GLint level, GLsizei samples);
1323
1324 // Common implementation for both DoFramebufferTexture2D wrappers.
1325 void DoFramebufferTexture2DCommon(const char* name,
1326 GLenum target, GLenum attachment, GLenum textarget,
1327 GLuint texture, GLint level, GLsizei samples);
1328
[email protected]a93bb842010-02-16 23:03:471329 // Wrapper for glGenerateMipmap
1330 void DoGenerateMipmap(GLenum target);
1331
[email protected]7d3c36e2013-07-12 14:13:161332 // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname
1333 // to account for different pname values defined in different extension
1334 // variants.
1335 GLenum AdjustGetPname(GLenum pname);
1336
[email protected]b273e432010-04-12 17:23:581337 // Wrapper for DoGetBooleanv.
1338 void DoGetBooleanv(GLenum pname, GLboolean* params);
1339
1340 // Wrapper for DoGetFloatv.
1341 void DoGetFloatv(GLenum pname, GLfloat* params);
1342
[email protected]36cef8ce2010-03-16 07:34:451343 // Wrapper for glGetFramebufferAttachmentParameteriv.
1344 void DoGetFramebufferAttachmentParameteriv(
1345 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1346
[email protected]a0c3e972010-04-21 00:49:131347 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581348 void DoGetIntegerv(GLenum pname, GLint* params);
1349
[email protected]29a9eb52010-04-13 09:04:231350 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061351 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231352 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1353
[email protected]17cfbe0e2013-03-07 01:26:081354 // Wrapper for glGetBufferParameteriv.
1355 void DoGetBufferParameteriv(
1356 GLenum target, GLenum pname, GLint* params);
1357
[email protected]a0c3e972010-04-21 00:49:131358 // Wrapper for glGetProgramiv.
1359 void DoGetProgramiv(
1360 GLuint program_id, GLenum pname, GLint* params);
1361
[email protected]36cef8ce2010-03-16 07:34:451362 // Wrapper for glRenderbufferParameteriv.
1363 void DoGetRenderbufferParameteriv(
1364 GLenum target, GLenum pname, GLint* params);
1365
[email protected]ddd968b82010-03-02 00:44:291366 // Wrapper for glGetShaderiv
1367 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1368
[email protected]4c6f5462014-03-05 00:26:561369 // Wrappers for glGetTexParameter.
1370 void DoGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
1371 void DoGetTexParameteriv(GLenum target, GLenum pname, GLint* params);
1372 void InitTextureMaxAnisotropyIfNeeded(GLenum target, GLenum pname);
1373
[email protected]b1122982010-05-17 23:04:241374 // Wrappers for glGetVertexAttrib.
1375 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1376 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1377
[email protected]1958e0e2010-04-22 05:17:151378 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241379 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151380 bool DoIsBuffer(GLuint client_id);
1381 bool DoIsFramebuffer(GLuint client_id);
1382 bool DoIsProgram(GLuint client_id);
1383 bool DoIsRenderbuffer(GLuint client_id);
1384 bool DoIsShader(GLuint client_id);
1385 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461386 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151387
[email protected]07f54fcc2009-12-22 02:46:301388 // Wrapper for glLinkProgram
1389 void DoLinkProgram(GLuint program);
1390
[email protected]36cef8ce2010-03-16 07:34:451391 // Wrapper for glRenderbufferStorage.
1392 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031393 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451394
[email protected]49cabed2013-11-13 18:15:181395 // Handler for glRenderbufferStorageMultisampleCHROMIUM.
1396 void DoRenderbufferStorageMultisampleCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301397 GLenum target, GLsizei samples, GLenum internalformat,
1398 GLsizei width, GLsizei height);
1399
[email protected]49cabed2013-11-13 18:15:181400 // Handler for glRenderbufferStorageMultisampleEXT
1401 // (multisampled_render_to_texture).
1402 void DoRenderbufferStorageMultisampleEXT(
1403 GLenum target, GLsizei samples, GLenum internalformat,
1404 GLsizei width, GLsizei height);
1405
1406 // Common validation for multisample extensions.
1407 bool ValidateRenderbufferStorageMultisample(GLsizei samples,
1408 GLenum internalformat,
1409 GLsizei width,
1410 GLsizei height);
1411
[email protected]4a4c18b2013-09-13 22:50:101412 // Verifies that the currently bound multisample renderbuffer is valid
1413 // Very slow! Only done on platforms with driver bugs that return invalid
1414 // buffers under memory pressure
1415 bool VerifyMultisampleRenderbufferIntegrity(
1416 GLuint renderbuffer, GLenum format);
1417
[email protected]b273e432010-04-12 17:23:581418 // Wrapper for glReleaseShaderCompiler.
1419 void DoReleaseShaderCompiler() { }
1420
[email protected]3916c97e2010-02-25 03:20:501421 // Wrappers for glTexParameter functions.
1422 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1423 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1424 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1425 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1426
1427 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1428 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121429 void DoUniform1i(GLint fake_location, GLint v0);
1430 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1431 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1432 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1433 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101434
1435 // Wrappers for glUniformfv because some drivers don't correctly accept
1436 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121437 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1438 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1439 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1440 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501441
[email protected]43c2f1f2011-03-25 18:35:361442 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121443 GLint fake_location, GLsizei count, GLboolean transpose,
1444 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361445 void DoUniformMatrix3fv(
[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 DoUniformMatrix4fv(
[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
[email protected]af6380962012-11-29 23:24:131452 bool SetVertexAttribValue(
1453 const char* function_name, GLuint index, const GLfloat* value);
1454
[email protected]b1122982010-05-17 23:04:241455 // Wrappers for glVertexAttrib??
1456 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1457 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1458 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1459 void DoVertexAttrib4f(
1460 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1461 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1462 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1463 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1464 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1465
[email protected]43410e92012-04-20 17:06:281466 // Wrapper for glViewport
1467 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1468
[email protected]07f54fcc2009-12-22 02:46:301469 // Wrapper for glUseProgram
1470 void DoUseProgram(GLuint program);
1471
[email protected]ae51d192010-04-27 00:48:031472 // Wrapper for glValidateProgram.
1473 void DoValidateProgram(GLuint program_client_id);
1474
[email protected]d2a0e1a2012-08-12 02:25:011475 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1476 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1477 void DoPopGroupMarkerEXT(void);
1478
[email protected]4e8a5b122010-05-08 22:00:101479 // Gets the number of values that will be returned by glGetXXX. Returns
1480 // false if pname is unknown.
1481 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1482
[email protected]07f54fcc2009-12-22 02:46:301483 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431484 bool IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:101485 const char* function_name, GLuint max_vertex_accessed, bool instanced,
1486 GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301487
[email protected]c13e1da62011-09-09 21:48:301488 // Returns true if successful, simulated will be true if attrib0 was
1489 // simulated.
[email protected]c6aef902012-02-14 03:31:421490 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431491 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]3fc38e22014-05-30 00:13:231492 void RestoreStateForAttrib(GLuint attrib, bool restore_array_binding);
[email protected]b1122982010-05-17 23:04:241493
[email protected]91c94eb2013-10-22 10:32:541494 // If an image is bound to texture, this will call Will/DidUseTexImage
1495 // if needed.
1496 void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1497 void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1498
1499 // Returns false if textures were replaced.
[email protected]e56131d22013-07-28 16:14:111500 bool PrepareTexturesForRender();
[email protected]91c94eb2013-10-22 10:32:541501 void RestoreStateForTextures();
[email protected]3916c97e2010-02-25 03:20:501502
[email protected]8fbedc02010-11-18 18:43:401503 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421504 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431505 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421506 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401507 void RestoreStateForSimulatedFixedAttribs();
1508
[email protected]c6aef902012-02-14 03:31:421509 // Handle DrawArrays and DrawElements for both instanced and non-instanced
[email protected]ac6904d62014-07-30 12:00:101510 // cases (primcount is always 1 for non-instanced).
[email protected]c6aef902012-02-14 03:31:421511 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431512 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421513 bool instanced, GLenum mode, GLint first, GLsizei count,
1514 GLsizei primcount);
1515 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431516 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421517 bool instanced, GLenum mode, GLsizei count, GLenum type,
1518 int32 offset, GLsizei primcount);
1519
[email protected]61eeb33f2011-07-26 15:30:311520 GLenum GetBindTargetForSamplerType(GLenum type) {
1521 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461522 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1523 switch (type) {
1524 case GL_SAMPLER_2D:
1525 return GL_TEXTURE_2D;
1526 case GL_SAMPLER_CUBE:
1527 return GL_TEXTURE_CUBE_MAP;
1528 case GL_SAMPLER_EXTERNAL_OES:
1529 return GL_TEXTURE_EXTERNAL_OES;
1530 case GL_SAMPLER_2D_RECT_ARB:
1531 return GL_TEXTURE_RECTANGLE_ARB;
1532 }
1533
1534 NOTREACHED();
1535 return 0;
[email protected]61eeb33f2011-07-26 15:30:311536 }
1537
[email protected]8e3e0662010-08-23 18:46:301538 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061539 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1540 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301541 switch (target) {
1542 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451543 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341544 framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301545 break;
[email protected]ebfb73c2012-08-15 02:37:451546 case GL_READ_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341547 framebuffer = framebuffer_state_.bound_read_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301548 break;
1549 default:
1550 NOTREACHED();
1551 break;
1552 }
[email protected]4d8f0dd2013-03-09 14:37:061553 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301554 }
1555
[email protected]ed9f9cd2013-02-27 21:12:351556 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201557 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271558 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201559 switch (target) {
1560 case GL_RENDERBUFFER:
[email protected]7cd76fd2013-06-02 21:11:111561 renderbuffer = state_.bound_renderbuffer.get();
[email protected]0d6bfdc2011-11-02 01:32:201562 break;
1563 default:
1564 NOTREACHED();
1565 break;
1566 }
[email protected]ee2a79c32013-03-10 03:50:271567 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201568 }
1569
[email protected]f7b85372010-02-03 01:11:371570 // Validates the program and location for a glGetUniform call and returns
1571 // a SizeResult setup to receive the result. Returns true if glGetUniform
1572 // should be called.
1573 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121574 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371575 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121576 error::Error* error, GLint* real_location, GLuint* service_id,
1577 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371578
jbauman7a059312014-10-16 19:30:541579 void MaybeExitOnContextLost();
mohan.reddy5e1b8952014-10-08 01:38:171580 virtual bool WasContextLost() override;
1581 virtual bool WasContextLostByRobustnessExtension() override;
1582 virtual void LoseContext(uint32 reset_status) override;
[email protected]38d139d2011-07-14 00:38:431583
[email protected]e51bdf32011-11-23 22:21:461584#if defined(OS_MACOSX)
1585 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1586#endif
1587
[email protected]ad84a3a2012-06-08 21:42:431588 bool ValidateCompressedTexDimensions(
1589 const char* function_name,
1590 GLint level, GLsizei width, GLsizei height, GLenum format);
1591 bool ValidateCompressedTexFuncData(
1592 const char* function_name,
1593 GLsizei width, GLsizei height, GLenum format, size_t size);
1594 bool ValidateCompressedTexSubDimensions(
1595 const char* function_name,
1596 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1597 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351598 Texture* texture);
[email protected]ad84a3a2012-06-08 21:42:431599
[email protected]ab09b612013-03-11 22:11:511600 void RenderWarning(const char* filename, int line, const std::string& msg);
1601 void PerformanceWarning(
1602 const char* filename, int line, const std::string& msg);
[email protected]0f8afe82012-05-14 23:43:011603
[email protected]62e155e2012-10-23 22:43:151604 const FeatureInfo::FeatureFlags& features() const {
1605 return feature_info_->feature_flags();
1606 }
1607
1608 const FeatureInfo::Workarounds& workarounds() const {
1609 return feature_info_->workarounds();
1610 }
1611
[email protected]a7266a92012-06-28 02:11:081612 bool ShouldDeferDraws() {
1613 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341614 framebuffer_state_.bound_draw_framebuffer.get() == NULL &&
[email protected]a7266a92012-06-28 02:11:081615 surface_->DeferDraws();
1616 }
1617
[email protected]09e17272012-11-30 10:30:441618 bool ShouldDeferReads() {
1619 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341620 framebuffer_state_.bound_read_framebuffer.get() == NULL &&
[email protected]09e17272012-11-30 10:30:441621 surface_->DeferDraws();
1622 }
1623
[email protected]c76fe672013-12-13 23:30:221624 error::Error WillAccessBoundFramebufferForDraw() {
1625 if (ShouldDeferDraws())
1626 return error::kDeferCommandUntilLater;
1627 if (!offscreen_target_frame_buffer_.get() &&
1628 !framebuffer_state_.bound_draw_framebuffer.get() &&
1629 !surface_->SetBackbufferAllocation(true))
1630 return error::kLostContext;
1631 return error::kNoError;
1632 }
1633
1634 error::Error WillAccessBoundFramebufferForRead() {
1635 if (ShouldDeferReads())
1636 return error::kDeferCommandUntilLater;
1637 if (!offscreen_target_frame_buffer_.get() &&
1638 !framebuffer_state_.bound_read_framebuffer.get() &&
1639 !surface_->SetBackbufferAllocation(true))
1640 return error::kLostContext;
1641 return error::kNoError;
1642 }
1643
vmiura8266ca72014-09-09 21:37:001644 // Set remaining commands to process to 0 to force DoCommands to return
1645 // and allow context preemption and GPU watchdog checks in GpuScheduler().
1646 void ExitCommandProcessingEarly() { commands_to_process_ = 0; }
1647
[email protected]5a36dc132013-07-23 23:17:551648 void ProcessPendingReadPixels();
1649 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
1650
[email protected]96449d2c2009-11-25 00:01:321651 // Generate a member function prototype for each command in an automated and
1652 // typesafe way.
vmiuracd108592014-09-08 14:36:341653#define GLES2_CMD_OP(name) \
1654 Error Handle##name(uint32 immediate_data_size, const void* data);
[email protected]96449d2c2009-11-25 00:01:321655
1656 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1657
1658 #undef GLES2_CMD_OP
1659
[email protected]2f2d7042010-04-14 21:45:581660 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381661 scoped_refptr<gfx::GLSurface> surface_;
1662 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021663
[email protected]a3ded6d2010-10-19 06:44:391664 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351665 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391666
[email protected]1d82e822013-04-10 21:32:321667 DebugMarkerManager debug_marker_manager_;
1668 Logger logger_;
1669
[email protected]e259eb412012-10-13 05:47:241670 // All the state for this context.
1671 ContextState state_;
1672
[email protected]34ff8b0c2010-10-01 20:06:021673 // Current width and height of the offscreen frame buffer.
1674 gfx::Size offscreen_size_;
1675
[email protected]96449d2c2009-11-25 00:01:321676 // Util to help with GL.
1677 GLES2Util util_;
1678
[email protected]43410e92012-04-20 17:06:281679 // unpack flip y as last set by glPixelStorei
1680 bool unpack_flip_y_;
1681
[email protected]6c75c712012-06-19 15:43:171682 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281683 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171684 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281685
[email protected]b1122982010-05-17 23:04:241686 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1687 GLuint attrib_0_buffer_id_;
1688
1689 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131690 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241691
[email protected]fc753442011-02-04 19:49:491692 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1693 bool attrib_0_buffer_matches_value_;
1694
[email protected]b1122982010-05-17 23:04:241695 // The size of attrib 0.
1696 GLsizei attrib_0_size_;
1697
[email protected]8fbedc02010-11-18 18:43:401698 // The buffer used to simulate GL_FIXED attribs.
1699 GLuint fixed_attrib_buffer_id_;
1700
1701 // The size of fiixed attrib buffer.
1702 GLsizei fixed_attrib_buffer_size_;
1703
[email protected]b9363b22010-06-09 22:06:151704 // The offscreen frame buffer that the client renders to. With EGL, the
1705 // depth and stencil buffers are separate. With regular GL there is a single
1706 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1707 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351708 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1709 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1710 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1711 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1712 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021713 GLenum offscreen_target_color_format_;
1714 GLenum offscreen_target_depth_format_;
1715 GLenum offscreen_target_stencil_format_;
1716 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561717 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351718
[email protected]de26b3c2011-08-03 21:54:271719 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351720 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1721 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
[email protected]370eaf12013-05-18 09:19:491722 scoped_refptr<TextureRef>
[email protected]ed9f9cd2013-02-27 21:12:351723 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271724
1725 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351726 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1727 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051728 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351729
[email protected]882ba1e22012-03-08 19:02:531730 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531731
[email protected]944b62f32012-09-27 02:20:461732 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1733
[email protected]b63f1d62014-07-18 15:40:591734 scoped_ptr<ImageManager> image_manager_;
1735
[email protected]729c0b42013-05-26 02:05:071736 base::Callback<void(gfx::Size, float)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001737
[email protected]840a7e462013-02-27 01:29:511738 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481739
[email protected]e3932abb2013-03-13 00:01:371740 ShaderCacheCallback shader_cache_callback_;
1741
[email protected]85a4ac22013-05-31 01:58:471742 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
[email protected]b0af4f52011-09-28 22:04:421743
[email protected]32fe9aa2011-01-21 23:47:131744 // The format of the back buffer_
1745 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461746 bool back_buffer_has_depth_;
1747 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131748
achaulkcf5316f2014-09-26 19:28:421749 bool surfaceless_;
1750
[email protected]60f22d32012-12-12 00:31:581751 // Backbuffer attachments that are currently undefined.
1752 uint32 backbuffer_needs_clear_bits_;
1753
[email protected]a6a09f852014-05-23 13:05:031754 // The current decoder error communicates the decoder error through command
1755 // processing functions that do not return the error value. Should be set only
1756 // if not returning an error.
[email protected]a3a93e7b2010-08-28 00:48:561757 error::Error current_decoder_error_;
1758
[email protected]b1d2dcb2010-05-17 19:24:181759 bool use_shader_translator_;
[email protected]87fb6ab2012-06-13 22:28:041760 scoped_refptr<ShaderTranslator> vertex_translator_;
1761 scoped_refptr<ShaderTranslator> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181762
[email protected]e82fb792011-09-22 00:33:291763 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411764
[email protected]915a59a12010-09-30 21:29:111765 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051766 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351767 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051768
[email protected]65225772011-05-12 21:10:241769 int frame_number_;
1770
vmiura8266ca72014-09-09 21:37:001771 // Number of commands remaining to be processed in DoCommands().
1772 int commands_to_process_;
1773
[email protected]706b69f2012-07-27 04:59:301774 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431775 GLenum reset_status_;
[email protected]93a7d98f2013-07-11 00:04:221776 bool reset_by_robustness_extension_;
[email protected]b381ee32014-03-22 02:43:431777 bool supports_post_sub_buffer_;
[email protected]38d139d2011-07-14 00:38:431778
[email protected]f0d74742011-10-03 16:31:041779 // These flags are used to override the state of the shared feature_info_
1780 // member. Because the same FeatureInfo instance may be shared among many
1781 // contexts, the assumptions on the availablity of extensions in WebGL
1782 // contexts may be broken. These flags override the shared state to preserve
1783 // WebGL semantics.
1784 bool force_webgl_glsl_validation_;
1785 bool derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:491786 bool frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:131787 bool draw_buffers_explicitly_enabled_;
[email protected]93c2fd82014-04-16 02:46:061788 bool shader_texture_lod_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:041789
[email protected]062c38b2012-01-18 03:25:101790 bool compile_shader_always_succeeds_;
1791
[email protected]828a3932014-04-02 14:43:131792 // An optional behaviour to lose the context and group when OOM.
1793 bool lose_context_when_out_of_memory_;
1794
[email protected]cae20172012-12-07 00:06:191795 // Log extra info.
1796 bool service_logging_;
1797
[email protected]e51bdf32011-11-23 22:21:461798#if defined(OS_MACOSX)
[email protected]c3a6b4a2014-06-04 09:25:531799 typedef std::map<GLuint, IOSurfaceRef> TextureToIOSurfaceMap;
[email protected]e51bdf32011-11-23 22:21:461800 TextureToIOSurfaceMap texture_to_io_surface_map_;
1801#endif
1802
[email protected]43410e92012-04-20 17:06:281803 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
1804
[email protected]1868a342012-11-07 15:56:021805 // Cached values of the currently assigned viewport dimensions.
1806 GLsizei viewport_max_width_;
1807 GLsizei viewport_max_height_;
1808
[email protected]63b465922012-09-06 02:04:521809 // Command buffer stats.
[email protected]63b465922012-09-06 02:04:521810 base::TimeDelta total_processing_commands_time_;
1811
[email protected]c986af502013-08-14 01:04:441812 // States related to each manager.
1813 DecoderTextureState texture_state_;
1814 DecoderFramebufferState framebuffer_state_;
1815
[email protected]fb97b662013-02-20 23:02:141816 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]8f9b8dd2013-09-12 18:05:131817 scoped_ptr<GPUStateTracer> gpu_state_tracer_;
vmiura1c2b1de2014-09-19 19:03:241818 const unsigned char* cb_command_trace_category_;
[email protected]cac16542014-01-15 17:53:511819 int gpu_trace_level_;
1820 bool gpu_trace_commands_;
vmiura1c2b1de2014-09-19 19:03:241821 bool gpu_debug_commands_;
[email protected]94307712012-11-16 23:26:111822
[email protected]5a36dc132013-07-23 23:17:551823 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_;
1824
[email protected]4a4c18b2013-09-13 22:50:101825 // Used to validate multisample renderbuffers if needed
1826 GLuint validation_texture_;
1827 GLuint validation_fbo_multisample_;
1828 GLuint validation_fbo_;
1829
vmiuracd108592014-09-08 14:36:341830 typedef gpu::gles2::GLES2Decoder::Error (GLES2DecoderImpl::*CmdHandler)(
1831 uint32 immediate_data_size,
1832 const void* data);
1833
1834 // A struct to hold info about each command.
1835 struct CommandInfo {
1836 CmdHandler cmd_handler;
1837 uint8 arg_flags; // How to handle the arguments for this command
1838 uint8 cmd_flags; // How to handle this command
1839 uint16 arg_count; // How many arguments are expected for this command.
1840 };
1841
1842 // A table of CommandInfo for all the commands.
1843 static const CommandInfo command_info[kNumCommands - kStartPoint];
1844
[email protected]96449d2c2009-11-25 00:01:321845 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1846};
1847
vmiuracd108592014-09-08 14:36:341848const GLES2DecoderImpl::CommandInfo GLES2DecoderImpl::command_info[] = {
1849#define GLES2_CMD_OP(name) \
1850 { \
1851 &GLES2DecoderImpl::Handle##name, cmds::name::kArgFlags, \
1852 cmds::name::cmd_flags, \
1853 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, \
1854 } \
1855 , /* NOLINT */
1856 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1857#undef GLES2_CMD_OP
1858};
1859
[email protected]ab09b612013-03-11 22:11:511860ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:301861 const char* function_name, ErrorState* error_state)
[email protected]ab09b612013-03-11 22:11:511862 : function_name_(function_name),
[email protected]40621eb52013-10-08 15:40:301863 error_state_(error_state) {
1864 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351865}
1866
1867ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]40621eb52013-10-08 15:40:301868 ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351869}
1870
[email protected]2b10c02d2014-01-29 16:43:021871static void RestoreCurrentTextureBindings(ContextState* state, GLenum target) {
[email protected]ce296892013-10-24 22:04:361872 TextureUnit& info = state->texture_units[0];
1873 GLuint last_id;
[email protected]2b10c02d2014-01-29 16:43:021874 scoped_refptr<TextureRef> texture_ref;
1875 switch (target) {
1876 case GL_TEXTURE_2D:
1877 texture_ref = info.bound_texture_2d;
1878 break;
1879 case GL_TEXTURE_CUBE_MAP:
1880 texture_ref = info.bound_texture_cube_map;
1881 break;
1882 case GL_TEXTURE_EXTERNAL_OES:
1883 texture_ref = info.bound_texture_external_oes;
1884 break;
1885 case GL_TEXTURE_RECTANGLE_ARB:
1886 texture_ref = info.bound_texture_rectangle_arb;
1887 break;
1888 default:
1889 NOTREACHED();
1890 break;
1891 }
1892 if (texture_ref.get()) {
1893 last_id = texture_ref->service_id();
[email protected]ce296892013-10-24 22:04:361894 } else {
1895 last_id = 0;
1896 }
1897
[email protected]2b10c02d2014-01-29 16:43:021898 glBindTexture(target, last_id);
[email protected]ce296892013-10-24 22:04:361899 glActiveTexture(GL_TEXTURE0 + state->active_texture_unit);
1900}
1901
[email protected]2b10c02d2014-01-29 16:43:021902ScopedTextureBinder::ScopedTextureBinder(ContextState* state,
1903 GLuint id,
1904 GLenum target)
1905 : state_(state),
1906 target_(target) {
[email protected]ab09b612013-03-11 22:11:511907 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021908 "ScopedTextureBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351909
1910 // TODO(apatrick): Check if there are any other states that need to be reset
1911 // before binding a new texture.
1912 glActiveTexture(GL_TEXTURE0);
[email protected]2b10c02d2014-01-29 16:43:021913 glBindTexture(target, id);
[email protected]6217d392010-03-25 22:08:351914}
1915
[email protected]2b10c02d2014-01-29 16:43:021916ScopedTextureBinder::~ScopedTextureBinder() {
[email protected]ab09b612013-03-11 22:11:511917 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021918 "ScopedTextureBinder::dtor", state_->GetErrorState());
1919 RestoreCurrentTextureBindings(state_, target_);
[email protected]6217d392010-03-25 22:08:351920}
1921
[email protected]18e785a2013-10-09 03:29:411922ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state,
[email protected]6217d392010-03-25 22:08:351923 GLuint id)
[email protected]18e785a2013-10-09 03:29:411924 : state_(state) {
[email protected]ab09b612013-03-11 22:11:511925 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411926 "ScopedRenderBufferBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351927 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1928}
1929
1930ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511931 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411932 "ScopedRenderBufferBinder::dtor", state_->GetErrorState());
1933 state_->RestoreRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:351934}
1935
1936ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1937 GLuint id)
1938 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511939 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301940 "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351941 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:451942 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:351943}
1944
1945ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511946 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301947 "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]8e3e0662010-08-23 18:46:301948 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:351949}
1950
[email protected]34ff8b0c2010-10-01 20:06:021951ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:271952 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:521953 : decoder_(decoder) {
[email protected]9d3b2e12013-10-02 01:04:341954 resolve_and_bind_ = (
1955 decoder_->offscreen_target_frame_buffer_.get() &&
1956 decoder_->IsOffscreenBufferMultisampled() &&
1957 (!decoder_->framebuffer_state_.bound_read_framebuffer.get() ||
1958 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:021959 if (!resolve_and_bind_)
1960 return;
1961
[email protected]ab09b612013-03-11 22:11:511962 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301963 "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:021964 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
1965 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:271966 GLuint targetid;
1967 if (internal) {
1968 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
1969 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:351970 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:271971 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:351972 decoder_->offscreen_resolved_color_texture_.reset(
[email protected]ce296892013-10-24 22:04:361973 new BackTexture(decoder->memory_tracker(), &decoder->state_));
[email protected]de26b3c2011-08-03 21:54:271974 decoder_->offscreen_resolved_color_texture_->Create();
1975
1976 DCHECK(decoder_->offscreen_saved_color_format_);
1977 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:091978 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
1979 false);
[email protected]de26b3c2011-08-03 21:54:271980 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
1981 decoder_->offscreen_resolved_color_texture_.get());
1982 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
1983 GL_FRAMEBUFFER_COMPLETE) {
1984 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
1985 << "because offscreen resolved FBO was incomplete.";
1986 return;
1987 }
1988 }
1989 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
1990 } else {
1991 targetid = decoder_->offscreen_saved_frame_buffer_->id();
1992 }
1993 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021994 const int width = decoder_->offscreen_size_.width();
1995 const int height = decoder_->offscreen_size_.height();
[email protected]454157e2014-05-03 02:49:451996 decoder->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f42f05b2013-11-15 21:46:181997 decoder->BlitFramebufferHelper(0,
1998 0,
1999 width,
2000 height,
2001 0,
2002 0,
2003 width,
2004 height,
2005 GL_COLOR_BUFFER_BIT,
2006 GL_NEAREST);
[email protected]de26b3c2011-08-03 21:54:272007 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:022008}
2009
2010ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
2011 if (!resolve_and_bind_)
2012 return;
2013
[email protected]ab09b612013-03-11 22:11:512014 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302015 "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:022016 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:222017 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:452018 decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]8c3e68782010-10-27 16:41:182019 }
[email protected]34ff8b0c2010-10-01 20:06:022020}
2021
[email protected]ce296892013-10-24 22:04:362022BackTexture::BackTexture(
2023 MemoryTracker* memory_tracker,
2024 ContextState* state)
2025 : memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2026 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482027 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252028 id_(0) {
[email protected]6217d392010-03-25 22:08:352029}
2030
[email protected]ed9f9cd2013-02-27 21:12:352031BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:352032 // This does not destroy the render texture because that would require that
2033 // the associated GL context was current. Just check that it was explicitly
2034 // destroyed.
2035 DCHECK_EQ(id_, 0u);
2036}
2037
[email protected]ed9f9cd2013-02-27 21:12:352038void BackTexture::Create() {
[email protected]40621eb52013-10-08 15:40:302039 ScopedGLErrorSuppressor suppressor("BackTexture::Create",
[email protected]ce296892013-10-24 22:04:362040 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352041 Destroy();
2042 glGenTextures(1, &id_);
[email protected]2b10c02d2014-01-29 16:43:022043 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]eeeb07b92014-08-16 07:46:262044 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2045 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
[email protected]3a4d0c52011-06-29 23:11:582046 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2047 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:162048
2049 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
2050 // never called on an offscreen context, no data will ever be uploaded to the
2051 // saved offscreen color texture (it is deferred until to when SwapBuffers
2052 // is called). My idea is that some nvidia drivers might have a bug where
2053 // deleting a texture that has never been populated might cause a
2054 // crash.
2055 glTexImage2D(
2056 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:482057
2058 bytes_allocated_ = 16u * 16u * 4u;
2059 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:352060}
2061
[email protected]ed9f9cd2013-02-27 21:12:352062bool BackTexture::AllocateStorage(
2063 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:352064 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302065 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage",
[email protected]ce296892013-10-24 22:04:362066 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022067 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]678a73f2012-12-19 19:22:092068 uint32 image_size = 0;
2069 GLES2Util::ComputeImageDataSizes(
2070 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size,
2071 NULL, NULL);
2072
[email protected]7989c9e2013-01-23 06:39:262073 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
2074 return false;
2075 }
2076
[email protected]40d90a22013-04-09 03:39:552077 scoped_ptr<char[]> zero_data;
[email protected]678a73f2012-12-19 19:22:092078 if (zero) {
2079 zero_data.reset(new char[image_size]);
2080 memset(zero_data.get(), 0, image_size);
2081 }
[email protected]6217d392010-03-25 22:08:352082
[email protected]8f1d2aa2013-05-10 23:45:382083 glTexImage2D(GL_TEXTURE_2D,
2084 0, // mip level
2085 format,
2086 size.width(),
2087 size.height(),
2088 0, // border
2089 format,
2090 GL_UNSIGNED_BYTE,
2091 zero_data.get());
[email protected]6217d392010-03-25 22:08:352092
[email protected]d37231fa2010-04-09 21:16:022093 size_ = size;
2094
[email protected]1078f912011-12-23 13:12:142095 bool success = glGetError() == GL_NO_ERROR;
2096 if (success) {
[email protected]68e81a4a62012-12-13 01:16:482097 memory_tracker_.TrackMemFree(bytes_allocated_);
2098 bytes_allocated_ = image_size;
2099 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142100 }
2101 return success;
[email protected]6217d392010-03-25 22:08:352102}
2103
[email protected]ed9f9cd2013-02-27 21:12:352104void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:352105 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302106 ScopedGLErrorSuppressor suppressor("BackTexture::Copy",
[email protected]ce296892013-10-24 22:04:362107 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022108 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]6217d392010-03-25 22:08:352109 glCopyTexImage2D(GL_TEXTURE_2D,
2110 0, // level
[email protected]3a4d0c52011-06-29 23:11:582111 format,
[email protected]6217d392010-03-25 22:08:352112 0, 0,
2113 size.width(),
2114 size.height(),
2115 0); // border
2116}
2117
[email protected]ed9f9cd2013-02-27 21:12:352118void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:352119 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302120 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy",
[email protected]ce296892013-10-24 22:04:362121 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352122 glDeleteTextures(1, &id_);
2123 id_ = 0;
2124 }
[email protected]68e81a4a62012-12-13 01:16:482125 memory_tracker_.TrackMemFree(bytes_allocated_);
2126 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352127}
2128
[email protected]ed9f9cd2013-02-27 21:12:352129void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:052130 id_ = 0;
2131}
2132
[email protected]d5a28e452013-10-10 01:01:402133BackRenderbuffer::BackRenderbuffer(
2134 RenderbufferManager* renderbuffer_manager,
2135 MemoryTracker* memory_tracker,
2136 ContextState* state)
2137 : renderbuffer_manager_(renderbuffer_manager),
2138 memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2139 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482140 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252141 id_(0) {
[email protected]6217d392010-03-25 22:08:352142}
2143
[email protected]ed9f9cd2013-02-27 21:12:352144BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:352145 // This does not destroy the render buffer because that would require that
2146 // the associated GL context was current. Just check that it was explicitly
2147 // destroyed.
2148 DCHECK_EQ(id_, 0u);
2149}
2150
[email protected]ed9f9cd2013-02-27 21:12:352151void BackRenderbuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302152 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create",
[email protected]d5a28e452013-10-10 01:01:402153 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352154 Destroy();
2155 glGenRenderbuffersEXT(1, &id_);
2156}
2157
[email protected]f42f05b2013-11-15 21:46:182158bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info,
2159 const gfx::Size& size,
2160 GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:352161 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:512162 ScopedGLErrorSuppressor suppressor(
[email protected]d5a28e452013-10-10 01:01:402163 "BackRenderbuffer::AllocateStorage", state_->GetErrorState());
2164 ScopedRenderBufferBinder binder(state_, id_);
[email protected]7989c9e2013-01-23 06:39:262165
2166 uint32 estimated_size = 0;
[email protected]d5a28e452013-10-10 01:01:402167 if (!renderbuffer_manager_->ComputeEstimatedRenderbufferSize(
[email protected]8e102e102013-09-20 22:50:232168 size.width(), size.height(), samples, format, &estimated_size)) {
[email protected]7989c9e2013-01-23 06:39:262169 return false;
2170 }
2171
2172 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
2173 return false;
2174 }
2175
[email protected]34ff8b0c2010-10-01 20:06:022176 if (samples <= 1) {
2177 glRenderbufferStorageEXT(GL_RENDERBUFFER,
2178 format,
2179 size.width(),
2180 size.height());
2181 } else {
[email protected]f42f05b2013-11-15 21:46:182182 GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info,
2183 GL_RENDERBUFFER,
2184 samples,
2185 format,
2186 size.width(),
2187 size.height());
[email protected]34ff8b0c2010-10-01 20:06:022188 }
[email protected]1078f912011-12-23 13:12:142189 bool success = glGetError() == GL_NO_ERROR;
2190 if (success) {
[email protected]d5a28e452013-10-10 01:01:402191 // Mark the previously allocated bytes as free.
[email protected]68e81a4a62012-12-13 01:16:482192 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:262193 bytes_allocated_ = estimated_size;
[email protected]d5a28e452013-10-10 01:01:402194 // Track the newly allocated bytes.
[email protected]68e81a4a62012-12-13 01:16:482195 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142196 }
2197 return success;
[email protected]6217d392010-03-25 22:08:352198}
2199
[email protected]ed9f9cd2013-02-27 21:12:352200void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352201 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302202 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy",
[email protected]d5a28e452013-10-10 01:01:402203 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352204 glDeleteRenderbuffersEXT(1, &id_);
2205 id_ = 0;
2206 }
[email protected]68e81a4a62012-12-13 01:16:482207 memory_tracker_.TrackMemFree(bytes_allocated_);
2208 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352209}
2210
[email protected]ed9f9cd2013-02-27 21:12:352211void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052212 id_ = 0;
2213}
2214
[email protected]ed9f9cd2013-02-27 21:12:352215BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352216 : decoder_(decoder),
2217 id_(0) {
2218}
2219
[email protected]ed9f9cd2013-02-27 21:12:352220BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:352221 // This does not destroy the frame buffer because that would require that
2222 // the associated GL context was current. Just check that it was explicitly
2223 // destroyed.
2224 DCHECK_EQ(id_, 0u);
2225}
2226
[email protected]ed9f9cd2013-02-27 21:12:352227void BackFramebuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302228 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create",
2229 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352230 Destroy();
2231 glGenFramebuffersEXT(1, &id_);
2232}
2233
[email protected]ed9f9cd2013-02-27 21:12:352234void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:352235 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512236 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302237 "BackFramebuffer::AttachRenderTexture", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352238 ScopedFrameBufferBinder binder(decoder_, id_);
2239 GLuint attach_id = texture ? texture->id() : 0;
2240 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2241 GL_COLOR_ATTACHMENT0,
2242 GL_TEXTURE_2D,
2243 attach_id,
2244 0);
2245}
2246
[email protected]ed9f9cd2013-02-27 21:12:352247void BackFramebuffer::AttachRenderBuffer(GLenum target,
2248 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352249 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512250 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302251 "BackFramebuffer::AttachRenderBuffer", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352252 ScopedFrameBufferBinder binder(decoder_, id_);
2253 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2254 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152255 target,
[email protected]6217d392010-03-25 22:08:352256 GL_RENDERBUFFER,
2257 attach_id);
2258}
2259
[email protected]ed9f9cd2013-02-27 21:12:352260void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352261 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302262 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy",
2263 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352264 glDeleteFramebuffersEXT(1, &id_);
2265 id_ = 0;
2266 }
2267}
2268
[email protected]ed9f9cd2013-02-27 21:12:352269void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052270 id_ = 0;
2271}
2272
[email protected]ed9f9cd2013-02-27 21:12:352273GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352274 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302275 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus",
2276 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352277 ScopedFrameBufferBinder binder(decoder_, id_);
2278 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2279}
2280
[email protected]aa7666122011-09-02 19:45:522281GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2282 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322283}
2284
[email protected]aa7666122011-09-02 19:45:522285GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392286 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572287 group_(group),
[email protected]1d82e822013-04-10 21:32:322288 logger_(&debug_marker_manager_),
[email protected]828a3932014-04-02 14:43:132289 state_(group_->feature_info(), this, &logger_),
[email protected]43410e92012-04-20 17:06:282290 unpack_flip_y_(false),
2291 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172292 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242293 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492294 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242295 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402296 fixed_attrib_buffer_id_(0),
2297 fixed_attrib_buffer_size_(0),
[email protected]34ff8b0c2010-10-01 20:06:022298 offscreen_target_color_format_(0),
2299 offscreen_target_depth_format_(0),
2300 offscreen_target_stencil_format_(0),
2301 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562302 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052303 offscreen_saved_color_format_(0),
[email protected]32fe9aa2011-01-21 23:47:132304 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462305 back_buffer_has_depth_(false),
2306 back_buffer_has_stencil_(false),
achaulkcf5316f2014-09-26 19:28:422307 surfaceless_(false),
[email protected]60f22d32012-12-12 00:31:582308 backbuffer_needs_clear_bits_(0),
[email protected]a3a93e7b2010-08-28 00:48:562309 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052310 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112311 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002312 feature_info_(group_->feature_info()),
[email protected]38d139d2011-07-14 00:38:432313 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302314 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512315 reset_status_(GL_NO_ERROR),
[email protected]93a7d98f2013-07-11 00:04:222316 reset_by_robustness_extension_(false),
[email protected]b381ee32014-03-22 02:43:432317 supports_post_sub_buffer_(false),
[email protected]f0d74742011-10-03 16:31:042318 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102319 derivatives_explicitly_enabled_(false),
[email protected]70dc60932013-06-04 03:33:492320 frag_depth_explicitly_enabled_(false),
[email protected]aff39ac82013-06-08 04:53:132321 draw_buffers_explicitly_enabled_(false),
[email protected]93c2fd82014-04-16 02:46:062322 shader_texture_lod_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282323 compile_shader_always_succeeds_(false),
[email protected]828a3932014-04-02 14:43:132324 lose_context_when_out_of_memory_(false),
[email protected]cae20172012-12-07 00:06:192325 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch(
2326 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022327 viewport_max_width_(0),
[email protected]4a4c18b2013-09-13 22:50:102328 viewport_max_height_(0),
[email protected]345ba902013-11-14 21:39:002329 texture_state_(group_->feature_info()
2330 ->workarounds()
2331 .texsubimage2d_faster_than_teximage2d),
vmiura1c2b1de2014-09-19 19:03:242332 cb_command_trace_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
2333 TRACE_DISABLED_BY_DEFAULT("cb_command"))),
2334 gpu_trace_level_(2),
2335 gpu_trace_commands_(false),
2336 gpu_debug_commands_(false),
[email protected]4a4c18b2013-09-13 22:50:102337 validation_texture_(0),
2338 validation_fbo_multisample_(0),
2339 validation_fbo_(0) {
[email protected]3b1ecc262011-08-03 22:49:572340 DCHECK(group);
2341
[email protected]b1122982010-05-17 23:04:242342 attrib_0_value_.v[0] = 0.0f;
2343 attrib_0_value_.v[1] = 0.0f;
2344 attrib_0_value_.v[2] = 0.0f;
2345 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152346
[email protected]c2f8c8402010-12-06 18:07:242347 // The shader translator is used for WebGL even when running on EGL
2348 // because additional restrictions are needed (like only enabling
2349 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562350 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2351 // the empty string to CompileShader and this is not a valid shader.
2352 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
[email protected]39ba4f02012-03-26 01:16:002353 CommandLine::ForCurrentProcess()->HasSwitch(
2354 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152355 use_shader_translator_ = false;
2356 }
[email protected]96449d2c2009-11-25 00:01:322357}
2358
[email protected]80eb6b52012-01-19 00:14:412359GLES2DecoderImpl::~GLES2DecoderImpl() {
2360}
2361
[email protected]c410da802011-03-14 19:17:412362bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382363 const scoped_refptr<gfx::GLSurface>& surface,
2364 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232365 bool offscreen,
[email protected]c410da802011-03-14 19:17:412366 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:292367 const DisallowedFeatures& disallowed_features,
[email protected]3c644d82011-06-20 19:58:242368 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322369 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382370 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302371 DCHECK(!context_.get());
2372
jbaumana7604692014-10-17 02:00:392373 surfaceless_ = surface->IsSurfaceless() && !offscreen;
achaulkcf5316f2014-09-26 19:28:422374
[email protected]55e136f2013-04-03 18:50:062375 set_initialized();
[email protected]b4af07d2014-08-20 00:11:572376 gpu_tracer_.reset(new GPUTracer(this));
[email protected]8f9b8dd2013-09-12 18:05:132377 gpu_state_tracer_ = GPUStateTracer::Create(&state_);
[email protected]fb97b662013-02-20 23:02:142378
[email protected]e844ae22012-01-14 03:36:262379 if (CommandLine::ForCurrentProcess()->HasSwitch(
2380 switches::kEnableGPUDebugging)) {
2381 set_debug(true);
2382 }
2383
[email protected]39ba4f02012-03-26 01:16:002384 if (CommandLine::ForCurrentProcess()->HasSwitch(
2385 switches::kEnableGPUCommandLogging)) {
2386 set_log_commands(true);
2387 }
2388
[email protected]062c38b2012-01-18 03:25:102389 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch(
2390 switches::kCompileShaderAlwaysSucceeds);
2391
[email protected]f62a5ab2011-05-23 20:34:152392
[email protected]63c9b052012-05-17 18:27:382393 // Take ownership of the context and surface. The surface can be replaced with
2394 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382395 context_ = context;
[email protected]63c9b052012-05-17 18:27:382396 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182397
[email protected]65f7efe2013-11-28 03:11:472398 ContextCreationAttribHelper attrib_parser;
2399 if (!attrib_parser.Parse(attribs))
2400 return false;
2401
[email protected]828a3932014-04-02 14:43:132402 // Save the loseContextWhenOutOfMemory context creation attribute.
2403 lose_context_when_out_of_memory_ =
[email protected]845c4e32014-08-13 11:50:402404 attrib_parser.lose_context_when_out_of_memory;
[email protected]828a3932014-04-02 14:43:132405
[email protected]65f7efe2013-11-28 03:11:472406 // If the failIfMajorPerformanceCaveat context creation attribute was true
2407 // and we are using a software renderer, fail.
[email protected]845c4e32014-08-13 11:50:402408 if (attrib_parser.fail_if_major_perf_caveat &&
[email protected]65f7efe2013-11-28 03:11:472409 feature_info_->feature_flags().is_swiftshader) {
2410 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
2411 Destroy(true);
2412 return false;
2413 }
2414
[email protected]956aec52013-09-05 15:41:192415 if (!group_->Initialize(this, disallowed_features)) {
[email protected]09ddb91f2011-04-14 23:16:222416 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392417 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422418 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382419 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032420 return false;
[email protected]a3ded6d2010-10-19 06:44:392421 }
[email protected]b64c24952012-04-19 03:20:272422 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282423
[email protected]e82fb792011-09-22 00:33:292424 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502425
[email protected]af6380962012-11-29 23:24:132426 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]da364812014-05-09 21:39:482427 vertex_array_manager_.reset(new VertexArrayManager());
2428
2429 GLuint default_vertex_attrib_service_id = 0;
2430 if (features().native_vertex_array_object) {
2431 glGenVertexArraysOES(1, &default_vertex_attrib_service_id);
2432 glBindVertexArrayOES(default_vertex_attrib_service_id);
2433 }
2434
2435 state_.default_vertex_attrib_manager =
2436 CreateVertexAttribManager(0, default_vertex_attrib_service_id, false);
2437
[email protected]81f20a622014-04-18 01:54:522438 state_.default_vertex_attrib_manager->Initialize(
[email protected]94ba2e02014-03-12 10:32:002439 group_->max_vertex_attribs(),
2440 feature_info_->workarounds().init_vertex_attributes);
[email protected]944b62f32012-09-27 02:20:462441
[email protected]81f20a622014-04-18 01:54:522442 // vertex_attrib_manager is set to default_vertex_attrib_manager by this call
[email protected]ab4fd7282012-10-12 16:25:572443 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322444
[email protected]7cd76fd2013-06-02 21:11:112445 query_manager_.reset(new QueryManager(this, feature_info_.get()));
[email protected]882ba1e22012-03-08 19:02:532446
[email protected]b63f1d62014-07-18 15:40:592447 image_manager_.reset(new ImageManager);
2448
[email protected]302ce6d2011-07-07 23:28:112449 util_.set_num_compressed_texture_formats(
2450 validators_->compressed_texture_format.GetValues().size());
2451
[email protected]1071e572011-02-09 20:00:122452 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2453 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2454 // OpenGL ES 2.0 does not have this issue.
2455 glEnableVertexAttribArray(0);
2456 }
[email protected]b1122982010-05-17 23:04:242457 glGenBuffersARB(1, &attrib_0_buffer_id_);
2458 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2459 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2460 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402461 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082462
[email protected]1868a342012-11-07 15:56:022463 state_.texture_units.resize(group_->max_texture_units());
2464 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492465 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312466 // We want the last bind to be 2D.
[email protected]370eaf12013-05-18 09:19:492467 TextureRef* ref;
[email protected]62e155e2012-10-23 22:43:152468 if (features().oes_egl_image_external) {
[email protected]370eaf12013-05-18 09:19:492469 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072470 GL_TEXTURE_EXTERNAL_OES);
[email protected]370eaf12013-05-18 09:19:492471 state_.texture_units[tt].bound_texture_external_oes = ref;
[email protected]5ebf59f2014-04-08 03:51:572472 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref ? ref->service_id() : 0);
[email protected]61eeb33f2011-07-26 15:30:312473 }
[email protected]62e155e2012-10-23 22:43:152474 if (features().arb_texture_rectangle) {
[email protected]370eaf12013-05-18 09:19:492475 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072476 GL_TEXTURE_RECTANGLE_ARB);
[email protected]370eaf12013-05-18 09:19:492477 state_.texture_units[tt].bound_texture_rectangle_arb = ref;
[email protected]5ebf59f2014-04-08 03:51:572478 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref ? ref->service_id() : 0);
[email protected]e51bdf32011-11-23 22:21:462479 }
[email protected]370eaf12013-05-18 09:19:492480 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2481 state_.texture_units[tt].bound_texture_cube_map = ref;
[email protected]5ebf59f2014-04-08 03:51:572482 glBindTexture(GL_TEXTURE_CUBE_MAP, ref ? ref->service_id() : 0);
[email protected]370eaf12013-05-18 09:19:492483 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2484 state_.texture_units[tt].bound_texture_2d = ref;
[email protected]5ebf59f2014-04-08 03:51:572485 glBindTexture(GL_TEXTURE_2D, ref ? ref->service_id() : 0);
[email protected]1958e0e2010-04-22 05:17:152486 }
[email protected]00f893d2010-08-24 18:55:492487 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502488 CHECK_GL_ERROR();
2489
[email protected]069944672012-04-25 20:52:232490 if (offscreen) {
[email protected]845c4e32014-08-13 11:50:402491 if (attrib_parser.samples > 0 && attrib_parser.sample_buffers > 0 &&
[email protected]b0609652012-12-14 07:24:542492 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022493 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432494 // max_sample_count must be initialized to a sane value. If
2495 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2496 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022497 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
[email protected]845c4e32014-08-13 11:50:402498 offscreen_target_samples_ = std::min(attrib_parser.samples,
[email protected]34ff8b0c2010-10-01 20:06:022499 max_sample_count);
2500 } else {
2501 offscreen_target_samples_ = 1;
2502 }
[email protected]845c4e32014-08-13 11:50:402503 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved;
[email protected]34ff8b0c2010-10-01 20:06:022504
2505 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2506 const bool rgb8_supported =
2507 context_->HasExtension("GL_OES_rgb8_rgba8");
2508 // The only available default render buffer formats in GLES2 have very
2509 // little precision. Don't enable multisampling unless 8-bit render
2510 // buffer formats are available--instead fall back to 8-bit textures.
2511 if (rgb8_supported && offscreen_target_samples_ > 1) {
[email protected]845c4e32014-08-13 11:50:402512 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022513 GL_RGBA8 : GL_RGB8;
2514 } else {
2515 offscreen_target_samples_ = 1;
[email protected]845c4e32014-08-13 11:50:402516 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022517 GL_RGBA : GL_RGB;
2518 }
2519
2520 // ANGLE only supports packed depth/stencil formats, so use it if it is
2521 // available.
2522 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182523 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272524 VLOG(1) << "GL_OES_packed_depth_stencil "
2525 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]845c4e32014-08-13 11:50:402526 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002527 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022528 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2529 offscreen_target_stencil_format_ = 0;
2530 } else {
2531 // It may be the case that this depth/stencil combination is not
2532 // supported, but this will be checked later by CheckFramebufferStatus.
[email protected]845c4e32014-08-13 11:50:402533 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022534 GL_DEPTH_COMPONENT16 : 0;
[email protected]845c4e32014-08-13 11:50:402535 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022536 GL_STENCIL_INDEX8 : 0;
2537 }
2538 } else {
[email protected]845c4e32014-08-13 11:50:402539 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022540 GL_RGBA : GL_RGB;
2541
2542 // If depth is requested at all, use the packed depth stencil format if
2543 // it's available, as some desktop GL drivers don't support any non-packed
2544 // formats for depth attachments.
2545 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182546 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272547 VLOG(1) << "GL_EXT_packed_depth_stencil "
2548 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022549
[email protected]845c4e32014-08-13 11:50:402550 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002551 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022552 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2553 offscreen_target_stencil_format_ = 0;
2554 } else {
[email protected]845c4e32014-08-13 11:50:402555 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022556 GL_DEPTH_COMPONENT : 0;
[email protected]845c4e32014-08-13 11:50:402557 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022558 GL_STENCIL_INDEX : 0;
2559 }
2560 }
2561
[email protected]845c4e32014-08-13 11:50:402562 offscreen_saved_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]97872062010-11-03 19:07:052563 GL_RGBA : GL_RGB;
2564
[email protected]6217d392010-03-25 22:08:352565 // Create the target frame buffer. This is the one that the client renders
2566 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352567 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352568 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022569 // Due to GLES2 format limitations, either the color texture (for
2570 // non-multisampling) or the color render buffer (for multisampling) will be
2571 // attached to the offscreen frame buffer. The render buffer has more
2572 // limited formats available to it, but the texture can't do multisampling.
2573 if (IsOffscreenBufferMultisampled()) {
[email protected]d5a28e452013-10-10 01:01:402574 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(
2575 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022576 offscreen_target_color_render_buffer_->Create();
2577 } else {
[email protected]ce296892013-10-24 22:04:362578 offscreen_target_color_texture_.reset(new BackTexture(
2579 memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022580 offscreen_target_color_texture_->Create();
2581 }
[email protected]d5a28e452013-10-10 01:01:402582 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(
2583 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152584 offscreen_target_depth_render_buffer_->Create();
[email protected]d5a28e452013-10-10 01:01:402585 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(
2586 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152587 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352588
2589 // Create the saved offscreen texture. The target frame buffer is copied
2590 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352591 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022592 offscreen_saved_frame_buffer_->Create();
2593 //
[email protected]ce296892013-10-24 22:04:362594 offscreen_saved_color_texture_.reset(new BackTexture(
2595 memory_tracker(), &state_));
[email protected]6217d392010-03-25 22:08:352596 offscreen_saved_color_texture_->Create();
2597
[email protected]6217d392010-03-25 22:08:352598 // Allocate the render buffers at their initial size and check the status
2599 // of the frame buffers is okay.
[email protected]799b4b22011-08-22 17:09:592600 if (!ResizeOffscreenFrameBuffer(size)) {
[email protected]d0498742010-09-20 20:27:012601 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382602 Destroy(true);
[email protected]6217d392010-03-25 22:08:352603 return false;
2604 }
2605
[email protected]678a73f2012-12-19 19:22:092606 // Allocate the offscreen saved color texture.
2607 DCHECK(offscreen_saved_color_format_);
2608 offscreen_saved_color_texture_->AllocateStorage(
2609 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2610
2611 offscreen_saved_frame_buffer_->AttachRenderTexture(
2612 offscreen_saved_color_texture_.get());
2613 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2614 GL_FRAMEBUFFER_COMPLETE) {
2615 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2616 Destroy(true);
2617 return false;
2618 }
2619
[email protected]6217d392010-03-25 22:08:352620 // Bind to the new default frame buffer (the offscreen target frame buffer).
2621 // This should now be associated with ID zero.
2622 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
[email protected]62e65f02013-05-29 22:28:102623 } else {
2624 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
2625 // These are NOT if the back buffer has these proprorties. They are
2626 // if we want the command buffer to enforce them regardless of what
2627 // the real backbuffer is assuming the real back buffer gives us more than
2628 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2629 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2630 // can't do anything about that.
2631
achaulkcf5316f2014-09-26 19:28:422632 if (!surfaceless_) {
2633 GLint v = 0;
2634 glGetIntegerv(GL_ALPHA_BITS, &v);
2635 // This checks if the user requested RGBA and we have RGBA then RGBA. If
2636 // the user requested RGB then RGB. If the user did not specify a
2637 // preference than use whatever we were given. Same for DEPTH and STENCIL.
2638 back_buffer_color_format_ =
2639 (attrib_parser.alpha_size != 0 && v > 0) ? GL_RGBA : GL_RGB;
2640 glGetIntegerv(GL_DEPTH_BITS, &v);
2641 back_buffer_has_depth_ = attrib_parser.depth_size != 0 && v > 0;
2642 glGetIntegerv(GL_STENCIL_BITS, &v);
2643 back_buffer_has_stencil_ = attrib_parser.stencil_size != 0 && v > 0;
2644 }
[email protected]6217d392010-03-25 22:08:352645 }
2646
[email protected]76a0ee102010-04-07 21:03:042647 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2648 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2649 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372650 // mailing list archives. It also implicitly enables the desktop GL
2651 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2652 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152653 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2654 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372655 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152656 }
[email protected]de17df392010-04-23 21:09:412657
[email protected]706b69f2012-07-27 04:59:302658 has_robustness_extension_ =
2659 context->HasExtension("GL_ARB_robustness") ||
2660 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432661
[email protected]c2f8c8402010-12-06 18:07:242662 if (!InitializeShaderTranslator()) {
2663 return false;
[email protected]de17df392010-04-23 21:09:412664 }
[email protected]76a0ee102010-04-07 21:03:042665
[email protected]e259eb412012-10-13 05:47:242666 state_.viewport_width = size.width();
2667 state_.viewport_height = size.height();
[email protected]43410e92012-04-20 17:06:282668
[email protected]5904806b2012-05-08 18:10:222669 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282670 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022671 viewport_max_width_ = viewport_params[0];
2672 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282673
[email protected]88a61bf2012-10-27 13:00:422674 state_.scissor_width = state_.viewport_width;
2675 state_.scissor_height = state_.viewport_height;
2676
[email protected]11f3e702012-06-19 19:00:012677 // Set all the default state because some GL drivers get it wrong.
[email protected]88ba52f2014-04-09 12:39:342678 state_.InitCapabilities(NULL);
2679 state_.InitState(NULL);
[email protected]e259eb412012-10-13 05:47:242680 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]11f3e702012-06-19 19:00:012681
2682 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2683 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2684 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2685 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
2686
achaulkcf5316f2014-09-26 19:28:422687 bool call_gl_clear = !surfaceless_;
[email protected]88cfd132013-07-11 00:59:002688#if defined(OS_ANDROID)
2689 // Temporary workaround for Android WebView because this clear ignores the
2690 // clip and corrupts that external UI of the App. Not calling glClear is ok
2691 // because the system already clears the buffer before each draw. Proper
2692 // fix might be setting the scissor clip properly before initialize. See
2693 // crbug.com/259023 for details.
2694 call_gl_clear = surface_->GetHandle();
2695#endif
2696 if (call_gl_clear) {
2697 // Clear the backbuffer.
2698 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2699 }
[email protected]561cc0a62013-05-07 18:34:452700
[email protected]b381ee32014-03-22 02:43:432701 supports_post_sub_buffer_ = surface->SupportsPostSubBuffer();
2702 if (feature_info_->workarounds()
2703 .disable_post_sub_buffers_for_onscreen_surfaces &&
2704 !surface->IsOffscreen())
2705 supports_post_sub_buffer_ = false;
2706
[email protected]62e155e2012-10-23 22:43:152707 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462708 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2709 }
[email protected]dd289a5d62012-06-30 22:05:462710
[email protected]9b753992013-04-27 02:04:412711 if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2712 context_->SetUnbindFboOnMakeCurrent();
[email protected]85cb4682013-04-20 00:54:242713 }
[email protected]85cb4682013-04-20 00:54:242714
[email protected]97419c02013-04-10 02:52:382715 // Only compositor contexts are known to use only the subset of GL
2716 // that can be safely migrated between the iGPU and the dGPU. Mark
2717 // those contexts as safe to forcibly transition between the GPUs.
2718 // http://crbug.com/180876, http://crbug.com/227228
2719 if (!offscreen)
2720 context_->SetSafeToForceGpuSwitch();
2721
[email protected]85a4ac22013-05-31 01:58:472722 async_pixel_transfer_manager_.reset(
[email protected]498b5c072013-06-04 19:30:072723 AsyncPixelTransferManager::Create(context.get()));
2724 async_pixel_transfer_manager_->Initialize(texture_manager());
[email protected]32145a92012-12-17 09:01:592725
[email protected]91c94eb2013-10-22 10:32:542726 framebuffer_manager()->AddObserver(this);
2727
[email protected]246a70452010-03-05 21:53:502728 return true;
[email protected]96449d2c2009-11-25 00:01:322729}
2730
[email protected]6d668892013-12-04 21:37:122731Capabilities GLES2DecoderImpl::GetCapabilities() {
2732 DCHECK(initialized());
2733
2734 Capabilities caps;
2735
[email protected]6d668892013-12-04 21:37:122736 caps.egl_image_external =
2737 feature_info_->feature_flags().oes_egl_image_external;
2738 caps.texture_format_bgra8888 =
2739 feature_info_->feature_flags().ext_texture_format_bgra8888;
2740 caps.texture_format_etc1 =
2741 feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture;
aeliasd880a3d2014-08-26 00:46:202742 caps.texture_format_etc1_npot =
2743 caps.texture_format_etc1 && !workarounds().etc1_power_of_two_only;
[email protected]6d668892013-12-04 21:37:122744 caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle;
2745 caps.texture_usage = feature_info_->feature_flags().angle_texture_usage;
2746 caps.texture_storage = feature_info_->feature_flags().ext_texture_storage;
2747 caps.discard_framebuffer =
2748 feature_info_->feature_flags().ext_discard_framebuffer;
[email protected]12c99ab02014-04-22 10:12:352749 caps.sync_query = feature_info_->feature_flags().chromium_sync_query;
[email protected]6d668892013-12-04 21:37:122750
2751#if defined(OS_MACOSX)
2752 // This is unconditionally true on mac, no need to test for it at runtime.
2753 caps.iosurface = true;
2754#endif
2755
[email protected]b381ee32014-03-22 02:43:432756 caps.post_sub_buffer = supports_post_sub_buffer_;
reveman340109182014-09-30 15:36:452757 caps.image = true;
[email protected]6d668892013-12-04 21:37:122758
edfad658b2014-10-10 08:59:522759 caps.blend_minmax = feature_info_->feature_flags().ext_blend_minmax;
[email protected]6d668892013-12-04 21:37:122760 return caps;
2761}
2762
[email protected]302ce6d2011-07-07 23:28:112763void GLES2DecoderImpl::UpdateCapabilities() {
2764 util_.set_num_compressed_texture_formats(
2765 validators_->compressed_texture_format.GetValues().size());
2766 util_.set_num_shader_binary_formats(
2767 validators_->shader_binary_format.GetValues().size());
2768}
2769
[email protected]c2f8c8402010-12-06 18:07:242770bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442771 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2772
[email protected]c2f8c8402010-12-06 18:07:242773 if (!use_shader_translator_) {
2774 return true;
2775 }
2776 ShBuiltInResources resources;
2777 ShInitBuiltInResources(&resources);
2778 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2779 resources.MaxVertexUniformVectors =
2780 group_->max_vertex_uniform_vectors();
2781 resources.MaxVaryingVectors = group_->max_varying_vectors();
2782 resources.MaxVertexTextureImageUnits =
2783 group_->max_vertex_texture_image_units();
2784 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2785 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2786 resources.MaxFragmentUniformVectors =
2787 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:492788 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]a0b78142013-05-23 00:47:242789 resources.MaxExpressionComplexity = 256;
2790 resources.MaxCallStackDepth = 256;
[email protected]f0d74742011-10-03 16:31:042791
[email protected]46c86752013-05-21 05:08:392792 GLint range[2] = { 0, 0 };
[email protected]8dc1bf92013-03-12 03:58:212793 GLint precision = 0;
2794 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
2795 range, &precision);
[email protected]448e459e2013-06-12 17:00:412796 resources.FragmentPrecisionHigh =
2797 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
[email protected]9e98f61b2013-03-05 02:21:142798
[email protected]f0d74742011-10-03 16:31:042799 if (force_webgl_glsl_validation_) {
2800 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:492801 resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:132802 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
[email protected]cd8f1892013-09-05 00:14:442803 if (!draw_buffers_explicitly_enabled_)
2804 resources.MaxDrawBuffers = 1;
[email protected]93c2fd82014-04-16 02:46:062805 resources.EXT_shader_texture_lod = shader_texture_lod_explicitly_enabled_;
oetuaho0decd442014-10-13 08:40:462806 resources.NV_draw_buffers =
2807 draw_buffers_explicitly_enabled_ && features().nv_draw_buffers;
[email protected]f0d74742011-10-03 16:31:042808 } else {
2809 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152810 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462811 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152812 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062813 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152814 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:492815 resources.EXT_draw_buffers =
2816 features().ext_draw_buffers ? 1 : 0;
[email protected]70dc60932013-06-04 03:33:492817 resources.EXT_frag_depth =
2818 features().ext_frag_depth ? 1 : 0;
[email protected]93c2fd82014-04-16 02:46:062819 resources.EXT_shader_texture_lod =
2820 features().ext_shader_texture_lod ? 1 : 0;
oetuaho0decd442014-10-13 08:40:462821 resources.NV_draw_buffers =
2822 features().nv_draw_buffers ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:042823 }
2824
[email protected]26b61442013-03-17 16:12:012825 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC
2826 : SH_GLES2_SPEC;
[email protected]6aedcdc2013-01-24 01:25:052827 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:022828 resources.HashFunction = &CityHash64;
[email protected]6aedcdc2013-01-24 01:25:052829 else
2830 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:122831 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2832 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2833 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
[email protected]a6739bc2013-09-07 04:45:212834 int driver_bug_workarounds = 0;
2835 if (workarounds().needs_glsl_built_in_function_emulation)
2836 driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS;
[email protected]81187c62013-09-09 23:54:542837 if (workarounds().init_gl_position_in_vertex_shader)
2838 driver_bug_workarounds |= SH_INIT_GL_POSITION;
[email protected]f0c87602013-10-17 19:34:112839 if (workarounds().unfold_short_circuit_as_ternary_operation)
2840 driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT;
[email protected]b03219d2014-02-12 11:17:052841 if (workarounds().init_varyings_without_static_use)
2842 driver_bug_workarounds |= SH_INIT_VARYINGS_WITHOUT_STATIC_USE;
[email protected]f4db2b12014-03-01 03:57:062843 if (workarounds().unroll_for_loop_with_sampler_array_index)
2844 driver_bug_workarounds |= SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX;
[email protected]711e90802014-07-22 20:40:252845 if (workarounds().scalarize_vec_and_mat_constructor_args)
2846 driver_bug_workarounds |= SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS;
[email protected]fa6d3982014-08-18 18:10:272847 if (workarounds().regenerate_struct_names)
2848 driver_bug_workarounds |= SH_REGENERATE_STRUCT_NAMES;
[email protected]87fb6ab2012-06-13 22:28:042849
[email protected]03cef9b2014-04-03 15:58:142850 vertex_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:262851 GL_VERTEX_SHADER,
[email protected]03cef9b2014-04-03 15:58:142852 shader_spec,
2853 &resources,
[email protected]a6739bc2013-09-07 04:45:212854 implementation_type,
2855 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042856 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242857 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:382858 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242859 return false;
2860 }
[email protected]87fb6ab2012-06-13 22:28:042861
[email protected]03cef9b2014-04-03 15:58:142862 fragment_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:262863 GL_FRAGMENT_SHADER,
[email protected]03cef9b2014-04-03 15:58:142864 shader_spec,
2865 &resources,
[email protected]a6739bc2013-09-07 04:45:212866 implementation_type,
2867 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042868 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242869 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:382870 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242871 return false;
2872 }
2873 return true;
2874}
2875
[email protected]ae51d192010-04-27 00:48:032876bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:472877 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352878 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032879 return false;
2880 }
2881 }
[email protected]40d90a22013-04-09 03:39:552882 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032883 glGenBuffersARB(n, service_ids.get());
2884 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352885 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032886 }
2887 return true;
2888}
2889
2890bool GLES2DecoderImpl::GenFramebuffersHelper(
2891 GLsizei n, const GLuint* client_ids) {
2892 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352893 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032894 return false;
2895 }
2896 }
[email protected]40d90a22013-04-09 03:39:552897 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032898 glGenFramebuffersEXT(n, service_ids.get());
2899 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352900 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032901 }
2902 return true;
2903}
2904
2905bool GLES2DecoderImpl::GenRenderbuffersHelper(
2906 GLsizei n, const GLuint* client_ids) {
2907 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352908 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032909 return false;
2910 }
2911 }
[email protected]40d90a22013-04-09 03:39:552912 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032913 glGenRenderbuffersEXT(n, service_ids.get());
2914 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352915 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032916 }
2917 return true;
2918}
2919
2920bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
2921 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352922 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032923 return false;
2924 }
2925 }
[email protected]40d90a22013-04-09 03:39:552926 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032927 glGenTextures(n, service_ids.get());
2928 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352929 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032930 }
2931 return true;
2932}
2933
2934void GLES2DecoderImpl::DeleteBuffersHelper(
2935 GLsizei n, const GLuint* client_ids) {
2936 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:212937 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102938 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242939 state_.vertex_attrib_manager->Unbind(buffer);
[email protected]7cd76fd2013-06-02 21:11:112940 if (state_.bound_array_buffer.get() == buffer) {
[email protected]e259eb412012-10-13 05:47:242941 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102942 }
[email protected]ed9f9cd2013-02-27 21:12:352943 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032944 }
[email protected]a93bb842010-02-16 23:03:472945 }
[email protected]07f54fcc2009-12-22 02:46:302946}
2947
[email protected]ae51d192010-04-27 00:48:032948void GLES2DecoderImpl::DeleteFramebuffersHelper(
2949 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452950 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152951 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:112952
[email protected]a25fa872010-03-25 02:57:582953 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352954 Framebuffer* framebuffer =
2955 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102956 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]9d3b2e12013-10-02 01:04:342957 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
2958 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]c986af502013-08-14 01:04:442959 framebuffer_state_.clear_state_dirty = true;
[email protected]ebfb73c2012-08-15 02:37:452960 GLenum target = supports_separate_framebuffer_binds ?
2961 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112962 glBindFramebufferEXT(target, GetBackbufferServiceId());
2963 }
[email protected]9d3b2e12013-10-02 01:04:342964 if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) {
2965 framebuffer_state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:452966 GLenum target = supports_separate_framebuffer_binds ?
2967 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112968 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:462969 }
[email protected]70d34263c2013-01-09 00:27:452970 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:352971 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032972 }
[email protected]a25fa872010-03-25 02:57:582973 }
[email protected]07f54fcc2009-12-22 02:46:302974}
2975
[email protected]ae51d192010-04-27 00:48:032976void GLES2DecoderImpl::DeleteRenderbuffersHelper(
2977 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452978 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152979 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:582980 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352981 Renderbuffer* renderbuffer =
2982 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102983 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:112984 if (state_.bound_renderbuffer.get() == renderbuffer) {
[email protected]e259eb412012-10-13 05:47:242985 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102986 }
2987 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452988 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:342989 if (framebuffer_state_.bound_read_framebuffer.get()) {
2990 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112991 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102992 }
[email protected]9d3b2e12013-10-02 01:04:342993 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2994 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112995 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102996 }
2997 } else {
[email protected]9d3b2e12013-10-02 01:04:342998 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2999 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113000 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103001 }
3002 }
[email protected]c986af502013-08-14 01:04:443003 framebuffer_state_.clear_state_dirty = true;
[email protected]ed9f9cd2013-02-27 21:12:353004 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033005 }
[email protected]a25fa872010-03-25 02:57:583006 }
[email protected]07f54fcc2009-12-22 02:46:303007}
3008
[email protected]ae51d192010-04-27 00:48:033009void GLES2DecoderImpl::DeleteTexturesHelper(
3010 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453011 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153012 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:473013 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]370eaf12013-05-18 09:19:493014 TextureRef* texture_ref = GetTexture(client_ids[ii]);
3015 if (texture_ref) {
3016 Texture* texture = texture_ref->texture();
[email protected]a0b78dc2011-11-11 10:43:103017 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:443018 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463019 }
[email protected]370eaf12013-05-18 09:19:493020 // Unbind texture_ref from texture_ref units.
[email protected]1868a342012-11-07 15:56:023021 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]370eaf12013-05-18 09:19:493022 state_.texture_units[jj].Unbind(texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103023 }
3024 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:453025 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:343026 if (framebuffer_state_.bound_read_framebuffer.get()) {
3027 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113028 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103029 }
[email protected]9d3b2e12013-10-02 01:04:343030 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3031 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113032 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103033 }
3034 } else {
[email protected]9d3b2e12013-10-02 01:04:343035 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3036 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113037 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103038 }
3039 }
[email protected]e51bdf32011-11-23 22:21:463040#if defined(OS_MACOSX)
[email protected]4f9958142013-07-02 03:58:073041 GLuint service_id = texture->service_id();
[email protected]e51bdf32011-11-23 22:21:463042 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
3043 ReleaseIOSurfaceForTexture(service_id);
3044 }
3045#endif
[email protected]ed9f9cd2013-02-27 21:12:353046 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033047 }
[email protected]a93bb842010-02-16 23:03:473048 }
[email protected]07f54fcc2009-12-22 02:46:303049}
3050
[email protected]43f28f832010-02-03 02:28:483051// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:323052
[email protected]eb54a562010-01-20 21:55:183053bool GLES2DecoderImpl::MakeCurrent() {
[email protected]177d1342013-12-07 04:20:343054 if (!context_.get())
[email protected]63c9b052012-05-17 18:27:383055 return false;
3056
[email protected]177d1342013-12-07 04:20:343057 if (!context_->MakeCurrent(surface_.get()) || WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:433058 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]e9f0ca82013-04-01 23:52:293059
jbauman7a059312014-10-16 19:30:543060 MaybeExitOnContextLost();
[email protected]e9f0ca82013-04-01 23:52:293061
[email protected]63c9b052012-05-17 18:27:383062 return false;
[email protected]38d139d2011-07-14 00:38:433063 }
3064
[email protected]69a8701e2013-03-07 21:31:093065 ProcessFinishedAsyncTransfers();
[email protected]69a8701e2013-03-07 21:31:093066
[email protected]9b753992013-04-27 02:04:413067 // Rebind the FBO if it was unbound by the context.
3068 if (workarounds().unbind_fbo_on_context_switch)
3069 RestoreFramebufferBindings();
3070
[email protected]c986af502013-08-14 01:04:443071 framebuffer_state_.clear_state_dirty = true;
[email protected]370eaf12013-05-18 09:19:493072
[email protected]69a8701e2013-03-07 21:31:093073 return true;
3074}
3075
3076void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]5a36dc132013-07-23 23:17:553077 ProcessPendingReadPixels();
[email protected]fe8d73c2013-02-16 22:37:323078 if (engine() && query_manager_.get())
3079 query_manager_->ProcessPendingTransferQueries();
3080
[email protected]5b3a8e02013-03-13 05:36:443081 // TODO(epenner): Is there a better place to do this?
3082 // This needs to occur before we execute any batch of commands
3083 // from the client, as the client may have recieved an async
3084 // completion while issuing those commands.
3085 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]b68b100752013-06-05 08:34:483086 async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
[email protected]eb54a562010-01-20 21:55:183087}
3088
[email protected]8e3e0662010-08-23 18:46:303089static void RebindCurrentFramebuffer(
3090 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:063091 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:243092 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:063093 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:463094
[email protected]a3783712012-01-20 22:18:243095 if (framebuffer_id == 0) {
3096 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:303097 }
[email protected]297ca1c2011-06-20 23:08:463098
[email protected]8e3e0662010-08-23 18:46:303099 glBindFramebufferEXT(target, framebuffer_id);
3100}
3101
3102void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]c986af502013-08-14 01:04:443103 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463104
[email protected]62e155e2012-10-23 22:43:153105 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:303106 RebindCurrentFramebuffer(
3107 GL_FRAMEBUFFER,
[email protected]9d3b2e12013-10-02 01:04:343108 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243109 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303110 } else {
3111 RebindCurrentFramebuffer(
3112 GL_READ_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343113 framebuffer_state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243114 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303115 RebindCurrentFramebuffer(
3116 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343117 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243118 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303119 }
[email protected]70d34263c2013-01-09 00:27:453120 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:303121}
3122
[email protected]0d6bfdc2011-11-02 01:32:203123bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:353124 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:203125 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:103126 if (!framebuffer) {
achaulkcf5316f2014-09-26 19:28:423127 if (surfaceless_)
3128 return false;
[email protected]60f22d32012-12-12 00:31:583129 if (backbuffer_needs_clear_bits_) {
3130 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
pkasting45796dc2014-10-17 04:18:323131 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1.f);
[email protected]454157e2014-05-03 02:49:453132 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]60f22d32012-12-12 00:31:583133 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473134 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3135 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]60f22d32012-12-12 00:31:583136 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:453137 state_.SetDeviceDepthMask(GL_TRUE);
3138 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]ee757922014-06-06 05:21:423139 bool reset_draw_buffer = false;
3140 if ((backbuffer_needs_clear_bits_ | GL_COLOR_BUFFER_BIT) != 0 &&
3141 group_->draw_buffer() == GL_NONE) {
3142 reset_draw_buffer = true;
3143 GLenum buf = GL_BACK;
3144 if (GetBackbufferServiceId() != 0) // emulated backbuffer
3145 buf = GL_COLOR_ATTACHMENT0;
3146 glDrawBuffersARB(1, &buf);
3147 }
[email protected]60f22d32012-12-12 00:31:583148 glClear(backbuffer_needs_clear_bits_);
[email protected]ee757922014-06-06 05:21:423149 if (reset_draw_buffer) {
3150 GLenum buf = GL_NONE;
3151 glDrawBuffersARB(1, &buf);
3152 }
[email protected]60f22d32012-12-12 00:31:583153 backbuffer_needs_clear_bits_ = 0;
3154 RestoreClearState();
3155 }
[email protected]0d6bfdc2011-11-02 01:32:203156 return true;
3157 }
3158
[email protected]968351b2011-12-20 08:26:513159 if (framebuffer_manager()->IsComplete(framebuffer)) {
3160 return true;
3161 }
3162
[email protected]0d6bfdc2011-11-02 01:32:203163 GLenum completeness = framebuffer->IsPossiblyComplete();
3164 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513165 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433166 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:273167 return false;
3168 }
[email protected]0d6bfdc2011-11-02 01:32:203169
3170 // Are all the attachments cleared?
3171 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
3172 texture_manager()->HaveUnclearedMips()) {
3173 if (!framebuffer->IsCleared()) {
3174 // Can we clear them?
[email protected]73276522012-11-09 05:50:203175 if (framebuffer->GetStatus(texture_manager(), target) !=
3176 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513177 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433178 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3179 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:203180 return false;
3181 }
3182 ClearUnclearedAttachments(target, framebuffer);
3183 }
3184 }
3185
[email protected]968351b2011-12-20 08:26:513186 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:203187 if (framebuffer->GetStatus(texture_manager(), target) !=
3188 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513189 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433190 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3191 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:513192 return false;
3193 }
3194 framebuffer_manager()->MarkAsComplete(framebuffer);
3195 }
3196
[email protected]0d6bfdc2011-11-02 01:32:203197 // NOTE: At this point we don't know if the framebuffer is complete but
3198 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:273199 return true;
3200}
3201
[email protected]0d6bfdc2011-11-02 01:32:203202bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:153203 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:513204 bool valid = CheckFramebufferValid(
[email protected]9d3b2e12013-10-02 01:04:343205 framebuffer_state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT,
3206 func_name);
[email protected]28718a92013-04-04 12:12:513207
3208 if (valid)
3209 OnUseFramebuffer();
3210
3211 return valid;
[email protected]0d6bfdc2011-11-02 01:32:203212 }
[email protected]9d3b2e12013-10-02 01:04:343213 return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113214 GL_DRAW_FRAMEBUFFER_EXT,
3215 func_name) &&
[email protected]9d3b2e12013-10-02 01:04:343216 CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113217 GL_READ_FRAMEBUFFER_EXT,
3218 func_name);
[email protected]0d6bfdc2011-11-02 01:32:203219}
3220
[email protected]2ea5950d2014-07-09 18:20:343221bool GLES2DecoderImpl::CheckBoundReadFramebufferColorAttachment(
3222 const char* func_name) {
3223 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3224 framebuffer_state_.bound_read_framebuffer.get() :
3225 framebuffer_state_.bound_draw_framebuffer.get();
3226 if (!framebuffer)
3227 return true;
3228 if (framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL) {
3229 LOCAL_SET_GL_ERROR(
3230 GL_INVALID_OPERATION, func_name, "no color image attached");
3231 return false;
3232 }
3233 return true;
3234}
3235
zmo383512cf2014-10-14 00:11:003236bool GLES2DecoderImpl::FormsTextureCopyingFeedbackLoop(
3237 TextureRef* texture, GLint level) {
3238 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3239 framebuffer_state_.bound_read_framebuffer.get() :
3240 framebuffer_state_.bound_draw_framebuffer.get();
3241 if (!framebuffer)
3242 return false;
3243 const Framebuffer::Attachment* attachment = framebuffer->GetAttachment(
3244 GL_COLOR_ATTACHMENT0);
3245 if (!attachment)
3246 return false;
3247 return attachment->FormsFeedbackLoop(texture, level);
3248}
3249
[email protected]8e3e0662010-08-23 18:46:303250gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:353251 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453252 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203253 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:353254 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:203255 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:263256 if (attachment) {
3257 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:503258 }
[email protected]9edc6b22010-12-23 02:00:263259 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:023260 } else if (offscreen_target_frame_buffer_.get()) {
3261 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:353262 } else {
[email protected]f62a5ab2011-05-23 20:34:153263 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:023264 }
[email protected]246a70452010-03-05 21:53:503265}
3266
[email protected]68586372013-12-11 01:27:593267GLenum GLES2DecoderImpl::GetBoundReadFrameBufferTextureType() {
3268 Framebuffer* framebuffer =
3269 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
3270 if (framebuffer != NULL) {
3271 return framebuffer->GetColorAttachmentTextureType();
3272 } else {
3273 return GL_UNSIGNED_BYTE;
3274 }
3275}
3276
[email protected]9edc6b22010-12-23 02:00:263277GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353278 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453279 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203280 if (framebuffer != NULL) {
3281 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:463282 } else if (offscreen_target_frame_buffer_.get()) {
3283 return offscreen_target_color_format_;
3284 } else {
3285 return back_buffer_color_format_;
3286 }
3287}
3288
3289GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353290 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453291 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203292 if (framebuffer != NULL) {
3293 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:263294 } else if (offscreen_target_frame_buffer_.get()) {
3295 return offscreen_target_color_format_;
3296 } else {
[email protected]32fe9aa2011-01-21 23:47:133297 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:263298 }
3299}
3300
[email protected]9a5afa432011-07-22 18:16:393301void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]2ad674132013-06-05 07:48:513302 if (!offscreen_saved_color_texture_info_.get())
3303 return;
3304 GLenum target = offscreen_saved_color_texture_info_->texture()->target();
3305 glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
3306 texture_manager()->SetLevelInfo(
3307 offscreen_saved_color_texture_info_.get(),
3308 GL_TEXTURE_2D,
3309 0, // level
3310 GL_RGBA,
3311 offscreen_size_.width(),
3312 offscreen_size_.height(),
3313 1, // depth
3314 0, // border
3315 GL_RGBA,
3316 GL_UNSIGNED_BYTE,
3317 true);
[email protected]737191ee72014-03-09 08:02:423318 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513319 "UpdateParentTextureInfo",
3320 GetErrorState(),
3321 offscreen_saved_color_texture_info_.get(),
3322 GL_TEXTURE_MAG_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263323 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423324 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513325 "UpdateParentTextureInfo",
3326 GetErrorState(),
3327 offscreen_saved_color_texture_info_.get(),
3328 GL_TEXTURE_MIN_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263329 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423330 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513331 "UpdateParentTextureInfo",
3332 GetErrorState(),
3333 offscreen_saved_color_texture_info_.get(),
3334 GL_TEXTURE_WRAP_S,
3335 GL_CLAMP_TO_EDGE);
[email protected]737191ee72014-03-09 08:02:423336 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513337 "UpdateParentTextureInfo",
3338 GetErrorState(),
3339 offscreen_saved_color_texture_info_.get(),
3340 GL_TEXTURE_WRAP_T,
3341 GL_CLAMP_TO_EDGE);
[email protected]c986af502013-08-14 01:04:443342 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
3343 &state_, target);
[email protected]2ad674132013-06-05 07:48:513344 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
[email protected]6217d392010-03-25 22:08:353345}
3346
[email protected]799b4b22011-08-22 17:09:593347void GLES2DecoderImpl::SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:073348 const base::Callback<void(gfx::Size, float)>& callback) {
[email protected]9d37f062011-11-22 01:24:523349 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:003350}
3351
[email protected]1d82e822013-04-10 21:32:323352Logger* GLES2DecoderImpl::GetLogger() {
3353 return &logger_;
[email protected]6b6e7ee2011-12-13 08:04:523354}
3355
[email protected]cac16542014-01-15 17:53:513356void GLES2DecoderImpl::BeginDecoding() {
3357 gpu_tracer_->BeginDecoding();
3358 gpu_trace_commands_ = gpu_tracer_->IsTracing();
vmiura1c2b1de2014-09-19 19:03:243359 gpu_debug_commands_ = log_commands() || debug() || gpu_trace_commands_ ||
3360 (*cb_command_trace_category_ != 0);
[email protected]cac16542014-01-15 17:53:513361}
3362
3363void GLES2DecoderImpl::EndDecoding() {
3364 gpu_tracer_->EndDecoding();
3365}
3366
[email protected]d3eba342013-04-18 21:11:503367ErrorState* GLES2DecoderImpl::GetErrorState() {
3368 return state_.GetErrorState();
3369}
3370
[email protected]e3932abb2013-03-13 00:01:373371void GLES2DecoderImpl::SetShaderCacheCallback(
3372 const ShaderCacheCallback& callback) {
3373 shader_cache_callback_ = callback;
3374}
3375
[email protected]840a7e462013-02-27 01:29:513376void GLES2DecoderImpl::SetWaitSyncPointCallback(
3377 const WaitSyncPointCallback& callback) {
3378 wait_sync_point_callback_ = callback;
3379}
3380
[email protected]85a4ac22013-05-31 01:58:473381AsyncPixelTransferManager*
3382 GLES2DecoderImpl::GetAsyncPixelTransferManager() {
3383 return async_pixel_transfer_manager_.get();
3384}
3385
3386void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
3387 async_pixel_transfer_manager_.reset();
[email protected]32145a92012-12-17 09:01:593388}
3389
[email protected]498b5c072013-06-04 19:30:073390void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest(
3391 AsyncPixelTransferManager* manager) {
3392 async_pixel_transfer_manager_ = make_scoped_ptr(manager);
3393}
3394
[email protected]1318e922010-09-17 22:03:163395bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3396 uint32* service_texture_id) {
[email protected]370eaf12013-05-18 09:19:493397 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3398 if (texture_ref) {
3399 *service_texture_id = texture_ref->service_id();
[email protected]1318e922010-09-17 22:03:163400 return true;
3401 }
3402 return false;
3403}
3404
[email protected]63b465922012-09-06 02:04:523405uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]c986af502013-08-14 01:04:443406 return texture_state_.texture_upload_count +
[email protected]b68b100752013-06-05 08:34:483407 async_pixel_transfer_manager_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523408}
3409
3410base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]c986af502013-08-14 01:04:443411 return texture_state_.total_texture_upload_time +
[email protected]b68b100752013-06-05 08:34:483412 async_pixel_transfer_manager_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523413}
3414
3415base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3416 return total_processing_commands_time_;
3417}
3418
[email protected]dc25dda2012-09-27 21:36:303419void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3420 total_processing_commands_time_ += time;
3421}
3422
[email protected]63c9b052012-05-17 18:27:383423void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063424 if (!initialized())
3425 return;
3426
[email protected]63c9b052012-05-17 18:27:383427 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053428
[email protected]80eb6b52012-01-19 00:14:413429 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243430 state_.vertex_attrib_manager = NULL;
[email protected]81f20a622014-04-18 01:54:523431 state_.default_vertex_attrib_manager = NULL;
[email protected]1868a342012-11-07 15:56:023432 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243433 state_.bound_array_buffer = NULL;
[email protected]8ebd46c2014-01-08 12:06:133434 state_.current_queries.clear();
[email protected]9d3b2e12013-10-02 01:04:343435 framebuffer_state_.bound_read_framebuffer = NULL;
3436 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]e259eb412012-10-13 05:47:243437 state_.bound_renderbuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413438
[email protected]cadac622013-06-11 16:46:363439 if (offscreen_saved_color_texture_info_.get()) {
[email protected]2ad674132013-06-05 07:48:513440 DCHECK(offscreen_target_color_texture_);
3441 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
3442 offscreen_saved_color_texture_->id());
3443 offscreen_saved_color_texture_->Invalidate();
3444 offscreen_saved_color_texture_info_ = NULL;
3445 }
[email protected]eadc96792010-10-27 19:39:393446 if (have_context) {
[email protected]c322e882012-05-23 18:06:183447 if (copy_texture_CHROMIUM_.get()) {
3448 copy_texture_CHROMIUM_->Destroy();
3449 copy_texture_CHROMIUM_.reset();
3450 }
[email protected]43410e92012-04-20 17:06:283451
[email protected]7cd76fd2013-06-02 21:11:113452 if (state_.current_program.get()) {
3453 program_manager()->UnuseProgram(shader_manager(),
3454 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:143455 }
3456
[email protected]b1122982010-05-17 23:04:243457 if (attrib_0_buffer_id_) {
3458 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3459 }
[email protected]8fbedc02010-11-18 18:43:403460 if (fixed_attrib_buffer_id_) {
3461 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3462 }
[email protected]b1122982010-05-17 23:04:243463
[email protected]4a4c18b2013-09-13 22:50:103464 if (validation_texture_) {
3465 glDeleteTextures(1, &validation_texture_);
3466 glDeleteFramebuffersEXT(1, &validation_fbo_multisample_);
3467 glDeleteFramebuffersEXT(1, &validation_fbo_);
3468 }
3469
[email protected]97872062010-11-03 19:07:053470 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543471 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053472 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543473 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053474 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023475 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053476 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153477 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053478 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153479 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053480 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023481 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053482 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543483 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273484 if (offscreen_resolved_frame_buffer_.get())
3485 offscreen_resolved_frame_buffer_->Destroy();
3486 if (offscreen_resolved_color_texture_.get())
3487 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053488 } else {
3489 if (offscreen_target_frame_buffer_.get())
3490 offscreen_target_frame_buffer_->Invalidate();
3491 if (offscreen_target_color_texture_.get())
3492 offscreen_target_color_texture_->Invalidate();
3493 if (offscreen_target_color_render_buffer_.get())
3494 offscreen_target_color_render_buffer_->Invalidate();
3495 if (offscreen_target_depth_render_buffer_.get())
3496 offscreen_target_depth_render_buffer_->Invalidate();
3497 if (offscreen_target_stencil_render_buffer_.get())
3498 offscreen_target_stencil_render_buffer_->Invalidate();
3499 if (offscreen_saved_frame_buffer_.get())
3500 offscreen_saved_frame_buffer_->Invalidate();
3501 if (offscreen_saved_color_texture_.get())
3502 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273503 if (offscreen_resolved_frame_buffer_.get())
3504 offscreen_resolved_frame_buffer_->Invalidate();
3505 if (offscreen_resolved_color_texture_.get())
3506 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023507 }
[email protected]83a52d032013-07-24 10:30:373508
3509 // Current program must be cleared after calling ProgramManager::UnuseProgram.
3510 // Otherwise, we can leak objects. http://crbug.com/258772.
3511 // state_.current_program must be reset before group_ is reset because
3512 // the later deletes the ProgramManager object that referred by
3513 // state_.current_program object.
3514 state_.current_program = NULL;
3515
[email protected]43410e92012-04-20 17:06:283516 copy_texture_CHROMIUM_.reset();
[email protected]97872062010-11-03 19:07:053517
[email protected]882ba1e22012-03-08 19:02:533518 if (query_manager_.get()) {
3519 query_manager_->Destroy(have_context);
3520 query_manager_.reset();
3521 }
3522
[email protected]944b62f32012-09-27 02:20:463523 if (vertex_array_manager_ .get()) {
3524 vertex_array_manager_->Destroy(have_context);
3525 vertex_array_manager_.reset();
3526 }
3527
[email protected]d2eaf52f2014-07-31 15:01:243528 if (image_manager_.get()) {
3529 image_manager_->Destroy(have_context);
3530 image_manager_.reset();
3531 }
3532
[email protected]97872062010-11-03 19:07:053533 offscreen_target_frame_buffer_.reset();
3534 offscreen_target_color_texture_.reset();
3535 offscreen_target_color_render_buffer_.reset();
3536 offscreen_target_depth_render_buffer_.reset();
3537 offscreen_target_stencil_render_buffer_.reset();
3538 offscreen_saved_frame_buffer_.reset();
3539 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273540 offscreen_resolved_frame_buffer_.reset();
3541 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463542
[email protected]03cef9b2014-04-03 15:58:143543 // Need to release these before releasing |group_| which may own the
3544 // ShaderTranslatorCache.
3545 fragment_translator_ = NULL;
3546 vertex_translator_ = NULL;
3547
[email protected]85a4ac22013-05-31 01:58:473548 // Should destroy the transfer manager before the texture manager held
3549 // by the context group.
3550 async_pixel_transfer_manager_.reset();
3551
[email protected]7cd76fd2013-06-02 21:11:113552 if (group_.get()) {
[email protected]ac5e4022014-01-24 12:44:393553 framebuffer_manager()->RemoveObserver(this);
[email protected]2d9d3b92013-01-18 01:07:233554 group_->Destroy(this, have_context);
3555 group_ = NULL;
3556 }
3557
3558 if (context_.get()) {
3559 context_->ReleaseCurrent(NULL);
3560 context_ = NULL;
3561 }
3562
[email protected]e51bdf32011-11-23 22:21:463563#if defined(OS_MACOSX)
3564 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3565 it != texture_to_io_surface_map_.end(); ++it) {
3566 CFRelease(it->second);
3567 }
3568 texture_to_io_surface_map_.clear();
3569#endif
[email protected]96449d2c2009-11-25 00:01:323570}
3571
[email protected]63c9b052012-05-17 18:27:383572void GLES2DecoderImpl::SetSurface(
3573 const scoped_refptr<gfx::GLSurface>& surface) {
3574 DCHECK(context_->IsCurrent(NULL));
3575 DCHECK(surface_.get());
3576 surface_ = surface;
3577 RestoreCurrentFramebufferBindings();
3578}
3579
[email protected]aba551b2014-02-08 03:38:323580void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
3581 if (!offscreen_saved_color_texture_.get()) {
3582 LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context";
3583 return;
3584 }
[email protected]2ad674132013-06-05 07:48:513585 if (!offscreen_saved_color_texture_info_.get()) {
[email protected]3c644d82011-06-20 19:58:243586 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]f46476932013-06-08 05:36:073587 offscreen_saved_color_texture_info_ = TextureRef::Create(
3588 texture_manager(), 0, service_id);
[email protected]2ad674132013-06-05 07:48:513589 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(),
3590 GL_TEXTURE_2D);
[email protected]9a5afa432011-07-22 18:16:393591 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243592 }
[email protected]aba551b2014-02-08 03:38:323593 mailbox_manager()->ProduceTexture(
3594 GL_TEXTURE_2D, mailbox, offscreen_saved_color_texture_info_->texture());
[email protected]3c644d82011-06-20 19:58:243595}
3596
[email protected]799b4b22011-08-22 17:09:593597bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3598 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3599 if (!is_offscreen) {
3600 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3601 << " with an onscreen framebuffer.";
3602 return false;
3603 }
3604
3605 if (offscreen_size_ == size)
3606 return true;
3607
3608 offscreen_size_ = size;
3609 int w = offscreen_size_.width();
3610 int h = offscreen_size_.height();
3611 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3612 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3613 << "to allocate storage due to excessive dimensions.";
3614 return false;
3615 }
3616
3617 // Reallocate the offscreen target buffers.
3618 DCHECK(offscreen_target_color_format_);
3619 if (IsOffscreenBufferMultisampled()) {
3620 if (!offscreen_target_color_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253621 feature_info_.get(),
3622 offscreen_size_,
3623 offscreen_target_color_format_,
3624 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593625 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3626 << "to allocate storage for offscreen target color buffer.";
3627 return false;
3628 }
3629 } else {
3630 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093631 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593632 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3633 << "to allocate storage for offscreen target color texture.";
3634 return false;
3635 }
3636 }
3637 if (offscreen_target_depth_format_ &&
3638 !offscreen_target_depth_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253639 feature_info_.get(),
3640 offscreen_size_,
3641 offscreen_target_depth_format_,
3642 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593643 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3644 << "to allocate storage for offscreen target depth buffer.";
3645 return false;
3646 }
3647 if (offscreen_target_stencil_format_ &&
3648 !offscreen_target_stencil_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253649 feature_info_.get(),
3650 offscreen_size_,
3651 offscreen_target_stencil_format_,
3652 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593653 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3654 << "to allocate storage for offscreen target stencil buffer.";
3655 return false;
3656 }
3657
3658 // Attach the offscreen target buffers to the target frame buffer.
3659 if (IsOffscreenBufferMultisampled()) {
3660 offscreen_target_frame_buffer_->AttachRenderBuffer(
3661 GL_COLOR_ATTACHMENT0,
3662 offscreen_target_color_render_buffer_.get());
3663 } else {
3664 offscreen_target_frame_buffer_->AttachRenderTexture(
3665 offscreen_target_color_texture_.get());
3666 }
3667 if (offscreen_target_depth_format_) {
3668 offscreen_target_frame_buffer_->AttachRenderBuffer(
3669 GL_DEPTH_ATTACHMENT,
3670 offscreen_target_depth_render_buffer_.get());
3671 }
3672 const bool packed_depth_stencil =
3673 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3674 if (packed_depth_stencil) {
3675 offscreen_target_frame_buffer_->AttachRenderBuffer(
3676 GL_STENCIL_ATTACHMENT,
3677 offscreen_target_depth_render_buffer_.get());
3678 } else if (offscreen_target_stencil_format_) {
3679 offscreen_target_frame_buffer_->AttachRenderBuffer(
3680 GL_STENCIL_ATTACHMENT,
3681 offscreen_target_stencil_render_buffer_.get());
3682 }
3683
3684 if (offscreen_target_frame_buffer_->CheckStatus() !=
3685 GL_FRAMEBUFFER_COMPLETE) {
3686 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3687 << "because offscreen FBO was incomplete.";
3688 return false;
3689 }
3690
3691 // Clear the target frame buffer.
3692 {
3693 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3694 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
pkasting45796dc2014-10-17 04:18:323695 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1.f);
[email protected]454157e2014-05-03 02:49:453696 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]799b4b22011-08-22 17:09:593697 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473698 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3699 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]799b4b22011-08-22 17:09:593700 glClearDepth(0);
[email protected]454157e2014-05-03 02:49:453701 state_.SetDeviceDepthMask(GL_TRUE);
3702 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]799b4b22011-08-22 17:09:593703 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3704 RestoreClearState();
3705 }
[email protected]d85ef76d2011-09-08 22:21:433706
3707 // Destroy the offscreen resolved framebuffers.
3708 if (offscreen_resolved_frame_buffer_.get())
3709 offscreen_resolved_frame_buffer_->Destroy();
3710 if (offscreen_resolved_color_texture_.get())
3711 offscreen_resolved_color_texture_->Destroy();
3712 offscreen_resolved_color_texture_.reset();
3713 offscreen_resolved_frame_buffer_.reset();
3714
[email protected]799b4b22011-08-22 17:09:593715 return true;
[email protected]6217d392010-03-25 22:08:353716}
3717
vmiuracd108592014-09-08 14:36:343718error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(uint32 immediate_data_size,
3719 const void* cmd_data) {
3720 const gles2::cmds::ResizeCHROMIUM& c =
3721 *static_cast<const gles2::cmds::ResizeCHROMIUM*>(cmd_data);
[email protected]09e17272012-11-30 10:30:443722 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023723 return error::kDeferCommandUntilLater;
3724
[email protected]799b4b22011-08-22 17:09:593725 GLuint width = static_cast<GLuint>(c.width);
3726 GLuint height = static_cast<GLuint>(c.height);
[email protected]729c0b42013-05-26 02:05:073727 GLfloat scale_factor = c.scale_factor;
[email protected]799b4b22011-08-22 17:09:593728 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:413729
3730 width = std::max(1U, width);
3731 height = std::max(1U, height);
3732
[email protected]a0d989162011-11-22 13:15:073733#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3734 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003735 // Make sure that we are done drawing to the back buffer before resizing.
3736 glFinish();
3737#endif
[email protected]799b4b22011-08-22 17:09:593738 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3739 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493740 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3741 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3742 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593743 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493744 }
[email protected]7ff86b92010-11-25 17:50:003745 }
[email protected]799b4b22011-08-22 17:09:593746
[email protected]9d37f062011-11-22 01:24:523747 if (!resize_callback_.is_null()) {
[email protected]729c0b42013-05-26 02:05:073748 resize_callback_.Run(gfx::Size(width, height), scale_factor);
[email protected]0e9346b2013-03-16 16:35:443749 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493750 if (!context_->IsCurrent(surface_.get())) {
3751 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3752 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053753 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493754 }
[email protected]658f7562011-09-09 05:24:053755 }
[email protected]799b4b22011-08-22 17:09:593756
3757 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393758}
3759
[email protected]96449d2c2009-11-25 00:01:323760const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3761 if (command_id > kStartPoint && command_id < kNumCommands) {
3762 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3763 }
3764 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3765}
3766
vmiura8266ca72014-09-09 21:37:003767// Decode a command, and call the corresponding GL functions.
3768// NOTE: DoCommand() is slower than calling DoCommands() on larger batches
3769// of commands at once, and is now only used for tests that need to track
3770// individual commands.
3771error::Error GLES2DecoderImpl::DoCommand(unsigned int command,
3772 unsigned int arg_count,
3773 const void* cmd_data) {
3774 return DoCommands(1, cmd_data, arg_count + 1, 0);
3775}
3776
3777// Decode multiple commands, and call the corresponding GL functions.
3778// NOTE: 'buffer' is a pointer to the command buffer. As such, it could be
3779// changed by a (malicious) client at any time, so if validation has to happen,
3780// it should operate on a copy of them.
3781// NOTE: This is duplicating code from AsyncAPIInterface::DoCommands() in the
3782// interest of performance in this critical execution loop.
vmiura1c2b1de2014-09-19 19:03:243783template <bool DebugImpl>
3784error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands,
3785 const void* buffer,
3786 int num_entries,
3787 int* entries_processed) {
vmiura8266ca72014-09-09 21:37:003788 commands_to_process_ = num_commands;
[email protected]f7a64ee2010-02-01 22:24:143789 error::Error result = error::kNoError;
vmiura8266ca72014-09-09 21:37:003790 const CommandBufferEntry* cmd_data =
3791 static_cast<const CommandBufferEntry*>(buffer);
3792 int process_pos = 0;
3793 unsigned int command = 0;
3794
3795 while (process_pos < num_entries && result == error::kNoError &&
3796 commands_to_process_--) {
3797 const unsigned int size = cmd_data->value_header.size;
3798 command = cmd_data->value_header.command;
3799
3800 if (size == 0) {
3801 result = error::kInvalidSize;
3802 break;
3803 }
3804
3805 if (static_cast<int>(size) + process_pos > num_entries) {
3806 result = error::kOutOfBounds;
3807 break;
3808 }
3809
vmiura1c2b1de2014-09-19 19:03:243810 if (DebugImpl) {
3811 TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
3812 GetCommandName(command));
vmiura8266ca72014-09-09 21:37:003813
vmiura1c2b1de2014-09-19 19:03:243814 if (log_commands()) {
3815 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]"
3816 << "cmd: " << GetCommandName(command);
3817 }
vmiura8266ca72014-09-09 21:37:003818 }
3819
3820 const unsigned int arg_count = size - 1;
3821 unsigned int command_index = command - kStartPoint - 1;
3822 if (command_index < arraysize(command_info)) {
3823 const CommandInfo& info = command_info[command_index];
3824 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3825 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3826 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
3827 bool doing_gpu_trace = false;
vmiura1c2b1de2014-09-19 19:03:243828 if (DebugImpl && gpu_trace_commands_) {
vmiura8266ca72014-09-09 21:37:003829 if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) {
3830 doing_gpu_trace = true;
3831 gpu_tracer_->Begin(GetCommandName(command), kTraceDecoder);
3832 }
[email protected]cac16542014-01-15 17:53:513833 }
[email protected]cac16542014-01-15 17:53:513834
vmiura8266ca72014-09-09 21:37:003835 uint32 immediate_data_size = (arg_count - info_arg_count) *
3836 sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:323837
vmiura8266ca72014-09-09 21:37:003838 result = (this->*info.cmd_handler)(immediate_data_size, cmd_data);
[email protected]cac16542014-01-15 17:53:513839
vmiura1c2b1de2014-09-19 19:03:243840 if (DebugImpl && doing_gpu_trace)
vmiura8266ca72014-09-09 21:37:003841 gpu_tracer_->End(kTraceDecoder);
[email protected]cac16542014-01-15 17:53:513842
vmiura1c2b1de2014-09-19 19:03:243843 if (DebugImpl && debug()) {
vmiura8266ca72014-09-09 21:37:003844 GLenum error;
3845 while ((error = glGetError()) != GL_NO_ERROR) {
3846 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
3847 << "GL ERROR: " << GLES2Util::GetStringEnum(error)
3848 << " : " << GetCommandName(command);
3849 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
3850 }
[email protected]b9849abf2009-11-25 19:13:193851 }
vmiura8266ca72014-09-09 21:37:003852 } else {
3853 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:323854 }
3855 } else {
vmiura8266ca72014-09-09 21:37:003856 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:323857 }
vmiura1c2b1de2014-09-19 19:03:243858
3859 if (DebugImpl) {
3860 TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
3861 GetCommandName(command));
3862 }
3863
vmiura8266ca72014-09-09 21:37:003864 if (result == error::kNoError &&
3865 current_decoder_error_ != error::kNoError) {
[email protected]a3a93e7b2010-08-28 00:48:563866 result = current_decoder_error_;
3867 current_decoder_error_ = error::kNoError;
vmiura8266ca72014-09-09 21:37:003868 }
3869
3870 if (result != error::kDeferCommandUntilLater) {
3871 process_pos += size;
3872 cmd_data += size;
3873 }
[email protected]a3a93e7b2010-08-28 00:48:563874 }
vmiura8266ca72014-09-09 21:37:003875
3876 if (entries_processed)
3877 *entries_processed = process_pos;
3878
3879 if (error::IsError(result)) {
3880 LOG(ERROR) << "Error: " << result << " for Command "
3881 << GetCommandName(command);
3882 }
3883
[email protected]b9849abf2009-11-25 19:13:193884 return result;
[email protected]96449d2c2009-11-25 00:01:323885}
3886
vmiura1c2b1de2014-09-19 19:03:243887error::Error GLES2DecoderImpl::DoCommands(unsigned int num_commands,
3888 const void* buffer,
3889 int num_entries,
3890 int* entries_processed) {
3891 if (gpu_debug_commands_) {
3892 return DoCommandsImpl<true>(
3893 num_commands, buffer, num_entries, entries_processed);
3894 } else {
3895 return DoCommandsImpl<false>(
3896 num_commands, buffer, num_entries, entries_processed);
3897 }
3898}
3899
[email protected]ed9f9cd2013-02-27 21:12:353900void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
3901 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:503902}
3903
[email protected]ae51d192010-04-27 00:48:033904bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353905 if (GetProgram(client_id)) {
[email protected]ae51d192010-04-27 00:48:033906 return false;
3907 }
[email protected]96449d2c2009-11-25 00:01:323908 GLuint service_id = glCreateProgram();
[email protected]ae51d192010-04-27 00:48:033909 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353910 CreateProgram(client_id, service_id);
[email protected]96449d2c2009-11-25 00:01:323911 }
[email protected]ae51d192010-04-27 00:48:033912 return true;
[email protected]96449d2c2009-11-25 00:01:323913}
3914
[email protected]ae51d192010-04-27 00:48:033915bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353916 if (GetShader(client_id)) {
[email protected]ae51d192010-04-27 00:48:033917 return false;
[email protected]96449d2c2009-11-25 00:01:323918 }
[email protected]ae51d192010-04-27 00:48:033919 GLuint service_id = glCreateShader(type);
3920 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353921 CreateShader(client_id, service_id, type);
[email protected]ae51d192010-04-27 00:48:033922 }
3923 return true;
[email protected]96449d2c2009-11-25 00:01:323924}
3925
[email protected]882ba1e22012-03-08 19:02:533926void GLES2DecoderImpl::DoFinish() {
3927 glFinish();
[email protected]5a36dc132013-07-23 23:17:553928 ProcessPendingReadPixels();
[email protected]22e3f552012-03-13 01:54:193929 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533930}
3931
3932void GLES2DecoderImpl::DoFlush() {
3933 glFlush();
[email protected]22e3f552012-03-13 01:54:193934 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533935}
3936
[email protected]3916c97e2010-02-25 03:20:503937void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:453938 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:023939 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:513940 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:533941 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:503942 return;
3943 }
[email protected]e259eb412012-10-13 05:47:243944 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:453945 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:503946}
3947
[email protected]051b1372010-04-12 02:42:083948void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:073949 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:083950 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033951 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:073952 buffer = GetBuffer(client_id);
3953 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:353954 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:223955 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
3956 "glBindBuffer",
3957 "id not generated by glGenBuffers");
[email protected]bf5a8d132011-08-16 08:39:353958 return;
3959 }
3960
[email protected]b10492f2013-03-08 05:24:073961 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:033962 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353963 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:073964 buffer = GetBuffer(client_id);
[email protected]ae51d192010-04-27 00:48:033965 }
[email protected]051b1372010-04-12 02:42:083966 }
[email protected]b10492f2013-03-08 05:24:073967 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
3968 if (buffer) {
3969 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:513970 LOCAL_SET_GL_ERROR(
3971 GL_INVALID_OPERATION,
3972 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:473973 return;
3974 }
[email protected]b10492f2013-03-08 05:24:073975 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:473976 }
[email protected]96449d2c2009-11-25 00:01:323977 switch (target) {
3978 case GL_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073979 state_.bound_array_buffer = buffer;
[email protected]96449d2c2009-11-25 00:01:323980 break;
3981 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073982 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
[email protected]96449d2c2009-11-25 00:01:323983 break;
3984 default:
[email protected]a93bb842010-02-16 23:03:473985 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:323986 break;
3987 }
[email protected]051b1372010-04-12 02:42:083988 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:323989}
3990
[email protected]f3b191b2013-06-19 03:43:543991bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha(
3992 bool all_draw_buffers) {
3993 Framebuffer* framebuffer =
3994 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
3995 if (!all_draw_buffers || !framebuffer) {
3996 return (GLES2Util::GetChannelsForFormat(
3997 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
3998 }
3999 return framebuffer->HasAlphaMRT();
[email protected]297ca1c2011-06-20 23:08:464000}
4001
4002bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:354003 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454004 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204005 if (framebuffer) {
4006 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:464007 }
4008 if (offscreen_target_frame_buffer_.get()) {
4009 return offscreen_target_depth_format_ != 0;
4010 }
4011 return back_buffer_has_depth_;
4012}
4013
4014bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:354015 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454016 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204017 if (framebuffer) {
4018 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:464019 }
4020 if (offscreen_target_frame_buffer_.get()) {
4021 return offscreen_target_stencil_format_ != 0 ||
4022 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
4023 }
4024 return back_buffer_has_stencil_;
4025}
4026
4027void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]c986af502013-08-14 01:04:444028 if (framebuffer_state_.clear_state_dirty) {
[email protected]454157e2014-05-03 02:49:454029 bool have_alpha = BoundFramebufferHasColorAttachmentWithAlpha(true);
4030 state_.SetDeviceColorMask(state_.color_mask_red,
4031 state_.color_mask_green,
4032 state_.color_mask_blue,
4033 state_.color_mask_alpha && have_alpha);
4034
[email protected]297ca1c2011-06-20 23:08:464035 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]454157e2014-05-03 02:49:454036 state_.SetDeviceDepthMask(state_.depth_mask && have_depth);
4037
[email protected]297ca1c2011-06-20 23:08:464038 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]454157e2014-05-03 02:49:454039 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424040 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]454157e2014-05-03 02:49:454041 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424042 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]454157e2014-05-03 02:49:454043
4044 state_.SetDeviceCapabilityState(
4045 GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
4046 state_.SetDeviceCapabilityState(
[email protected]f731b9462012-10-30 00:35:224047 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
[email protected]c986af502013-08-14 01:04:444048 framebuffer_state_.clear_state_dirty = false;
[email protected]297ca1c2011-06-20 23:08:464049 }
4050}
4051
[email protected]1868a342012-11-07 15:56:024052GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]7cd76fd2013-06-02 21:11:114053 return (offscreen_target_frame_buffer_.get())
4054 ? offscreen_target_frame_buffer_->id()
4055 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0);
[email protected]1868a342012-11-07 15:56:024056}
4057
[email protected]8875a5f2014-06-27 08:33:474058void GLES2DecoderImpl::RestoreState(const ContextState* prev_state) {
[email protected]962bfbe72013-05-24 11:16:144059 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
4060 "context", logger_.GetLogPrefix());
[email protected]29a4d902013-02-26 20:18:064061 // Restore the Framebuffer first because of bugs in Intel drivers.
4062 // Intel drivers incorrectly clip the viewport settings to
4063 // the size of the current framebuffer object.
4064 RestoreFramebufferBindings();
[email protected]5baa86bc2014-01-16 04:33:164065 state_.RestoreState(prev_state);
[email protected]29a4d902013-02-26 20:18:064066}
4067
4068void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]9d3b2e12013-10-02 01:04:344069 GLuint service_id =
4070 framebuffer_state_.bound_draw_framebuffer.get()
4071 ? framebuffer_state_.bound_draw_framebuffer->service_id()
4072 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064073 if (!features().chromium_framebuffer_multisample) {
4074 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
4075 } else {
4076 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
[email protected]9d3b2e12013-10-02 01:04:344077 service_id = framebuffer_state_.bound_read_framebuffer.get()
4078 ? framebuffer_state_.bound_read_framebuffer->service_id()
[email protected]7cd76fd2013-06-02 21:11:114079 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064080 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
4081 }
[email protected]70d34263c2013-01-09 00:27:454082 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:064083}
4084
[email protected]8875a5f2014-06-27 08:33:474085void GLES2DecoderImpl::RestoreRenderbufferBindings() {
4086 state_.RestoreRenderbufferBindings();
4087}
4088
[email protected]29a4d902013-02-26 20:18:064089void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
[email protected]62e65f02013-05-29 22:28:104090 Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
4091 if (texture) {
[email protected]9bc9a2e82013-04-03 03:56:254092 GLenum target = texture->target();
4093 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:064094 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254095 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:064096 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254097 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:064098 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254099 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:064100 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254101 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:064102 RestoreTextureUnitBindings(state_.active_texture_unit);
4103 }
[email protected]70d34263c2013-01-09 00:27:454104}
4105
[email protected]cd2ef752014-02-12 23:16:034106void GLES2DecoderImpl::ClearAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524107 // Must use native VAO 0, as RestoreAllAttributes can't fully restore
4108 // other VAOs.
4109 if (feature_info_->feature_flags().native_vertex_array_object)
4110 glBindVertexArrayOES(0);
4111
[email protected]cd2ef752014-02-12 23:16:034112 for (uint32 i = 0; i < group_->max_vertex_attribs(); ++i) {
4113 if (i != 0) // Never disable attribute 0
4114 glDisableVertexAttribArray(i);
4115 if(features().angle_instanced_arrays)
4116 glVertexAttribDivisorANGLE(i, 0);
4117 }
4118}
4119
4120void GLES2DecoderImpl::RestoreAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524121 state_.RestoreVertexAttribs();
[email protected]cd2ef752014-02-12 23:16:034122}
4123
[email protected]454157e2014-05-03 02:49:454124void GLES2DecoderImpl::SetIgnoreCachedStateForTest(bool ignore) {
4125 state_.SetIgnoreCachedStateForTest(ignore);
4126}
4127
[email protected]70d34263c2013-01-09 00:27:454128void GLES2DecoderImpl::OnFboChanged() const {
4129 if (workarounds().restore_scissor_on_fbo_change)
[email protected]28718a92013-04-04 12:12:514130 state_.fbo_binding_for_scissor_workaround_dirty_ = true;
4131}
4132
4133// Called after the FBO is checked for completeness.
4134void GLES2DecoderImpl::OnUseFramebuffer() const {
4135 if (state_.fbo_binding_for_scissor_workaround_dirty_) {
4136 state_.fbo_binding_for_scissor_workaround_dirty_ = false;
[email protected]81fc9d02013-03-14 23:53:324137 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:514138 glScissor(state_.scissor_x,
4139 state_.scissor_y,
4140 state_.scissor_width,
4141 state_.scissor_height);
4142
4143 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
4144 // it's unclear how this bug works.
4145 glFlush();
4146 }
[email protected]b177ae22011-11-01 03:29:114147}
4148
[email protected]051b1372010-04-12 02:42:084149void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:064150 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:084151 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034152 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:064153 framebuffer = GetFramebuffer(client_id);
4154 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:354155 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224156 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4157 "glBindFramebuffer",
4158 "id not generated by glGenFramebuffers");
4159 return;
[email protected]bf5a8d132011-08-16 08:39:354160 }
4161
[email protected]4d8f0dd2013-03-09 14:37:064162 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:034163 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354164 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:064165 framebuffer = GetFramebuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034166 } else {
[email protected]4d8f0dd2013-03-09 14:37:064167 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:084168 }
[email protected]4d8f0dd2013-03-09 14:37:064169 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084170 }
[email protected]4d8f0dd2013-03-09 14:37:064171 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:304172
4173 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344174 framebuffer_state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304175 }
[email protected]cac16542014-01-15 17:53:514176
4177 // vmiura: This looks like dup code
[email protected]8e3e0662010-08-23 18:46:304178 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344179 framebuffer_state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304180 }
[email protected]6217d392010-03-25 22:08:354181
[email protected]c986af502013-08-14 01:04:444182 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:464183
[email protected]b177ae22011-11-01 03:29:114184 // If we are rendering to the backbuffer get the FBO id for any simulated
4185 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:064186 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:114187 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:464188 }
[email protected]6217d392010-03-25 22:08:354189
[email protected]051b1372010-04-12 02:42:084190 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:454191 OnFboChanged();
[email protected]86093972010-03-11 00:13:564192}
4193
[email protected]051b1372010-04-12 02:42:084194void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:274195 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:084196 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034197 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:274198 renderbuffer = GetRenderbuffer(client_id);
4199 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:354200 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224201 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4202 "glBindRenderbuffer",
4203 "id not generated by glGenRenderbuffers");
[email protected]bf5a8d132011-08-16 08:39:354204 return;
4205 }
4206
[email protected]8875a5f2014-06-27 08:33:474207 // It's a new id so make a renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:034208 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354209 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:274210 renderbuffer = GetRenderbuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034211 } else {
[email protected]ee2a79c32013-03-10 03:50:274212 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:084213 }
[email protected]ee2a79c32013-03-10 03:50:274214 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084215 }
[email protected]caa13ed2014-02-17 11:29:204216 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenderbuffer");
[email protected]ee2a79c32013-03-10 03:50:274217 state_.bound_renderbuffer = renderbuffer;
[email protected]8875a5f2014-06-27 08:33:474218 state_.bound_renderbuffer_valid = true;
4219 glBindRenderbufferEXT(GL_RENDERBUFFER, service_id);
[email protected]86093972010-03-11 00:13:564220}
4221
[email protected]051b1372010-04-12 02:42:084222void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:494223 TextureRef* texture_ref = NULL;
[email protected]051b1372010-04-12 02:42:084224 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034225 if (client_id != 0) {
[email protected]370eaf12013-05-18 09:19:494226 texture_ref = GetTexture(client_id);
4227 if (!texture_ref) {
[email protected]bf5a8d132011-08-16 08:39:354228 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224229 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4230 "glBindTexture",
4231 "id not generated by glGenTextures");
4232 return;
[email protected]bf5a8d132011-08-16 08:39:354233 }
4234
[email protected]02965c22013-03-09 02:40:074235 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:034236 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:414237 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:354238 CreateTexture(client_id, service_id);
[email protected]370eaf12013-05-18 09:19:494239 texture_ref = GetTexture(client_id);
[email protected]ae51d192010-04-27 00:48:034240 }
4241 } else {
[email protected]370eaf12013-05-18 09:19:494242 texture_ref = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:084243 }
[email protected]ae51d192010-04-27 00:48:034244
[email protected]1958e0e2010-04-22 05:17:154245 // Check the texture exists
[email protected]5ebf59f2014-04-08 03:51:574246 if (texture_ref) {
4247 Texture* texture = texture_ref->texture();
4248 // Check that we are not trying to bind it to a different target.
4249 if (texture->target() != 0 && texture->target() != target) {
4250 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4251 "glBindTexture",
4252 "texture bound to more than 1 target.");
4253 return;
4254 }
4255 LogClientServiceForInfo(texture, client_id, "glBindTexture");
4256 if (texture->target() == 0) {
4257 texture_manager()->SetTarget(texture_ref, target);
4258 }
4259 glBindTexture(target, texture->service_id());
4260 } else {
4261 glBindTexture(target, 0);
[email protected]1958e0e2010-04-22 05:17:154262 }
[email protected]32145a92012-12-17 09:01:594263
[email protected]e259eb412012-10-13 05:47:244264 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:504265 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:474266 switch (target) {
4267 case GL_TEXTURE_2D:
[email protected]370eaf12013-05-18 09:19:494268 unit.bound_texture_2d = texture_ref;
[email protected]a93bb842010-02-16 23:03:474269 break;
4270 case GL_TEXTURE_CUBE_MAP:
[email protected]370eaf12013-05-18 09:19:494271 unit.bound_texture_cube_map = texture_ref;
[email protected]a93bb842010-02-16 23:03:474272 break;
[email protected]61eeb33f2011-07-26 15:30:314273 case GL_TEXTURE_EXTERNAL_OES:
[email protected]370eaf12013-05-18 09:19:494274 unit.bound_texture_external_oes = texture_ref;
[email protected]61eeb33f2011-07-26 15:30:314275 break;
[email protected]e51bdf32011-11-23 22:21:464276 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]370eaf12013-05-18 09:19:494277 unit.bound_texture_rectangle_arb = texture_ref;
[email protected]e51bdf32011-11-23 22:21:464278 break;
[email protected]a93bb842010-02-16 23:03:474279 default:
4280 NOTREACHED(); // Validation should prevent us getting here.
4281 break;
4282 }
4283}
4284
[email protected]07f54fcc2009-12-22 02:46:304285void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244286 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:124287 if (index != 0 ||
4288 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:244289 glDisableVertexAttribArray(index);
4290 }
[email protected]07f54fcc2009-12-22 02:46:304291 } else {
[email protected]ab09b612013-03-11 22:11:514292 LOCAL_SET_GL_ERROR(
4293 GL_INVALID_VALUE,
4294 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304295 }
4296}
4297
[email protected]60f22d32012-12-12 00:31:584298void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
4299 GLsizei numAttachments,
4300 const GLenum* attachments) {
[email protected]ed9f9cd2013-02-27 21:12:354301 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:584302 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4303
4304 // Validates the attachments. If one of them fails
4305 // the whole command fails.
4306 for (GLsizei i = 0; i < numAttachments; ++i) {
4307 if ((framebuffer &&
4308 !validators_->attachment.IsValid(attachments[i])) ||
4309 (!framebuffer &&
4310 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:514311 LOCAL_SET_GL_ERROR_INVALID_ENUM(
4312 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:584313 return;
4314 }
4315 }
4316
4317 // Marks each one of them as not cleared
4318 for (GLsizei i = 0; i < numAttachments; ++i) {
4319 if (framebuffer) {
4320 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
4321 texture_manager(),
4322 attachments[i],
4323 false);
4324 } else {
4325 switch (attachments[i]) {
4326 case GL_COLOR_EXT:
4327 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
4328 break;
4329 case GL_DEPTH_EXT:
4330 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
4331 case GL_STENCIL_EXT:
4332 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
4333 break;
4334 default:
4335 NOTREACHED();
4336 break;
4337 }
4338 }
4339 }
4340
[email protected]d49c5402013-09-11 15:39:024341 // If the default framebuffer is bound but we are still rendering to an
4342 // FBO, translate attachment names that refer to default framebuffer
4343 // channels to corresponding framebuffer attachments.
4344 scoped_ptr<GLenum[]> translated_attachments(new GLenum[numAttachments]);
4345 for (GLsizei i = 0; i < numAttachments; ++i) {
4346 GLenum attachment = attachments[i];
4347 if (!framebuffer && GetBackbufferServiceId()) {
4348 switch (attachment) {
4349 case GL_COLOR_EXT:
4350 attachment = GL_COLOR_ATTACHMENT0;
4351 break;
4352 case GL_DEPTH_EXT:
4353 attachment = GL_DEPTH_ATTACHMENT;
4354 break;
4355 case GL_STENCIL_EXT:
4356 attachment = GL_STENCIL_ATTACHMENT;
4357 break;
4358 default:
4359 NOTREACHED();
4360 return;
4361 }
4362 }
4363 translated_attachments[i] = attachment;
4364 }
4365
boliu2e7d8a7a2014-10-16 20:35:204366 ScopedRenderTo do_render(framebuffer);
[email protected]d49c5402013-09-11 15:39:024367 glDiscardFramebufferEXT(target, numAttachments, translated_attachments.get());
[email protected]60f22d32012-12-12 00:31:584368}
4369
[email protected]07f54fcc2009-12-22 02:46:304370void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244371 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:304372 glEnableVertexAttribArray(index);
4373 } else {
[email protected]ab09b612013-03-11 22:11:514374 LOCAL_SET_GL_ERROR(
4375 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304376 }
4377}
4378
[email protected]a93bb842010-02-16 23:03:474379void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]c986af502013-08-14 01:04:444380 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
4381 &state_, target);
[email protected]370eaf12013-05-18 09:19:494382 if (!texture_ref ||
4383 !texture_manager()->CanGenerateMipmaps(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:514384 LOCAL_SET_GL_ERROR(
4385 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:474386 return;
4387 }
[email protected]38c0a972012-05-12 00:48:024388
[email protected]12d95352012-12-14 07:23:544389 if (target == GL_TEXTURE_CUBE_MAP) {
4390 for (int i = 0; i < 6; ++i) {
4391 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]370eaf12013-05-18 09:19:494392 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
[email protected]ab09b612013-03-11 22:11:514393 LOCAL_SET_GL_ERROR(
4394 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544395 return;
4396 }
4397 }
4398 } else {
[email protected]370eaf12013-05-18 09:19:494399 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
[email protected]ab09b612013-03-11 22:11:514400 LOCAL_SET_GL_ERROR(
4401 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544402 return;
4403 }
[email protected]7687479c2012-05-14 23:54:044404 }
4405
[email protected]ab09b612013-03-11 22:11:514406 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:194407 // Workaround for Mac driver bug. In the large scheme of things setting
4408 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:564409 // hit so there's probably no need to make this conditional. The bug appears
4410 // to be that if the filtering mode is set to something that doesn't require
4411 // mipmaps for rendering, or is never set to something other than the default,
4412 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:154413 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:194414 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4415 }
[email protected]a93bb842010-02-16 23:03:474416 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:154417 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]370eaf12013-05-18 09:19:494418 glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
4419 texture_ref->texture()->min_filter());
[email protected]c892a4e12012-05-08 18:20:194420 }
[email protected]ab09b612013-03-11 22:11:514421 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:024422 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:494423 texture_manager()->MarkMipmapsGenerated(texture_ref);
[email protected]38c0a972012-05-12 00:48:024424 }
[email protected]a93bb842010-02-16 23:03:474425}
4426
[email protected]b273e432010-04-12 17:23:584427bool GLES2DecoderImpl::GetHelper(
4428 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:584429 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:154430 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4431 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434432 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4433 *num_written = 1;
[email protected]c959a09a2014-03-27 11:44:214434 // Return the GL implementation's preferred format and (see below type)
4435 // if we have the GL extension that exposes this. This allows the GPU
4436 // client to use the implementation's preferred format for glReadPixels
4437 // for optimisation.
4438 //
4439 // A conflicting extension (GL_ARB_ES2_compatibility) specifies an error
4440 // case when requested on integer/floating point buffers but which is
4441 // acceptable on GLES2 and with the GL_OES_read_format extension.
4442 //
4443 // Therefore if an error occurs we swallow the error and use the
4444 // internal implementation.
[email protected]ad84a3a2012-06-08 21:42:434445 if (params) {
[email protected]c959a09a2014-03-27 11:44:214446 if (context_->HasExtension("GL_OES_read_format")) {
4447 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4448 GetErrorState());
4449 glGetIntegerv(pname, params);
4450 if (glGetError() == GL_NO_ERROR)
4451 return true;
4452 }
[email protected]68586372013-12-11 01:27:594453 *params = GLES2Util::GetPreferredGLReadPixelsFormat(
4454 GetBoundReadFrameBufferInternalFormat());
[email protected]ad84a3a2012-06-08 21:42:434455 }
4456 return true;
4457 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4458 *num_written = 1;
4459 if (params) {
[email protected]c959a09a2014-03-27 11:44:214460 if (context_->HasExtension("GL_OES_read_format")) {
4461 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4462 GetErrorState());
4463 glGetIntegerv(pname, params);
4464 if (glGetError() == GL_NO_ERROR)
4465 return true;
4466 }
[email protected]68586372013-12-11 01:27:594467 *params = GLES2Util::GetPreferredGLReadPixelsType(
4468 GetBoundReadFrameBufferInternalFormat(),
4469 GetBoundReadFrameBufferTextureType());
[email protected]ad84a3a2012-06-08 21:42:434470 }
4471 return true;
4472 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4473 *num_written = 1;
4474 if (params) {
4475 *params = group_->max_fragment_uniform_vectors();
4476 }
4477 return true;
4478 case GL_MAX_VARYING_VECTORS:
4479 *num_written = 1;
4480 if (params) {
4481 *params = group_->max_varying_vectors();
4482 }
4483 return true;
4484 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4485 *num_written = 1;
4486 if (params) {
4487 *params = group_->max_vertex_uniform_vectors();
4488 }
4489 return true;
[email protected]4e8a5b122010-05-08 22:00:104490 }
[email protected]5cb735d2011-10-13 01:37:234491 }
4492 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:244493 case GL_MAX_VIEWPORT_DIMS:
4494 if (offscreen_target_frame_buffer_.get()) {
4495 *num_written = 2;
4496 if (params) {
4497 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4498 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4499 }
4500 return true;
4501 }
[email protected]5cb735d2011-10-13 01:37:234502 return false;
[email protected]84afefa2011-10-19 21:45:534503 case GL_MAX_SAMPLES:
4504 *num_written = 1;
4505 if (params) {
4506 params[0] = renderbuffer_manager()->max_samples();
4507 }
4508 return true;
4509 case GL_MAX_RENDERBUFFER_SIZE:
4510 *num_written = 1;
4511 if (params) {
4512 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4513 }
4514 return true;
[email protected]5cb735d2011-10-13 01:37:234515 case GL_MAX_TEXTURE_SIZE:
4516 *num_written = 1;
4517 if (params) {
4518 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4519 }
4520 return true;
4521 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4522 *num_written = 1;
4523 if (params) {
4524 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4525 }
4526 return true;
[email protected]2f143d482013-03-14 18:04:494527 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4528 *num_written = 1;
4529 if (params) {
4530 params[0] = group_->max_color_attachments();
4531 }
4532 return true;
4533 case GL_MAX_DRAW_BUFFERS_ARB:
4534 *num_written = 1;
4535 if (params) {
4536 params[0] = group_->max_draw_buffers();
4537 }
4538 return true;
[email protected]297ca1c2011-06-20 23:08:464539 case GL_ALPHA_BITS:
4540 *num_written = 1;
4541 if (params) {
4542 GLint v = 0;
4543 glGetIntegerv(GL_ALPHA_BITS, &v);
[email protected]f3b191b2013-06-19 03:43:544544 params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
[email protected]297ca1c2011-06-20 23:08:464545 }
4546 return true;
4547 case GL_DEPTH_BITS:
4548 *num_written = 1;
4549 if (params) {
4550 GLint v = 0;
4551 glGetIntegerv(GL_DEPTH_BITS, &v);
4552 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4553 }
4554 return true;
4555 case GL_STENCIL_BITS:
4556 *num_written = 1;
4557 if (params) {
4558 GLint v = 0;
4559 glGetIntegerv(GL_STENCIL_BITS, &v);
4560 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4561 }
4562 return true;
[email protected]656dcaad2010-05-07 17:18:374563 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114564 *num_written = validators_->compressed_texture_format.GetValues().size();
4565 if (params) {
4566 for (GLint ii = 0; ii < *num_written; ++ii) {
4567 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4568 }
4569 }
[email protected]656dcaad2010-05-07 17:18:374570 return true;
[email protected]b273e432010-04-12 17:23:584571 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4572 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104573 if (params) {
[email protected]302ce6d2011-07-07 23:28:114574 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104575 }
[email protected]b273e432010-04-12 17:23:584576 return true;
4577 case GL_NUM_SHADER_BINARY_FORMATS:
4578 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104579 if (params) {
[email protected]302ce6d2011-07-07 23:28:114580 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104581 }
[email protected]b273e432010-04-12 17:23:584582 return true;
4583 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114584 *num_written = validators_->shader_binary_format.GetValues().size();
4585 if (params) {
4586 for (GLint ii = 0; ii < *num_written; ++ii) {
4587 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4588 }
4589 }
4590 return true;
[email protected]b273e432010-04-12 17:23:584591 case GL_SHADER_COMPILER:
4592 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104593 if (params) {
4594 *params = GL_TRUE;
4595 }
[email protected]b273e432010-04-12 17:23:584596 return true;
[email protected]6b8cf1a2010-05-06 16:13:584597 case GL_ARRAY_BUFFER_BINDING:
4598 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104599 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114600 if (state_.bound_array_buffer.get()) {
[email protected]4e8a5b122010-05-08 22:00:104601 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:244602 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:104603 &client_id);
4604 *params = client_id;
4605 } else {
4606 *params = 0;
4607 }
[email protected]6b8cf1a2010-05-06 16:13:584608 }
4609 return true;
4610 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4611 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104612 if (params) {
[email protected]e259eb412012-10-13 05:47:244613 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:104614 GLuint client_id = 0;
4615 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:254616 state_.vertex_attrib_manager->element_array_buffer()->
4617 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104618 *params = client_id;
4619 } else {
4620 *params = 0;
4621 }
[email protected]6b8cf1a2010-05-06 16:13:584622 }
4623 return true;
4624 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304625 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584626 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104627 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354628 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454629 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204630 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104631 GLuint client_id = 0;
4632 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204633 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304634 *params = client_id;
4635 } else {
4636 *params = 0;
4637 }
4638 }
4639 return true;
[email protected]ebfb73c2012-08-15 02:37:454640 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304641 *num_written = 1;
4642 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354643 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454644 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204645 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304646 GLuint client_id = 0;
4647 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204648 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104649 *params = client_id;
4650 } else {
4651 *params = 0;
4652 }
[email protected]6b8cf1a2010-05-06 16:13:584653 }
4654 return true;
4655 case GL_RENDERBUFFER_BINDING:
4656 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104657 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354658 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204659 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4660 if (renderbuffer) {
[email protected]62e65f02013-05-29 22:28:104661 *params = renderbuffer->client_id();
[email protected]4e8a5b122010-05-08 22:00:104662 } else {
4663 *params = 0;
4664 }
[email protected]6b8cf1a2010-05-06 16:13:584665 }
4666 return true;
4667 case GL_CURRENT_PROGRAM:
4668 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104669 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114670 if (state_.current_program.get()) {
[email protected]4e8a5b122010-05-08 22:00:104671 GLuint client_id = 0;
4672 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244673 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104674 *params = client_id;
4675 } else {
4676 *params = 0;
4677 }
[email protected]6b8cf1a2010-05-06 16:13:584678 }
4679 return true;
[email protected]bf835842012-11-19 15:21:514680 case GL_VERTEX_ARRAY_BINDING_OES:
4681 *num_written = 1;
4682 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114683 if (state_.vertex_attrib_manager.get() !=
[email protected]81f20a622014-04-18 01:54:524684 state_.default_vertex_attrib_manager.get()) {
[email protected]bf835842012-11-19 15:21:514685 GLuint client_id = 0;
4686 vertex_array_manager_->GetClientId(
4687 state_.vertex_attrib_manager->service_id(), &client_id);
4688 *params = client_id;
4689 } else {
4690 *params = 0;
4691 }
4692 }
4693 return true;
[email protected]4e8a5b122010-05-08 22:00:104694 case GL_TEXTURE_BINDING_2D:
4695 *num_written = 1;
4696 if (params) {
[email protected]e259eb412012-10-13 05:47:244697 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114698 if (unit.bound_texture_2d.get()) {
[email protected]62e65f02013-05-29 22:28:104699 *params = unit.bound_texture_2d->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584700 } else {
4701 *params = 0;
4702 }
[email protected]6b8cf1a2010-05-06 16:13:584703 }
[email protected]4e8a5b122010-05-08 22:00:104704 return true;
4705 case GL_TEXTURE_BINDING_CUBE_MAP:
4706 *num_written = 1;
4707 if (params) {
[email protected]e259eb412012-10-13 05:47:244708 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114709 if (unit.bound_texture_cube_map.get()) {
[email protected]62e65f02013-05-29 22:28:104710 *params = unit.bound_texture_cube_map->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584711 } else {
4712 *params = 0;
4713 }
[email protected]6b8cf1a2010-05-06 16:13:584714 }
[email protected]4e8a5b122010-05-08 22:00:104715 return true;
[email protected]61eeb33f2011-07-26 15:30:314716 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4717 *num_written = 1;
4718 if (params) {
[email protected]e259eb412012-10-13 05:47:244719 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114720 if (unit.bound_texture_external_oes.get()) {
[email protected]62e65f02013-05-29 22:28:104721 *params = unit.bound_texture_external_oes->client_id();
[email protected]61eeb33f2011-07-26 15:30:314722 } else {
4723 *params = 0;
4724 }
4725 }
4726 return true;
[email protected]e51bdf32011-11-23 22:21:464727 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4728 *num_written = 1;
4729 if (params) {
[email protected]e259eb412012-10-13 05:47:244730 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114731 if (unit.bound_texture_rectangle_arb.get()) {
[email protected]62e65f02013-05-29 22:28:104732 *params = unit.bound_texture_rectangle_arb->client_id();
[email protected]e51bdf32011-11-23 22:21:464733 } else {
4734 *params = 0;
4735 }
4736 }
4737 return true;
[email protected]6c75c712012-06-19 15:43:174738 case GL_UNPACK_FLIP_Y_CHROMIUM:
4739 *num_written = 1;
4740 if (params) {
4741 params[0] = unpack_flip_y_;
4742 }
4743 return true;
4744 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4745 *num_written = 1;
4746 if (params) {
4747 params[0] = unpack_premultiply_alpha_;
4748 }
4749 return true;
4750 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4751 *num_written = 1;
4752 if (params) {
4753 params[0] = unpack_unpremultiply_alpha_;
4754 }
4755 return true;
[email protected]6eda6822014-04-03 23:00:504756 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
4757 *num_written = 1;
4758 if (params) {
4759 params[0] = group_->bind_generates_resource() ? 1 : 0;
4760 }
4761 return true;
[email protected]b273e432010-04-12 17:23:584762 default:
[email protected]2f143d482013-03-14 18:04:494763 if (pname >= GL_DRAW_BUFFER0_ARB &&
4764 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
4765 *num_written = 1;
4766 if (params) {
4767 Framebuffer* framebuffer =
4768 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4769 if (framebuffer) {
4770 params[0] = framebuffer->GetDrawBuffer(pname);
4771 } else { // backbuffer
4772 if (pname == GL_DRAW_BUFFER0_ARB)
4773 params[0] = group_->draw_buffer();
4774 else
4775 params[0] = GL_NONE;
4776 }
4777 }
4778 return true;
4779 }
[email protected]4e8a5b122010-05-08 22:00:104780 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534781 return false;
[email protected]b273e432010-04-12 17:23:584782 }
4783}
4784
[email protected]4e8a5b122010-05-08 22:00:104785bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4786 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264787 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534788 return true;
4789 }
[email protected]4e8a5b122010-05-08 22:00:104790 return GetHelper(pname, NULL, num_values);
4791}
4792
[email protected]7d3c36e2013-07-12 14:13:164793GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) {
4794 if (GL_MAX_SAMPLES == pname &&
4795 features().use_img_for_multisampled_render_to_texture) {
4796 return GL_MAX_SAMPLES_IMG;
4797 }
4798 return pname;
4799}
4800
[email protected]b273e432010-04-12 17:23:584801void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4802 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104803 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534804 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554805 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:264806 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:534807 GetHelper(pname, values.get(), &num_written);
4808 }
[email protected]b273e432010-04-12 17:23:584809 for (GLsizei ii = 0; ii < num_written; ++ii) {
4810 params[ii] = static_cast<GLboolean>(values[ii]);
4811 }
4812 } else {
[email protected]7d3c36e2013-07-12 14:13:164813 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584814 glGetBooleanv(pname, params);
4815 }
4816}
4817
4818void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4819 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104820 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:264821 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:534822 if (GetHelper(pname, NULL, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554823 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]f63b1232012-10-31 07:03:534824 GetHelper(pname, values.get(), &num_written);
4825 for (GLsizei ii = 0; ii < num_written; ++ii) {
4826 params[ii] = static_cast<GLfloat>(values[ii]);
4827 }
4828 } else {
[email protected]7d3c36e2013-07-12 14:13:164829 pname = AdjustGetPname(pname);
[email protected]f63b1232012-10-31 07:03:534830 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:584831 }
[email protected]b273e432010-04-12 17:23:584832 }
4833}
4834
4835void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4836 DCHECK(params);
4837 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:264838 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:534839 !GetHelper(pname, params, &num_written)) {
[email protected]7d3c36e2013-07-12 14:13:164840 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584841 glGetIntegerv(pname, params);
4842 }
4843}
4844
[email protected]a0c3e972010-04-21 00:49:134845void GLES2DecoderImpl::DoGetProgramiv(
4846 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:424847 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
4848 if (!program) {
[email protected]a0c3e972010-04-21 00:49:134849 return;
4850 }
[email protected]df37b9932013-03-08 05:21:424851 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:134852}
4853
[email protected]17cfbe0e2013-03-07 01:26:084854void GLES2DecoderImpl::DoGetBufferParameteriv(
4855 GLenum target, GLenum pname, GLint* params) {
[email protected]0fbba3732013-07-17 15:40:134856 // Just delegate it. Some validation is actually done before this.
4857 buffer_manager()->ValidateAndDoGetBufferParameteriv(
4858 &state_, target, pname, params);
[email protected]17cfbe0e2013-03-07 01:26:084859}
4860
[email protected]258a3313f2011-10-18 20:13:574861void GLES2DecoderImpl::DoBindAttribLocation(
[email protected]df37b9932013-03-08 05:21:424862 GLuint program_id, GLuint index, const char* name) {
[email protected]258a3313f2011-10-18 20:13:574863 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514864 LOCAL_SET_GL_ERROR(
4865 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:574866 return;
4867 }
[email protected]68dcb1f2012-04-07 00:14:564868 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514869 LOCAL_SET_GL_ERROR(
4870 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:564871 return;
4872 }
4873 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:514874 LOCAL_SET_GL_ERROR(
4875 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:564876 return;
4877 }
[email protected]df37b9932013-03-08 05:21:424878 Program* program = GetProgramInfoNotShader(
4879 program_id, "glBindAttribLocation");
4880 if (!program) {
[email protected]258a3313f2011-10-18 20:13:574881 return;
[email protected]558847a2010-03-24 07:02:544882 }
zmo460b593e2014-10-13 23:07:454883 // At this point, the program's shaders may not be translated yet,
4884 // therefore, we may not find the hashed attribute name.
4885 // glBindAttribLocation call with original name is useless.
4886 // So instead, we should simply cache the binding, and then call
4887 // Program::ExecuteBindAttribLocationCalls() right before link.
[email protected]df37b9932013-03-08 05:21:424888 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
zmo460b593e2014-10-13 23:07:454889 // TODO(zmo): Get rid of the following glBindAttribLocation call.
[email protected]df37b9932013-03-08 05:21:424890 glBindAttribLocation(program->service_id(), index, name);
[email protected]258a3313f2011-10-18 20:13:574891}
4892
[email protected]558847a2010-03-24 07:02:544893error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
vmiuracd108592014-09-08 14:36:344894 uint32 immediate_data_size,
4895 const void* cmd_data) {
4896 const gles2::cmds::BindAttribLocationBucket& c =
4897 *static_cast<const gles2::cmds::BindAttribLocationBucket*>(cmd_data);
[email protected]6b8cf1a2010-05-06 16:13:584898 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544899 GLuint index = static_cast<GLuint>(c.index);
4900 Bucket* bucket = GetBucket(c.name_bucket_id);
4901 if (!bucket || bucket->size() == 0) {
4902 return error::kInvalidArguments;
4903 }
4904 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:184905 if (!bucket->GetAsString(&name_str)) {
4906 return error::kInvalidArguments;
4907 }
[email protected]258a3313f2011-10-18 20:13:574908 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544909 return error::kNoError;
4910}
4911
[email protected]2be6abf32012-06-26 00:28:334912void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:424913 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:334914 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514915 LOCAL_SET_GL_ERROR(
4916 GL_INVALID_VALUE,
4917 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:334918 return;
4919 }
4920 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514921 LOCAL_SET_GL_ERROR(
4922 GL_INVALID_OPERATION,
4923 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:334924 return;
4925 }
4926 if (location < 0 || static_cast<uint32>(location) >=
4927 (group_->max_fragment_uniform_vectors() +
4928 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:514929 LOCAL_SET_GL_ERROR(
4930 GL_INVALID_VALUE,
4931 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334932 return;
4933 }
[email protected]df37b9932013-03-08 05:21:424934 Program* program = GetProgramInfoNotShader(
4935 program_id, "glBindUniformLocationCHROMIUM");
4936 if (!program) {
[email protected]2be6abf32012-06-26 00:28:334937 return;
4938 }
[email protected]df37b9932013-03-08 05:21:424939 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:514940 LOCAL_SET_GL_ERROR(
4941 GL_INVALID_VALUE,
4942 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334943 }
4944}
4945
[email protected]2be6abf32012-06-26 00:28:334946error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
4947 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:344948 const void* cmd_data) {
4949 const gles2::cmds::BindUniformLocationCHROMIUMBucket& c =
4950 *static_cast<const gles2::cmds::BindUniformLocationCHROMIUMBucket*>(
4951 cmd_data);
[email protected]2be6abf32012-06-26 00:28:334952 GLuint program = static_cast<GLuint>(c.program);
4953 GLint location = static_cast<GLint>(c.location);
4954 Bucket* bucket = GetBucket(c.name_bucket_id);
4955 if (!bucket || bucket->size() == 0) {
4956 return error::kInvalidArguments;
4957 }
4958 std::string name_str;
4959 if (!bucket->GetAsString(&name_str)) {
4960 return error::kInvalidArguments;
4961 }
4962 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4963 return error::kNoError;
4964}
4965
vmiuracd108592014-09-08 14:36:344966error::Error GLES2DecoderImpl::HandleDeleteShader(uint32 immediate_data_size,
4967 const void* cmd_data) {
4968 const gles2::cmds::DeleteShader& c =
4969 *static_cast<const gles2::cmds::DeleteShader*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:034970 GLuint client_id = c.shader;
4971 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424972 Shader* shader = GetShader(client_id);
4973 if (shader) {
4974 if (!shader->IsDeleted()) {
4975 glDeleteShader(shader->service_id());
4976 shader_manager()->MarkAsDeleted(shader);
[email protected]ca488e12010-12-13 20:06:144977 }
[email protected]ae51d192010-04-27 00:48:034978 } else {
[email protected]ab09b612013-03-11 22:11:514979 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:034980 }
[email protected]96449d2c2009-11-25 00:01:324981 }
[email protected]f7a64ee2010-02-01 22:24:144982 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324983}
4984
vmiuracd108592014-09-08 14:36:344985error::Error GLES2DecoderImpl::HandleDeleteProgram(uint32 immediate_data_size,
4986 const void* cmd_data) {
4987 const gles2::cmds::DeleteProgram& c =
4988 *static_cast<const gles2::cmds::DeleteProgram*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:034989 GLuint client_id = c.program;
4990 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424991 Program* program = GetProgram(client_id);
4992 if (program) {
4993 if (!program->IsDeleted()) {
4994 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:144995 }
[email protected]ae51d192010-04-27 00:48:034996 } else {
[email protected]ab09b612013-03-11 22:11:514997 LOCAL_SET_GL_ERROR(
4998 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:034999 }
[email protected]96449d2c2009-11-25 00:01:325000 }
[email protected]f7a64ee2010-02-01 22:24:145001 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:325002}
5003
[email protected]a7266a92012-06-28 02:11:085004error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:445005 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:205006 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]297ca1c2011-06-20 23:08:465007 ApplyDirtyState();
boliu2e7d8a7a2014-10-16 20:35:205008 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]3a03a8f2011-03-19 00:51:275009 glClear(mask);
5010 }
[email protected]a7266a92012-06-28 02:11:085011 return error::kNoError;
5012}
5013
[email protected]36cef8ce2010-03-16 07:34:455014void GLES2DecoderImpl::DoFramebufferRenderbuffer(
5015 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:035016 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:065017 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5018 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515019 LOCAL_SET_GL_ERROR(
5020 GL_INVALID_OPERATION,
5021 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455022 return;
5023 }
[email protected]ae51d192010-04-27 00:48:035024 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:275025 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:035026 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:275027 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
5028 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515029 LOCAL_SET_GL_ERROR(
5030 GL_INVALID_OPERATION,
5031 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:035032 return;
5033 }
[email protected]ee2a79c32013-03-10 03:50:275034 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:035035 }
[email protected]ab09b612013-03-11 22:11:515036 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:035037 glFramebufferRenderbufferEXT(
5038 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:515039 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:265040 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:275041 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:285042 }
[email protected]9d3b2e12013-10-02 01:04:345043 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445044 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465045 }
[email protected]81fc9d02013-03-14 23:53:325046 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:285047}
5048
[email protected]3a2e7c7b2010-08-06 01:12:285049void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465050 if (SetCapabilityState(cap, false)) {
5051 glDisable(cap);
5052 }
[email protected]3a2e7c7b2010-08-06 01:12:285053}
5054
5055void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465056 if (SetCapabilityState(cap, true)) {
5057 glEnable(cap);
5058 }
[email protected]3a2e7c7b2010-08-06 01:12:285059}
5060
[email protected]88a61bf2012-10-27 13:00:425061void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
5062 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
5063 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
5064 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:285065}
5066
[email protected]b04e24c2013-01-08 18:35:255067void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:425068 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
5069 state_.sample_coverage_invert = (invert != 0);
5070 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:285071}
5072
[email protected]0d6bfdc2011-11-02 01:32:205073// Assumes framebuffer is complete.
5074void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:065075 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:305076 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:205077 // bind this to the DRAW point, clear then bind back to READ
5078 // TODO(gman): I don't think there is any guarantee that an FBO that
5079 // is complete on the READ attachment will be complete as a DRAW
5080 // attachment.
5081 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:065082 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:305083 }
[email protected]3a2e7c7b2010-08-06 01:12:285084 GLbitfield clear_bits = 0;
[email protected]ee757922014-06-06 05:21:425085 if (framebuffer->HasUnclearedColorAttachments()) {
[email protected]297ca1c2011-06-20 23:08:465086 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:205087 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:465088 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:065089 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
5090 1.0f);
[email protected]454157e2014-05-03 02:49:455091 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285092 clear_bits |= GL_COLOR_BUFFER_BIT;
[email protected]0e58af82014-08-08 14:02:535093 if (feature_info_->feature_flags().ext_draw_buffers)
5094 framebuffer->PrepareDrawBuffersForClear();
[email protected]3a2e7c7b2010-08-06 01:12:285095 }
5096
[email protected]4d8f0dd2013-03-09 14:37:065097 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
5098 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285099 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:475100 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
5101 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]3a2e7c7b2010-08-06 01:12:285102 clear_bits |= GL_STENCIL_BUFFER_BIT;
5103 }
5104
[email protected]4d8f0dd2013-03-09 14:37:065105 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
5106 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285107 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:455108 state_.SetDeviceDepthMask(GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285109 clear_bits |= GL_DEPTH_BUFFER_BIT;
5110 }
5111
[email protected]454157e2014-05-03 02:49:455112 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]3a2e7c7b2010-08-06 01:12:285113 glClear(clear_bits);
5114
[email protected]0e58af82014-08-08 14:02:535115 if ((clear_bits | GL_COLOR_BUFFER_BIT) != 0 &&
5116 feature_info_->feature_flags().ext_draw_buffers)
[email protected]ee757922014-06-06 05:21:425117 framebuffer->RestoreDrawBuffersAfterClear();
5118
[email protected]968351b2011-12-20 08:26:515119 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:065120 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:285121
[email protected]c007aa02010-09-02 22:22:405122 RestoreClearState();
5123
5124 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:065125 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
5126 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:485127 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:065128 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
5129 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:485130 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:405131 }
5132}
5133
5134void GLES2DecoderImpl::RestoreClearState() {
[email protected]c986af502013-08-14 01:04:445135 framebuffer_state_.clear_state_dirty = true;
[email protected]e259eb412012-10-13 05:47:245136 glClearColor(
5137 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
5138 state_.color_clear_alpha);
5139 glClearStencil(state_.stencil_clear);
5140 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:225141 if (state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:455142 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]3a2e7c7b2010-08-06 01:12:285143 }
[email protected]36cef8ce2010-03-16 07:34:455144}
5145
5146GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:355147 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:305148 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:205149 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:455150 return GL_FRAMEBUFFER_COMPLETE;
5151 }
[email protected]0d6bfdc2011-11-02 01:32:205152 GLenum completeness = framebuffer->IsPossiblyComplete();
5153 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
5154 return completeness;
5155 }
[email protected]73276522012-11-09 05:50:205156 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:455157}
5158
5159void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:035160 GLenum target, GLenum attachment, GLenum textarget,
5161 GLuint client_texture_id, GLint level) {
[email protected]7d3c36e2013-07-12 14:13:165162 DoFramebufferTexture2DCommon(
5163 "glFramebufferTexture2D", target, attachment,
5164 textarget, client_texture_id, level, 0);
5165}
5166
5167void GLES2DecoderImpl::DoFramebufferTexture2DMultisample(
5168 GLenum target, GLenum attachment, GLenum textarget,
5169 GLuint client_texture_id, GLint level, GLsizei samples) {
[email protected]7d3c36e2013-07-12 14:13:165170 DoFramebufferTexture2DCommon(
5171 "glFramebufferTexture2DMultisample", target, attachment,
5172 textarget, client_texture_id, level, samples);
5173}
5174
5175void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
5176 const char* name, GLenum target, GLenum attachment, GLenum textarget,
5177 GLuint client_texture_id, GLint level, GLsizei samples) {
5178 if (samples > renderbuffer_manager()->max_samples()) {
5179 LOCAL_SET_GL_ERROR(
5180 GL_INVALID_VALUE,
5181 "glFramebufferTexture2DMultisample", "samples too large");
5182 return;
5183 }
[email protected]4d8f0dd2013-03-09 14:37:065184 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5185 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515186 LOCAL_SET_GL_ERROR(
5187 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165188 name, "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:455189 return;
5190 }
[email protected]ae51d192010-04-27 00:48:035191 GLuint service_id = 0;
[email protected]370eaf12013-05-18 09:19:495192 TextureRef* texture_ref = NULL;
[email protected]ae51d192010-04-27 00:48:035193 if (client_texture_id) {
[email protected]370eaf12013-05-18 09:19:495194 texture_ref = GetTexture(client_texture_id);
5195 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:515196 LOCAL_SET_GL_ERROR(
5197 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165198 name, "unknown texture_ref");
[email protected]ae51d192010-04-27 00:48:035199 return;
5200 }
[email protected]370eaf12013-05-18 09:19:495201 service_id = texture_ref->service_id();
[email protected]ae51d192010-04-27 00:48:035202 }
[email protected]0d6bfdc2011-11-02 01:32:205203
[email protected]80eb6b52012-01-19 00:14:415204 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:515205 LOCAL_SET_GL_ERROR(
5206 GL_INVALID_VALUE,
[email protected]7d3c36e2013-07-12 14:13:165207 name, "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:205208 return;
5209 }
5210
[email protected]91c94eb2013-10-22 10:32:545211 if (texture_ref)
5212 DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget);
5213
[email protected]7d3c36e2013-07-12 14:13:165214 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
5215 if (0 == samples) {
5216 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
5217 } else {
5218 if (features().use_img_for_multisampled_render_to_texture) {
5219 glFramebufferTexture2DMultisampleIMG(target, attachment, textarget,
5220 service_id, level, samples);
5221 } else {
5222 glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
5223 service_id, level, samples);
5224 }
5225 }
5226 GLenum error = LOCAL_PEEK_GL_ERROR(name);
[email protected]9edc6b22010-12-23 02:00:265227 if (error == GL_NO_ERROR) {
[email protected]7d3c36e2013-07-12 14:13:165228 framebuffer->AttachTexture(attachment, texture_ref, textarget, level,
5229 samples);
[email protected]3a2e7c7b2010-08-06 01:12:285230 }
[email protected]9d3b2e12013-10-02 01:04:345231 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445232 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465233 }
[email protected]91c94eb2013-10-22 10:32:545234
5235 if (texture_ref)
5236 DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget);
5237
[email protected]81fc9d02013-03-14 23:53:325238 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:455239}
5240
5241void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
5242 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:065243 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5244 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515245 LOCAL_SET_GL_ERROR(
5246 GL_INVALID_OPERATION,
[email protected]caa13ed2014-02-17 11:29:205247 "glGetFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455248 return;
5249 }
[email protected]74c1ec42010-08-12 01:55:575250 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
[email protected]62e65f02013-05-29 22:28:105251 const Framebuffer::Attachment* attachment_object =
5252 framebuffer->GetAttachment(attachment);
5253 *params = attachment_object ? attachment_object->object_name() : 0;
5254 } else {
[email protected]7d3c36e2013-07-12 14:13:165255 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT &&
5256 features().use_img_for_multisampled_render_to_texture) {
5257 pname = GL_TEXTURE_SAMPLES_IMG;
5258 }
[email protected]62e65f02013-05-29 22:28:105259 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:575260 }
[email protected]36cef8ce2010-03-16 07:34:455261}
5262
5263void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
5264 GLenum target, GLenum pname, GLint* params) {
[email protected]ed9f9cd2013-02-27 21:12:355265 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205266 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5267 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515268 LOCAL_SET_GL_ERROR(
5269 GL_INVALID_OPERATION,
5270 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455271 return;
5272 }
[email protected]8875a5f2014-06-27 08:33:475273
5274 EnsureRenderbufferBound();
[email protected]3a03a8f2011-03-19 00:51:275275 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:435276 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5277 *params = renderbuffer->internal_format();
5278 break;
5279 case GL_RENDERBUFFER_WIDTH:
5280 *params = renderbuffer->width();
5281 break;
5282 case GL_RENDERBUFFER_HEIGHT:
5283 *params = renderbuffer->height();
5284 break;
[email protected]7d3c36e2013-07-12 14:13:165285 case GL_RENDERBUFFER_SAMPLES_EXT:
5286 if (features().use_img_for_multisampled_render_to_texture) {
5287 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG,
5288 params);
5289 } else {
5290 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT,
5291 params);
5292 }
[email protected]ad84a3a2012-06-08 21:42:435293 default:
5294 glGetRenderbufferParameterivEXT(target, pname, params);
5295 break;
[email protected]b71f52c2010-06-18 22:20:205296 }
[email protected]36cef8ce2010-03-16 07:34:455297}
5298
[email protected]49cabed2013-11-13 18:15:185299void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:305300 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
5301 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5302 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:445303 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]0c16343f2013-03-08 20:40:165304
[email protected]49cabed2013-11-13 18:15:185305 if (!CheckBoundFramebuffersValid("glBlitFramebufferCHROMIUM")) {
[email protected]0c16343f2013-03-08 20:40:165306 return;
5307 }
5308
[email protected]454157e2014-05-03 02:49:455309 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
boliu2e7d8a7a2014-10-16 20:35:205310 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]f42f05b2013-11-15 21:46:185311 BlitFramebufferHelper(
5312 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]454157e2014-05-03 02:49:455313 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST,
5314 state_.enable_flags.scissor_test);
[email protected]f42f05b2013-11-15 21:46:185315}
5316
[email protected]8875a5f2014-06-27 08:33:475317void GLES2DecoderImpl::EnsureRenderbufferBound() {
5318 if (!state_.bound_renderbuffer_valid) {
5319 state_.bound_renderbuffer_valid = true;
5320 glBindRenderbufferEXT(GL_RENDERBUFFER,
5321 state_.bound_renderbuffer.get()
5322 ? state_.bound_renderbuffer->service_id()
5323 : 0);
5324 }
5325}
5326
[email protected]f42f05b2013-11-15 21:46:185327void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(
5328 const FeatureInfo* feature_info,
5329 GLenum target,
5330 GLsizei samples,
5331 GLenum internal_format,
5332 GLsizei width,
5333 GLsizei height) {
5334 // TODO(sievers): This could be resolved at the GL binding level, but the
5335 // binding process is currently a bit too 'brute force'.
5336 if (feature_info->feature_flags().is_angle) {
5337 glRenderbufferStorageMultisampleANGLE(
5338 target, samples, internal_format, width, height);
5339 } else if (feature_info->feature_flags().use_core_framebuffer_multisample) {
5340 glRenderbufferStorageMultisample(
5341 target, samples, internal_format, width, height);
5342 } else {
5343 glRenderbufferStorageMultisampleEXT(
5344 target, samples, internal_format, width, height);
5345 }
5346}
5347
5348void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0,
5349 GLint srcY0,
5350 GLint srcX1,
5351 GLint srcY1,
5352 GLint dstX0,
5353 GLint dstY0,
5354 GLint dstX1,
5355 GLint dstY1,
5356 GLbitfield mask,
5357 GLenum filter) {
5358 // TODO(sievers): This could be resolved at the GL binding level, but the
5359 // binding process is currently a bit too 'brute force'.
5360 if (feature_info_->feature_flags().is_angle) {
[email protected]5094b0f2010-11-09 19:45:245361 glBlitFramebufferANGLE(
5362 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]f42f05b2013-11-15 21:46:185363 } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) {
5364 glBlitFramebuffer(
5365 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]5094b0f2010-11-09 19:45:245366 } else {
5367 glBlitFramebufferEXT(
5368 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5369 }
[email protected]8e3e0662010-08-23 18:46:305370}
5371
[email protected]49cabed2013-11-13 18:15:185372bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample(
5373 GLsizei samples,
5374 GLenum internalformat,
5375 GLsizei width,
5376 GLsizei height) {
[email protected]84afefa2011-10-19 21:45:535377 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:515378 LOCAL_SET_GL_ERROR(
5379 GL_INVALID_VALUE,
5380 "glRenderbufferStorageMultisample", "samples too large");
[email protected]49cabed2013-11-13 18:15:185381 return false;
[email protected]84afefa2011-10-19 21:45:535382 }
5383
5384 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5385 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515386 LOCAL_SET_GL_ERROR(
5387 GL_INVALID_VALUE,
5388 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185389 return false;
[email protected]84afefa2011-10-19 21:45:535390 }
5391
[email protected]7989c9e2013-01-23 06:39:265392 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235393 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5394 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515395 LOCAL_SET_GL_ERROR(
5396 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205397 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185398 return false;
[email protected]8e3e0662010-08-23 18:46:305399 }
5400
[email protected]7989c9e2013-01-23 06:39:265401 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515402 LOCAL_SET_GL_ERROR(
5403 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205404 "glRenderbufferStorageMultisample", "out of memory");
[email protected]49cabed2013-11-13 18:15:185405 return false;
5406 }
5407
5408 return true;
5409}
5410
5411void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM(
5412 GLenum target, GLsizei samples, GLenum internalformat,
5413 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185414 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5415 if (!renderbuffer) {
5416 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5417 "glRenderbufferStorageMultisampleCHROMIUM",
5418 "no renderbuffer bound");
5419 return;
5420 }
5421
5422 if (!ValidateRenderbufferStorageMultisample(
5423 samples, internalformat, width, height)) {
[email protected]7989c9e2013-01-23 06:39:265424 return;
5425 }
5426
[email protected]8875a5f2014-06-27 08:33:475427 EnsureRenderbufferBound();
[email protected]8e102e102013-09-20 22:50:235428 GLenum impl_format =
5429 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5430 internalformat);
[email protected]49cabed2013-11-13 18:15:185431 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(
5432 "glRenderbufferStorageMultisampleCHROMIUM");
[email protected]f42f05b2013-11-15 21:46:185433 RenderbufferStorageMultisampleHelper(
Daniel Cheng3d7ce9f2014-08-26 00:26:255434 feature_info_.get(), target, samples, impl_format, width, height);
[email protected]49cabed2013-11-13 18:15:185435 GLenum error =
5436 LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM");
[email protected]9edc6b22010-12-23 02:00:265437 if (error == GL_NO_ERROR) {
[email protected]4a4c18b2013-09-13 22:50:105438
5439 if (workarounds().validate_multisample_buffer_allocation) {
5440 if (!VerifyMultisampleRenderbufferIntegrity(
5441 renderbuffer->service_id(), impl_format)) {
5442 LOCAL_SET_GL_ERROR(
5443 GL_OUT_OF_MEMORY,
[email protected]49cabed2013-11-13 18:15:185444 "glRenderbufferStorageMultisampleCHROMIUM", "out of memory");
[email protected]4a4c18b2013-09-13 22:50:105445 return;
5446 }
5447 }
5448
[email protected]968351b2011-12-20 08:26:515449 // TODO(gman): If renderbuffers tracked which framebuffers they were
5450 // attached to we could just mark those framebuffers as not complete.
5451 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205452 renderbuffer_manager()->SetInfo(
5453 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265454 }
[email protected]8e3e0662010-08-23 18:46:305455}
5456
[email protected]49cabed2013-11-13 18:15:185457// This is the handler for multisampled_render_to_texture extensions.
5458void GLES2DecoderImpl::DoRenderbufferStorageMultisampleEXT(
5459 GLenum target, GLsizei samples, GLenum internalformat,
5460 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185461 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5462 if (!renderbuffer) {
5463 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5464 "glRenderbufferStorageMultisampleEXT",
5465 "no renderbuffer bound");
5466 return;
5467 }
5468
5469 if (!ValidateRenderbufferStorageMultisample(
5470 samples, internalformat, width, height)) {
5471 return;
5472 }
5473
[email protected]8875a5f2014-06-27 08:33:475474 EnsureRenderbufferBound();
[email protected]49cabed2013-11-13 18:15:185475 GLenum impl_format =
5476 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5477 internalformat);
5478 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT");
5479 if (features().use_img_for_multisampled_render_to_texture) {
5480 glRenderbufferStorageMultisampleIMG(
5481 target, samples, impl_format, width, height);
5482 } else {
5483 glRenderbufferStorageMultisampleEXT(
5484 target, samples, impl_format, width, height);
5485 }
5486 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT");
5487 if (error == GL_NO_ERROR) {
5488 // TODO(gman): If renderbuffers tracked which framebuffers they were
5489 // attached to we could just mark those framebuffers as not complete.
5490 framebuffer_manager()->IncFramebufferStateChangeCount();
5491 renderbuffer_manager()->SetInfo(
5492 renderbuffer, samples, internalformat, width, height);
5493 }
5494}
5495
[email protected]4a4c18b2013-09-13 22:50:105496// This function validates the allocation of a multisampled renderbuffer
5497// by clearing it to a key color, blitting the contents to a texture, and
5498// reading back the color to ensure it matches the key.
5499bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity(
5500 GLuint renderbuffer, GLenum format) {
5501
5502 // Only validate color buffers.
5503 // These formats have been selected because they are very common or are known
5504 // to be used by the WebGL backbuffer. If problems are observed with other
5505 // color formats they can be added here.
5506 switch(format) {
5507 case GL_RGB:
5508 case GL_RGB8:
5509 case GL_RGBA:
5510 case GL_RGBA8:
5511 break;
5512 default:
5513 return true;
5514 }
5515
5516 GLint draw_framebuffer, read_framebuffer;
5517
5518 // Cache framebuffer and texture bindings.
5519 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer);
5520 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer);
5521
5522 if (!validation_texture_) {
5523 GLint bound_texture;
5524 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
5525
5526 // Create additional resources needed for the verification.
5527 glGenTextures(1, &validation_texture_);
5528 glGenFramebuffersEXT(1, &validation_fbo_multisample_);
5529 glGenFramebuffersEXT(1, &validation_fbo_);
5530
5531 // Texture only needs to be 1x1.
5532 glBindTexture(GL_TEXTURE_2D, validation_texture_);
5533 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB,
5534 GL_UNSIGNED_BYTE, NULL);
5535
5536 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5537 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5538 GL_TEXTURE_2D, validation_texture_, 0);
5539
5540 glBindTexture(GL_TEXTURE_2D, bound_texture);
5541 }
5542
5543 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5544 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5545 GL_RENDERBUFFER, renderbuffer);
5546
5547 // Cache current state and reset it to the values we require.
5548 GLboolean scissor_enabled = false;
5549 glGetBooleanv(GL_SCISSOR_TEST, &scissor_enabled);
5550 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455551 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]4a4c18b2013-09-13 22:50:105552
[email protected]454157e2014-05-03 02:49:455553 GLboolean color_mask[4] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
[email protected]4a4c18b2013-09-13 22:50:105554 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask);
[email protected]454157e2014-05-03 02:49:455555 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]4a4c18b2013-09-13 22:50:105556
5557 GLfloat clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5558 glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color);
5559 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
5560
5561 // Clear the buffer to the desired key color.
5562 glClear(GL_COLOR_BUFFER_BIT);
5563
5564 // Blit from the multisample buffer to a standard texture.
5565 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, validation_fbo_multisample_);
5566 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, validation_fbo_);
5567
[email protected]f42f05b2013-11-15 21:46:185568 BlitFramebufferHelper(
5569 0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
[email protected]4a4c18b2013-09-13 22:50:105570
5571 // Read a pixel from the buffer.
5572 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5573
5574 unsigned char pixel[3] = {0, 0, 0};
5575 glReadPixels(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);
5576
5577 // Detach the renderbuffer.
5578 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5579 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5580 GL_RENDERBUFFER, 0);
5581
5582 // Restore cached state.
5583 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455584 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]4a4c18b2013-09-13 22:50:105585
[email protected]454157e2014-05-03 02:49:455586 state_.SetDeviceColorMask(
5587 color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
[email protected]4a4c18b2013-09-13 22:50:105588 glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
5589 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, draw_framebuffer);
5590 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, read_framebuffer);
5591
5592 // Return true if the pixel matched the desired key color.
5593 return (pixel[0] == 0xFF &&
5594 pixel[1] == 0x00 &&
5595 pixel[2] == 0xFF);
5596}
5597
[email protected]36cef8ce2010-03-16 07:34:455598void GLES2DecoderImpl::DoRenderbufferStorage(
5599 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:355600 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205601 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5602 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515603 LOCAL_SET_GL_ERROR(
5604 GL_INVALID_OPERATION,
5605 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455606 return;
5607 }
[email protected]876f6fee2010-08-02 23:10:325608
[email protected]84afefa2011-10-19 21:45:535609 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5610 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515611 LOCAL_SET_GL_ERROR(
5612 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535613 return;
5614 }
5615
[email protected]7989c9e2013-01-23 06:39:265616 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235617 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5618 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515619 LOCAL_SET_GL_ERROR(
5620 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265621 return;
5622 }
5623
5624 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515625 LOCAL_SET_GL_ERROR(
5626 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265627 return;
[email protected]b71f52c2010-06-18 22:20:205628 }
[email protected]876f6fee2010-08-02 23:10:325629
[email protected]8875a5f2014-06-27 08:33:475630 EnsureRenderbufferBound();
[email protected]ab09b612013-03-11 22:11:515631 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:265632 glRenderbufferStorageEXT(
[email protected]8e102e102013-09-20 22:50:235633 target,
5634 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5635 internalformat),
5636 width,
5637 height);
[email protected]ab09b612013-03-11 22:11:515638 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:265639 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515640 // TODO(gman): If tetxures tracked which framebuffers they were attached to
5641 // we could just mark those framebuffers as not complete.
5642 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205643 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:265644 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265645 }
[email protected]36cef8ce2010-03-16 07:34:455646}
5647
[email protected]df37b9932013-03-08 05:21:425648void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:385649 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:425650 Program* program = GetProgramInfoNotShader(
5651 program_id, "glLinkProgram");
5652 if (!program) {
[email protected]a93bb842010-02-16 23:03:475653 return;
5654 }
[email protected]05afda12011-01-20 00:17:345655
[email protected]df37b9932013-03-08 05:21:425656 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]65dfc602012-07-23 20:39:395657 ShaderTranslator* vertex_translator = NULL;
5658 ShaderTranslator* fragment_translator = NULL;
5659 if (use_shader_translator_) {
[email protected]7cd76fd2013-06-02 21:11:115660 vertex_translator = vertex_translator_.get();
5661 fragment_translator = fragment_translator_.get();
[email protected]65dfc602012-07-23 20:39:395662 }
[email protected]df37b9932013-03-08 05:21:425663 if (program->Link(shader_manager(),
[email protected]7cd76fd2013-06-02 21:11:115664 vertex_translator,
5665 fragment_translator,
[email protected]008401532014-02-07 00:10:505666 workarounds().count_all_in_varyings_packing ?
5667 Program::kCountAll : Program::kCountOnlyStaticallyUsed,
[email protected]7cd76fd2013-06-02 21:11:115668 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:425669 if (program == state_.current_program.get()) {
[email protected]b05955552014-02-06 18:41:185670 if (workarounds().use_current_program_after_successful_link)
[email protected]df37b9932013-03-08 05:21:425671 glUseProgram(program->service_id());
[email protected]b05955552014-02-06 18:41:185672 if (workarounds().clear_uniforms_before_first_program_use)
5673 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:545674 }
5675 }
vmiura8266ca72014-09-09 21:37:005676
5677 // LinkProgram can be very slow. Exit command processing to allow for
5678 // context preemption and GPU watchdog checks.
5679 ExitCommandProcessingEarly();
[email protected]07f54fcc2009-12-22 02:46:305680};
5681
[email protected]3916c97e2010-02-25 03:20:505682void GLES2DecoderImpl::DoTexParameterf(
5683 GLenum target, GLenum pname, GLfloat param) {
[email protected]c986af502013-08-14 01:04:445684 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5685 &state_, target);
[email protected]02965c22013-03-09 02:40:075686 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515687 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245688 return;
[email protected]07f54fcc2009-12-22 02:46:305689 }
[email protected]cbb22e42011-05-12 23:36:245690
[email protected]737191ee72014-03-09 08:02:425691 texture_manager()->SetParameterf(
5692 "glTexParameterf", GetErrorState(), texture, pname, param);
[email protected]07f54fcc2009-12-22 02:46:305693}
5694
[email protected]3916c97e2010-02-25 03:20:505695void GLES2DecoderImpl::DoTexParameteri(
5696 GLenum target, GLenum pname, GLint param) {
[email protected]c986af502013-08-14 01:04:445697 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5698 &state_, target);
[email protected]02965c22013-03-09 02:40:075699 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515700 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245701 return;
[email protected]3916c97e2010-02-25 03:20:505702 }
[email protected]cbb22e42011-05-12 23:36:245703
[email protected]737191ee72014-03-09 08:02:425704 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505705 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:505706}
5707
5708void GLES2DecoderImpl::DoTexParameterfv(
5709 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]c986af502013-08-14 01:04:445710 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5711 &state_, target);
[email protected]02965c22013-03-09 02:40:075712 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515713 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245714 return;
[email protected]3916c97e2010-02-25 03:20:505715 }
[email protected]cbb22e42011-05-12 23:36:245716
[email protected]737191ee72014-03-09 08:02:425717 texture_manager()->SetParameterf(
5718 "glTexParameterfv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505719}
5720
5721void GLES2DecoderImpl::DoTexParameteriv(
5722 GLenum target, GLenum pname, const GLint* params) {
[email protected]c986af502013-08-14 01:04:445723 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5724 &state_, target);
[email protected]02965c22013-03-09 02:40:075725 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515726 LOCAL_SET_GL_ERROR(
5727 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245728 return;
[email protected]3916c97e2010-02-25 03:20:505729 }
[email protected]cbb22e42011-05-12 23:36:245730
[email protected]737191ee72014-03-09 08:02:425731 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505732 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505733}
5734
[email protected]939e7362010-05-13 20:49:105735bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]7cd76fd2013-06-02 21:11:115736 if (!state_.current_program.get()) {
[email protected]ad84a3a2012-06-08 21:42:435737 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:515738 LOCAL_SET_GL_ERROR(
5739 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:435740 return false;
[email protected]939e7362010-05-13 20:49:105741 }
[email protected]e259eb412012-10-13 05:47:245742 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:515743 LOCAL_SET_GL_ERROR(
5744 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:105745 return false;
5746 }
5747 return true;
5748}
5749
5750bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
5751 GLint location, const char* function_name) {
5752 if (!CheckCurrentProgram(function_name)) {
5753 return false;
5754 }
5755 return location != -1;
5756}
5757
zmof9a81360f2014-10-17 00:06:145758bool GLES2DecoderImpl::CheckDrawingFeedbackLoops() {
5759 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
5760 if (!framebuffer)
5761 return false;
5762 const Framebuffer::Attachment* attachment =
5763 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
5764 if (!attachment)
5765 return false;
5766
5767 DCHECK(state_.current_program.get());
5768 const Program::SamplerIndices& sampler_indices =
5769 state_.current_program->sampler_indices();
5770 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
5771 const Program::UniformInfo* uniform_info =
5772 state_.current_program->GetUniformInfo(sampler_indices[ii]);
5773 DCHECK(uniform_info);
5774 if (uniform_info->type != GL_SAMPLER_2D)
5775 continue;
5776 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5777 GLuint texture_unit_index = uniform_info->texture_units[jj];
5778 if (texture_unit_index >= state_.texture_units.size())
5779 continue;
5780 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
5781 TextureRef* texture_ref =
5782 texture_unit.GetInfoForSamplerType(GL_SAMPLER_2D).get();
5783 if (attachment->IsTexture(texture_ref))
5784 return true;
5785 }
5786 }
5787 return false;
5788}
5789
[email protected]43c2f1f2011-03-25 18:35:365790bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]9b1f1b52014-03-12 10:40:135791 GLint fake_location,
5792 const char* function_name,
5793 Program::UniformApiType api_type,
5794 GLint* real_location,
5795 GLenum* type,
5796 GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:365797 DCHECK(type);
5798 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:125799 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:525800
[email protected]1b0a6752012-02-22 03:44:125801 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:105802 return false;
5803 }
[email protected]43c2f1f2011-03-25 18:35:365804 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:355805 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:245806 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:125807 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:365808 if (!info) {
[email protected]ab09b612013-03-11 22:11:515809 LOCAL_SET_GL_ERROR(
5810 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:105811 return false;
5812 }
[email protected]9b1f1b52014-03-12 10:40:135813
5814 if ((api_type & info->accepts_api_type) == 0) {
[email protected]ab09b612013-03-11 22:11:515815 LOCAL_SET_GL_ERROR(
5816 GL_INVALID_OPERATION, function_name,
5817 "wrong uniform function for type");
[email protected]476ccb72012-12-06 15:52:525818 return false;
5819 }
[email protected]43c2f1f2011-03-25 18:35:365820 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:515821 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435822 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:365823 return false;
5824 }
5825 *count = std::min(info->size - array_index, *count);
5826 if (*count <= 0) {
5827 return false;
5828 }
5829 *type = info->type;
[email protected]939e7362010-05-13 20:49:105830 return true;
5831}
5832
[email protected]1b0a6752012-02-22 03:44:125833void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
5834 GLenum type = 0;
5835 GLsizei count = 1;
5836 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135837 if (!PrepForSetUniformByLocation(fake_location,
5838 "glUniform1i",
5839 Program::kUniform1i,
5840 &real_location,
5841 &type,
5842 &count)) {
[email protected]3916c97e2010-02-25 03:20:505843 return;
5844 }
[email protected]e259eb412012-10-13 05:47:245845 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025846 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:515847 LOCAL_SET_GL_ERROR(
5848 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465849 return;
5850 }
[email protected]1b0a6752012-02-22 03:44:125851 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:505852}
5853
5854void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:125855 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:365856 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125857 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135858 if (!PrepForSetUniformByLocation(fake_location,
5859 "glUniform1iv",
5860 Program::kUniform1i,
5861 &real_location,
5862 &type,
5863 &count)) {
[email protected]43c2f1f2011-03-25 18:35:365864 return;
5865 }
[email protected]74727112012-06-13 21:18:085866 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
5867 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:245868 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025869 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:515870 LOCAL_SET_GL_ERROR(
5871 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465872 return;
5873 }
[email protected]43c2f1f2011-03-25 18:35:365874 }
[email protected]1b0a6752012-02-22 03:44:125875 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:505876}
5877
[email protected]939e7362010-05-13 20:49:105878void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:125879 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365880 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125881 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135882 if (!PrepForSetUniformByLocation(fake_location,
5883 "glUniform1fv",
5884 Program::kUniform1f,
5885 &real_location,
5886 &type,
5887 &count)) {
[email protected]939e7362010-05-13 20:49:105888 return;
5889 }
5890 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:555891 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:105892 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:535893 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105894 }
[email protected]1b0a6752012-02-22 03:44:125895 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105896 } else {
[email protected]1b0a6752012-02-22 03:44:125897 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105898 }
5899}
5900
5901void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:125902 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365903 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125904 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135905 if (!PrepForSetUniformByLocation(fake_location,
5906 "glUniform2fv",
5907 Program::kUniform2f,
5908 &real_location,
5909 &type,
5910 &count)) {
[email protected]939e7362010-05-13 20:49:105911 return;
5912 }
5913 if (type == GL_BOOL_VEC2) {
5914 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:555915 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105916 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535917 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105918 }
[email protected]1b0a6752012-02-22 03:44:125919 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105920 } else {
[email protected]1b0a6752012-02-22 03:44:125921 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105922 }
5923}
5924
5925void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:125926 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365927 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125928 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135929 if (!PrepForSetUniformByLocation(fake_location,
5930 "glUniform3fv",
5931 Program::kUniform3f,
5932 &real_location,
5933 &type,
5934 &count)) {
[email protected]939e7362010-05-13 20:49:105935 return;
5936 }
5937 if (type == GL_BOOL_VEC3) {
5938 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:555939 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105940 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535941 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105942 }
[email protected]1b0a6752012-02-22 03:44:125943 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105944 } else {
[email protected]1b0a6752012-02-22 03:44:125945 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105946 }
5947}
5948
5949void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:125950 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365951 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125952 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135953 if (!PrepForSetUniformByLocation(fake_location,
5954 "glUniform4fv",
5955 Program::kUniform4f,
5956 &real_location,
5957 &type,
5958 &count)) {
[email protected]939e7362010-05-13 20:49:105959 return;
5960 }
5961 if (type == GL_BOOL_VEC4) {
5962 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:555963 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105964 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535965 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105966 }
[email protected]1b0a6752012-02-22 03:44:125967 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105968 } else {
[email protected]1b0a6752012-02-22 03:44:125969 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105970 }
5971}
5972
[email protected]43c2f1f2011-03-25 18:35:365973void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:125974 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365975 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125976 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135977 if (!PrepForSetUniformByLocation(fake_location,
5978 "glUniform2iv",
5979 Program::kUniform2i,
5980 &real_location,
5981 &type,
5982 &count)) {
[email protected]43c2f1f2011-03-25 18:35:365983 return;
5984 }
[email protected]1b0a6752012-02-22 03:44:125985 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365986}
5987
5988void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:125989 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365990 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125991 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135992 if (!PrepForSetUniformByLocation(fake_location,
5993 "glUniform3iv",
5994 Program::kUniform3i,
5995 &real_location,
5996 &type,
5997 &count)) {
[email protected]43c2f1f2011-03-25 18:35:365998 return;
5999 }
[email protected]1b0a6752012-02-22 03:44:126000 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366001}
6002
6003void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:126004 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366005 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126006 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136007 if (!PrepForSetUniformByLocation(fake_location,
6008 "glUniform4iv",
6009 Program::kUniform4i,
6010 &real_location,
6011 &type,
6012 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366013 return;
6014 }
[email protected]1b0a6752012-02-22 03:44:126015 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366016}
6017
6018void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:126019 GLint fake_location, GLsizei count, GLboolean transpose,
6020 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366021 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126022 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136023 if (!PrepForSetUniformByLocation(fake_location,
6024 "glUniformMatrix2fv",
6025 Program::kUniformMatrix2f,
6026 &real_location,
6027 &type,
6028 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366029 return;
6030 }
[email protected]1b0a6752012-02-22 03:44:126031 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366032}
6033
6034void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:126035 GLint fake_location, GLsizei count, GLboolean transpose,
6036 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366037 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126038 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136039 if (!PrepForSetUniformByLocation(fake_location,
6040 "glUniformMatrix3fv",
6041 Program::kUniformMatrix3f,
6042 &real_location,
6043 &type,
6044 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366045 return;
6046 }
[email protected]1b0a6752012-02-22 03:44:126047 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366048}
6049
6050void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:126051 GLint fake_location, GLsizei count, GLboolean transpose,
6052 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366053 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126054 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136055 if (!PrepForSetUniformByLocation(fake_location,
6056 "glUniformMatrix4fv",
6057 Program::kUniformMatrix4f,
6058 &real_location,
6059 &type,
6060 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366061 return;
6062 }
[email protected]1b0a6752012-02-22 03:44:126063 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366064}
6065
[email protected]df37b9932013-03-08 05:21:426066void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:036067 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:426068 Program* program = NULL;
6069 if (program_id) {
6070 program = GetProgramInfoNotShader(program_id, "glUseProgram");
6071 if (!program) {
[email protected]ae51d192010-04-27 00:48:036072 return;
6073 }
[email protected]df37b9932013-03-08 05:21:426074 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:506075 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:516076 LOCAL_SET_GL_ERROR(
6077 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:506078 return;
6079 }
[email protected]df37b9932013-03-08 05:21:426080 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:506081 }
[email protected]7cd76fd2013-06-02 21:11:116082 if (state_.current_program.get()) {
6083 program_manager()->UnuseProgram(shader_manager(),
6084 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:146085 }
[email protected]df37b9932013-03-08 05:21:426086 state_.current_program = program;
6087 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:546088 glUseProgram(service_id);
[email protected]7cd76fd2013-06-02 21:11:116089 if (state_.current_program.get()) {
6090 program_manager()->UseProgram(state_.current_program.get());
[email protected]b05955552014-02-06 18:41:186091 if (workarounds().clear_uniforms_before_first_program_use)
6092 program_manager()->ClearUniforms(program);
[email protected]ca488e12010-12-13 20:06:146093 }
[email protected]3916c97e2010-02-25 03:20:506094}
6095
[email protected]ab09b612013-03-11 22:11:516096void GLES2DecoderImpl::RenderWarning(
6097 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:326098 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016099}
6100
[email protected]ab09b612013-03-11 22:11:516101void GLES2DecoderImpl::PerformanceWarning(
6102 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:506103 logger_.LogMessage(filename, line,
6104 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016105}
6106
[email protected]91c94eb2013-10-22 10:32:546107void GLES2DecoderImpl::DoWillUseTexImageIfNeeded(
6108 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546109 // Image is already in use if texture is attached to a framebuffer.
6110 if (texture && !texture->IsAttachedToFramebuffer()) {
6111 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6112 if (image) {
6113 ScopedGLErrorSuppressor suppressor(
6114 "GLES2DecoderImpl::DoWillUseTexImageIfNeeded",
6115 GetErrorState());
6116 glBindTexture(textarget, texture->service_id());
6117 image->WillUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026118 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546119 }
6120 }
6121}
6122
6123void GLES2DecoderImpl::DoDidUseTexImageIfNeeded(
6124 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546125 // Image is still in use if texture is attached to a framebuffer.
6126 if (texture && !texture->IsAttachedToFramebuffer()) {
6127 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6128 if (image) {
6129 ScopedGLErrorSuppressor suppressor(
6130 "GLES2DecoderImpl::DoDidUseTexImageIfNeeded",
6131 GetErrorState());
6132 glBindTexture(textarget, texture->service_id());
6133 image->DidUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026134 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546135 }
6136 }
6137}
6138
[email protected]e56131d22013-07-28 16:14:116139bool GLES2DecoderImpl::PrepareTexturesForRender() {
[email protected]7cd76fd2013-06-02 21:11:116140 DCHECK(state_.current_program.get());
[email protected]91c94eb2013-10-22 10:32:546141 if (!texture_manager()->HaveUnrenderableTextures() &&
[email protected]7bffe9e12014-01-27 23:02:556142 !texture_manager()->HaveImages()) {
[email protected]e56131d22013-07-28 16:14:116143 return true;
[email protected]ef526492010-06-02 23:12:256144 }
[email protected]e2367b42013-05-31 03:37:216145
[email protected]ef526492010-06-02 23:12:256146 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:356147 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:246148 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506149 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356150 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246151 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506152 DCHECK(uniform_info);
6153 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6154 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026155 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246156 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]91c94eb2013-10-22 10:32:546157 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366158 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]91c94eb2013-10-22 10:32:546159 GLenum textarget = GetBindTargetForSamplerType(uniform_info->type);
6160 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]ef526492010-06-02 23:12:256161 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:506162 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6163 glBindTexture(
[email protected]91c94eb2013-10-22 10:32:546164 textarget,
[email protected]00f893d2010-08-24 18:55:496165 texture_manager()->black_texture_id(uniform_info->type));
[email protected]ab09b612013-03-11 22:11:516166 LOCAL_RENDER_WARNING(
[email protected]0f8afe82012-05-14 23:43:016167 std::string("texture bound to texture unit ") +
6168 base::IntToString(texture_unit_index) +
[email protected]ad9b7f8b2013-06-17 07:36:296169 " is not renderable. It maybe non-power-of-2 and have"
6170 " incompatible texture filtering or is not"
6171 " 'texture complete'");
[email protected]91c94eb2013-10-22 10:32:546172 continue;
[email protected]3916c97e2010-02-25 03:20:506173 }
[email protected]91c94eb2013-10-22 10:32:546174
[email protected]4e7b89202014-01-28 01:44:066175 if (textarget != GL_TEXTURE_CUBE_MAP) {
6176 Texture* texture = texture_ref->texture();
6177 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6178 if (image && !texture->IsAttachedToFramebuffer()) {
6179 ScopedGLErrorSuppressor suppressor(
6180 "GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState());
6181 textures_set = true;
6182 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6183 image->WillUseTexImage();
6184 continue;
6185 }
[email protected]91c94eb2013-10-22 10:32:546186 }
[email protected]3916c97e2010-02-25 03:20:506187 }
6188 // else: should this be an error?
6189 }
6190 }
[email protected]e56131d22013-07-28 16:14:116191 return !textures_set;
[email protected]3916c97e2010-02-25 03:20:506192}
6193
[email protected]91c94eb2013-10-22 10:32:546194void GLES2DecoderImpl::RestoreStateForTextures() {
[email protected]7cd76fd2013-06-02 21:11:116195 DCHECK(state_.current_program.get());
[email protected]ed9f9cd2013-02-27 21:12:356196 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116197 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506198 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356199 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246200 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506201 DCHECK(uniform_info);
6202 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6203 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026204 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246205 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]7cd76fd2013-06-02 21:11:116206 TextureRef* texture_ref =
[email protected]91c94eb2013-10-22 10:32:546207 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496208 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]3916c97e2010-02-25 03:20:506209 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]370eaf12013-05-18 09:19:496210 // Get the texture_ref info that was previously bound here.
[email protected]7cd76fd2013-06-02 21:11:116211 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D
6212 ? texture_unit.bound_texture_2d.get()
6213 : texture_unit.bound_texture_cube_map.get();
[email protected]3916c97e2010-02-25 03:20:506214 glBindTexture(texture_unit.bind_target,
[email protected]370eaf12013-05-18 09:19:496215 texture_ref ? texture_ref->service_id() : 0);
[email protected]91c94eb2013-10-22 10:32:546216 continue;
6217 }
6218
[email protected]4e7b89202014-01-28 01:44:066219 if (texture_unit.bind_target != GL_TEXTURE_CUBE_MAP) {
6220 Texture* texture = texture_ref->texture();
6221 gfx::GLImage* image =
6222 texture->GetLevelImage(texture_unit.bind_target, 0);
6223 if (image && !texture->IsAttachedToFramebuffer()) {
6224 ScopedGLErrorSuppressor suppressor(
6225 "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState());
6226 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6227 image->DidUseTexImage();
6228 continue;
6229 }
[email protected]3916c97e2010-02-25 03:20:506230 }
6231 }
6232 }
6233 }
6234 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:246235 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:306236}
6237
[email protected]0d6bfdc2011-11-02 01:32:206238bool GLES2DecoderImpl::ClearUnclearedTextures() {
6239 // Only check if there are some uncleared textures.
6240 if (!texture_manager()->HaveUnsafeTextures()) {
6241 return true;
6242 }
6243
6244 // 1: Check all textures we are about to render with.
[email protected]7cd76fd2013-06-02 21:11:116245 if (state_.current_program.get()) {
[email protected]ed9f9cd2013-02-27 21:12:356246 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116247 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:206248 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356249 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246250 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:206251 DCHECK(uniform_info);
6252 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6253 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026254 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246255 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:496256 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366257 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496258 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
6259 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
[email protected]0d6bfdc2011-11-02 01:32:206260 return false;
6261 }
6262 }
6263 }
6264 }
6265 }
6266 }
6267 return true;
6268}
6269
[email protected]c6aef902012-02-14 03:31:426270bool GLES2DecoderImpl::IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:106271 const char* function_name, GLuint max_vertex_accessed, bool instanced,
6272 GLsizei primcount) {
6273 DCHECK(instanced || primcount == 1);
6274
[email protected]689fa1c52010-06-09 18:35:036275 // NOTE: We specifically do not check current_program->IsValid() because
6276 // it could never be invalid since glUseProgram would have failed. While
6277 // glLinkProgram could later mark the program as invalid the previous
6278 // valid program will still function if it is still the current program.
[email protected]7cd76fd2013-06-02 21:11:116279 if (!state_.current_program.get()) {
[email protected]3916c97e2010-02-25 03:20:506280 // The program does not exist.
6281 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:516282 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:506283 return false;
6284 }
[email protected]c6aef902012-02-14 03:31:426285
zmof9a81360f2014-10-17 00:06:146286 if (CheckDrawingFeedbackLoops()) {
6287 LOCAL_SET_GL_ERROR(
6288 GL_INVALID_OPERATION, function_name,
6289 "Source and destination textures of the draw are the same.");
6290 return false;
6291 }
6292
[email protected]7cd76fd2013-06-02 21:11:116293 return state_.vertex_attrib_manager
6294 ->ValidateBindings(function_name,
6295 this,
6296 feature_info_.get(),
6297 state_.current_program.get(),
6298 max_vertex_accessed,
[email protected]ac6904d62014-07-30 12:00:106299 instanced,
[email protected]7cd76fd2013-06-02 21:11:116300 primcount);
[email protected]b1122982010-05-17 23:04:246301}
6302
[email protected]c13e1da62011-09-09 21:48:306303bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:436304 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:306305 DCHECK(simulated);
6306 *simulated = false;
6307
[email protected]876f6fee2010-08-02 23:10:326308 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:306309 return true;
[email protected]876f6fee2010-08-02 23:10:326310
[email protected]ac77603c72013-03-08 13:52:066311 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:356312 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:246313 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:246314 bool attrib_0_used =
6315 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:066316 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:306317 return true;
[email protected]b1122982010-05-17 23:04:246318 }
6319
[email protected]b1122982010-05-17 23:04:246320 // Make a buffer with a single repeated vec4 value enough to
6321 // simulate the constant value that is supposed to be here.
6322 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:306323 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:476324 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:306325
6326 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:476327 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306328 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516329 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306330 return false;
6331 }
6332
[email protected]ab09b612013-03-11 22:11:516333 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016334 "Attribute 0 is disabled. This has signficant performance penalty");
6335
[email protected]ab09b612013-03-11 22:11:516336 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:306337 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
6338
[email protected]8f0b86c2f2012-04-10 05:48:286339 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
6340 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:496341 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306342 GLenum error = glGetError();
6343 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516344 LOCAL_SET_GL_ERROR(
6345 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306346 return false;
6347 }
[email protected]fc753442011-02-04 19:49:496348 }
[email protected]af6380962012-11-29 23:24:136349
6350 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:286351 if (new_buffer ||
6352 (attrib_0_used &&
6353 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:136354 (value.v[0] != attrib_0_value_.v[0] ||
6355 value.v[1] != attrib_0_value_.v[1] ||
6356 value.v[2] != attrib_0_value_.v[2] ||
6357 value.v[3] != attrib_0_value_.v[3])))) {
6358 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:496359 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
6360 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:136361 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:246362 attrib_0_size_ = size_needed;
6363 }
6364
6365 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
6366
[email protected]ac77603c72013-03-08 13:52:066367 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:426368 glVertexAttribDivisorANGLE(0, 0);
6369
[email protected]c13e1da62011-09-09 21:48:306370 *simulated = true;
[email protected]b1122982010-05-17 23:04:246371 return true;
[email protected]b1122982010-05-17 23:04:246372}
6373
[email protected]3fc38e22014-05-30 00:13:236374void GLES2DecoderImpl::RestoreStateForAttrib(
6375 GLuint attrib_index, bool restore_array_binding) {
[email protected]ac77603c72013-03-08 13:52:066376 const VertexAttrib* attrib =
6377 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
[email protected]3fc38e22014-05-30 00:13:236378 if (restore_array_binding) {
6379 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
6380 Buffer* buffer = attrib->buffer();
6381 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
6382 glVertexAttribPointer(
6383 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
6384 attrib->gl_stride(), ptr);
6385 }
[email protected]ac77603c72013-03-08 13:52:066386 if (attrib->divisor())
6387 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:246388 glBindBuffer(
[email protected]3fc38e22014-05-30 00:13:236389 GL_ARRAY_BUFFER, state_.bound_array_buffer.get() ?
6390 state_.bound_array_buffer->service_id() : 0);
[email protected]43410e92012-04-20 17:06:286391
[email protected]265f8992012-07-20 01:03:146392 // Never touch vertex attribute 0's state (in particular, never
6393 // disable it) when running on desktop GL because it will never be
6394 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:066395 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:146396 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:066397 if (attrib->enabled()) {
6398 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146399 } else {
[email protected]ac77603c72013-03-08 13:52:066400 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146401 }
[email protected]43410e92012-04-20 17:06:286402 }
[email protected]b1122982010-05-17 23:04:246403}
[email protected]07f54fcc2009-12-22 02:46:306404
[email protected]8fbedc02010-11-18 18:43:406405bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:436406 const char* function_name,
[email protected]c6aef902012-02-14 03:31:426407 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:406408 DCHECK(simulated);
6409 *simulated = false;
6410 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
6411 return true;
6412
[email protected]e259eb412012-10-13 05:47:246413 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:406414 return true;
6415 }
6416
[email protected]ab09b612013-03-11 22:11:516417 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016418 "GL_FIXED attributes have a signficant performance penalty");
6419
[email protected]8fbedc02010-11-18 18:43:406420 // NOTE: we could be smart and try to check if a buffer is used
6421 // twice in 2 different attribs, find the overlapping parts and therefore
6422 // duplicate the minimum amount of data but this whole code path is not meant
6423 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
6424 // tests so we just add to the buffer attrib used.
6425
[email protected]c13e1da62011-09-09 21:48:306426 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:066427 const VertexAttribManager::VertexAttribList& enabled_attribs =
6428 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
6429 for (VertexAttribManager::VertexAttribList::const_iterator it =
6430 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6431 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356432 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066433 state_.current_program->GetAttribInfoByLocation(attrib->index());
6434 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
6435 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:426436 GLuint num_vertices = max_accessed + 1;
6437 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516438 LOCAL_SET_GL_ERROR(
6439 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426440 return false;
6441 }
[email protected]8fbedc02010-11-18 18:43:406442 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066443 attrib->CanAccess(max_accessed) &&
6444 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:476445 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:066446 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:476447 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:516448 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436449 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406450 return false;
6451 }
6452 }
6453 }
6454
[email protected]3aad1a32012-09-07 20:54:476455 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
6456 uint32 size_needed = 0;
6457 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306458 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516459 LOCAL_SET_GL_ERROR(
6460 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406461 return false;
6462 }
6463
[email protected]ab09b612013-03-11 22:11:516464 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:406465
6466 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:306467 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:406468 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306469 GLenum error = glGetError();
6470 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516471 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436472 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:306473 return false;
6474 }
[email protected]8fbedc02010-11-18 18:43:406475 }
6476
6477 // Copy the elements and convert to float
6478 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:066479 for (VertexAttribManager::VertexAttribList::const_iterator it =
6480 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6481 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356482 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066483 state_.current_program->GetAttribInfoByLocation(attrib->index());
6484 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:426485 max_vertex_accessed);
6486 GLuint num_vertices = max_accessed + 1;
6487 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516488 LOCAL_SET_GL_ERROR(
6489 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426490 return false;
6491 }
[email protected]8fbedc02010-11-18 18:43:406492 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066493 attrib->CanAccess(max_accessed) &&
6494 attrib->type() == GL_FIXED) {
6495 int num_elements = attrib->size() * kSizeOfFloat;
[email protected]8fbedc02010-11-18 18:43:406496 int size = num_elements * num_vertices;
[email protected]40d90a22013-04-09 03:39:556497 scoped_ptr<float[]> data(new float[size]);
[email protected]8fbedc02010-11-18 18:43:406498 const int32* src = reinterpret_cast<const int32 *>(
[email protected]ac77603c72013-03-08 13:52:066499 attrib->buffer()->GetRange(attrib->offset(), size));
[email protected]8fbedc02010-11-18 18:43:406500 const int32* end = src + num_elements;
6501 float* dst = data.get();
6502 while (src != end) {
6503 *dst++ = static_cast<float>(*src++) / 65536.0f;
6504 }
6505 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get());
6506 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066507 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:406508 reinterpret_cast<GLvoid*>(offset));
6509 offset += size;
6510 }
6511 }
6512 *simulated = true;
6513 return true;
6514}
6515
6516void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
6517 // There's no need to call glVertexAttribPointer because we shadow all the
6518 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:246519 glBindBuffer(
6520 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:116521 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
6522 : 0);
[email protected]8fbedc02010-11-18 18:43:406523}
6524
[email protected]ad84a3a2012-06-08 21:42:436525error::Error GLES2DecoderImpl::DoDrawArrays(
6526 const char* function_name,
6527 bool instanced,
6528 GLenum mode,
6529 GLint first,
6530 GLsizei count,
6531 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226532 error::Error error = WillAccessBoundFramebufferForDraw();
6533 if (error != error::kNoError)
6534 return error;
[email protected]38d139d2011-07-14 00:38:436535 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516536 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:436537 return error::kNoError;
6538 }
6539 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516540 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:436541 return error::kNoError;
6542 }
[email protected]c6aef902012-02-14 03:31:426543 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516544 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426545 return error::kNoError;
6546 }
[email protected]ad84a3a2012-06-08 21:42:436547 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:436548 return error::kNoError;
6549 }
6550 // We have to check this here because the prototype for glDrawArrays
6551 // is GLint not GLsizei.
6552 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:516553 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:436554 return error::kNoError;
6555 }
6556
[email protected]ac6904d62014-07-30 12:00:106557 if (count == 0 || primcount == 0) {
[email protected]ab09b612013-03-11 22:11:516558 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:436559 return error::kNoError;
6560 }
6561
6562 GLuint max_vertex_accessed = first + count - 1;
[email protected]ac6904d62014-07-30 12:00:106563 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206564 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516565 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206566 return error::kNoError;
6567 }
[email protected]c13e1da62011-09-09 21:48:306568 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436569 if (!SimulateAttrib0(
6570 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306571 return error::kNoError;
6572 }
[email protected]38d139d2011-07-14 00:38:436573 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436574 if (SimulateFixedAttribs(
6575 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6576 primcount)) {
[email protected]e56131d22013-07-28 16:14:116577 bool textures_set = !PrepareTexturesForRender();
[email protected]38d139d2011-07-14 00:38:436578 ApplyDirtyState();
[email protected]00c2cf92014-03-14 00:08:376579 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:426580 if (!instanced) {
6581 glDrawArrays(mode, first, count);
6582 } else {
6583 glDrawArraysInstancedANGLE(mode, first, count, primcount);
6584 }
[email protected]38d139d2011-07-14 00:38:436585 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546586 RestoreStateForTextures();
[email protected]38d139d2011-07-14 00:38:436587 }
6588 if (simulated_fixed_attribs) {
6589 RestoreStateForSimulatedFixedAttribs();
6590 }
6591 }
6592 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:236593 // We don't have to restore attrib 0 generic data at the end of this
6594 // function even if it is simulated. This is because we will simulate
6595 // it in each draw call, and attrib 0 generic data queries use cached
6596 // values instead of passing down to the underlying driver.
6597 RestoreStateForAttrib(0, false);
[email protected]38d139d2011-07-14 00:38:436598 }
[email protected]38d139d2011-07-14 00:38:436599 }
6600 return error::kNoError;
6601}
6602
vmiuracd108592014-09-08 14:36:346603error::Error GLES2DecoderImpl::HandleDrawArrays(uint32 immediate_data_size,
6604 const void* cmd_data) {
6605 const cmds::DrawArrays& c = *static_cast<const cmds::DrawArrays*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:436606 return DoDrawArrays("glDrawArrays",
6607 false,
[email protected]c6aef902012-02-14 03:31:426608 static_cast<GLenum>(c.mode),
6609 static_cast<GLint>(c.first),
6610 static_cast<GLsizei>(c.count),
[email protected]ac6904d62014-07-30 12:00:106611 1);
[email protected]c6aef902012-02-14 03:31:426612}
6613
6614error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
vmiuracd108592014-09-08 14:36:346615 uint32 immediate_data_size,
6616 const void* cmd_data) {
6617 const gles2::cmds::DrawArraysInstancedANGLE& c =
6618 *static_cast<const gles2::cmds::DrawArraysInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:156619 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516620 LOCAL_SET_GL_ERROR(
6621 GL_INVALID_OPERATION,
6622 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426623 return error::kNoError;
6624 }
[email protected]ad84a3a2012-06-08 21:42:436625 return DoDrawArrays("glDrawArraysIntancedANGLE",
6626 true,
[email protected]c6aef902012-02-14 03:31:426627 static_cast<GLenum>(c.mode),
6628 static_cast<GLint>(c.first),
6629 static_cast<GLsizei>(c.count),
6630 static_cast<GLsizei>(c.primcount));
6631}
6632
[email protected]ad84a3a2012-06-08 21:42:436633error::Error GLES2DecoderImpl::DoDrawElements(
6634 const char* function_name,
6635 bool instanced,
6636 GLenum mode,
6637 GLsizei count,
6638 GLenum type,
6639 int32 offset,
6640 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226641 error::Error error = WillAccessBoundFramebufferForDraw();
6642 if (error != error::kNoError)
6643 return error;
[email protected]e259eb412012-10-13 05:47:246644 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:516645 LOCAL_SET_GL_ERROR(
6646 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296647 return error::kNoError;
6648 }
6649
[email protected]8eee29c2010-04-29 03:38:296650 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516651 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296652 return error::kNoError;
6653 }
6654 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516655 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296656 return error::kNoError;
6657 }
[email protected]9438b012010-06-15 22:55:056658 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516659 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296660 return error::kNoError;
6661 }
[email protected]9438b012010-06-15 22:55:056662 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516663 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296664 return error::kNoError;
6665 }
[email protected]c6aef902012-02-14 03:31:426666 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516667 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426668 return error::kNoError;
6669 }
[email protected]8eee29c2010-04-29 03:38:296670
[email protected]ad84a3a2012-06-08 21:42:436671 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276672 return error::kNoError;
6673 }
6674
[email protected]ac6904d62014-07-30 12:00:106675 if (count == 0 || primcount == 0) {
[email protected]6c788fb72010-08-26 02:16:316676 return error::kNoError;
6677 }
6678
[email protected]8eee29c2010-04-29 03:38:296679 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:086680 Buffer* element_array_buffer =
6681 state_.vertex_attrib_manager->element_array_buffer();
6682
6683 if (!element_array_buffer->GetMaxValueForRange(
6684 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:516685 LOCAL_SET_GL_ERROR(
6686 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296687 return error::kNoError;
6688 }
6689
[email protected]ac6904d62014-07-30 12:00:106690 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206691 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516692 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206693 return error::kNoError;
6694 }
[email protected]c13e1da62011-09-09 21:48:306695 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436696 if (!SimulateAttrib0(
6697 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306698 return error::kNoError;
6699 }
[email protected]8fbedc02010-11-18 18:43:406700 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436701 if (SimulateFixedAttribs(
6702 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6703 primcount)) {
[email protected]e56131d22013-07-28 16:14:116704 bool textures_set = !PrepareTexturesForRender();
[email protected]297ca1c2011-06-20 23:08:466705 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:086706 // TODO(gman): Refactor to hide these details in BufferManager or
6707 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:406708 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:086709 bool used_client_side_array = false;
6710 if (element_array_buffer->IsClientSideArray()) {
6711 used_client_side_array = true;
6712 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6713 indices = element_array_buffer->GetRange(offset, 0);
6714 }
6715
[email protected]00c2cf92014-03-14 00:08:376716 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:426717 if (!instanced) {
6718 glDrawElements(mode, count, type, indices);
6719 } else {
6720 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6721 }
[email protected]17cfbe0e2013-03-07 01:26:086722
6723 if (used_client_side_array) {
6724 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
6725 element_array_buffer->service_id());
6726 }
6727
[email protected]8fbedc02010-11-18 18:43:406728 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546729 RestoreStateForTextures();
[email protected]8fbedc02010-11-18 18:43:406730 }
6731 if (simulated_fixed_attribs) {
6732 RestoreStateForSimulatedFixedAttribs();
6733 }
[email protected]ba3176a2009-12-16 18:19:466734 }
[email protected]b1122982010-05-17 23:04:246735 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:236736 // We don't have to restore attrib 0 generic data at the end of this
6737 // function even if it is simulated. This is because we will simulate
6738 // it in each draw call, and attrib 0 generic data queries use cached
6739 // values instead of passing down to the underlying driver.
6740 RestoreStateForAttrib(0, false);
[email protected]b1122982010-05-17 23:04:246741 }
[email protected]96449d2c2009-11-25 00:01:326742 }
[email protected]f7a64ee2010-02-01 22:24:146743 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326744}
6745
vmiuracd108592014-09-08 14:36:346746error::Error GLES2DecoderImpl::HandleDrawElements(uint32 immediate_data_size,
6747 const void* cmd_data) {
6748 const gles2::cmds::DrawElements& c =
6749 *static_cast<const gles2::cmds::DrawElements*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:436750 return DoDrawElements("glDrawElements",
6751 false,
[email protected]c6aef902012-02-14 03:31:426752 static_cast<GLenum>(c.mode),
6753 static_cast<GLsizei>(c.count),
6754 static_cast<GLenum>(c.type),
6755 static_cast<int32>(c.index_offset),
[email protected]ac6904d62014-07-30 12:00:106756 1);
[email protected]c6aef902012-02-14 03:31:426757}
6758
6759error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
vmiuracd108592014-09-08 14:36:346760 uint32 immediate_data_size,
6761 const void* cmd_data) {
6762 const gles2::cmds::DrawElementsInstancedANGLE& c =
6763 *static_cast<const gles2::cmds::DrawElementsInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:156764 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516765 LOCAL_SET_GL_ERROR(
6766 GL_INVALID_OPERATION,
6767 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426768 return error::kNoError;
6769 }
[email protected]ad84a3a2012-06-08 21:42:436770 return DoDrawElements("glDrawElementsInstancedANGLE",
6771 true,
[email protected]c6aef902012-02-14 03:31:426772 static_cast<GLenum>(c.mode),
6773 static_cast<GLsizei>(c.count),
6774 static_cast<GLenum>(c.type),
6775 static_cast<int32>(c.index_offset),
6776 static_cast<GLsizei>(c.primcount));
6777}
6778
[email protected]269200b12010-11-18 22:53:066779GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:236780 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
6781 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:076782 Buffer* buffer = GetBuffer(buffer_id);
6783 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:036784 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516785 LOCAL_SET_GL_ERROR(
6786 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:236787 } else {
[email protected]b10492f2013-03-08 05:24:076788 if (!buffer->GetMaxValueForRange(
6789 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:036790 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516791 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:066792 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436793 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:236794 }
6795 }
6796 return max_vertex_accessed;
6797}
6798
[email protected]96449d2c2009-11-25 00:01:326799// Calls glShaderSource for the various versions of the ShaderSource command.
6800// Assumes that data / data_size points to a piece of memory that is in range
6801// of whatever context it came from (shared memory, immediate memory, bucket
6802// memory.)
[email protected]45bf5152010-02-12 00:11:316803error::Error GLES2DecoderImpl::ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036804 GLuint client_id, const char* data, uint32 data_size) {
[email protected]258a3313f2011-10-18 20:13:576805 std::string str(data, data + data_size);
[email protected]df37b9932013-03-08 05:21:426806 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
6807 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316808 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326809 }
[email protected]45bf5152010-02-12 00:11:316810 // Note: We don't actually call glShaderSource here. We wait until
6811 // the call to glCompileShader.
zmo576a0492014-09-13 01:12:326812 shader->set_source(str);
[email protected]f7a64ee2010-02-01 22:24:146813 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326814}
6815
[email protected]558847a2010-03-24 07:02:546816error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
vmiuracd108592014-09-08 14:36:346817 uint32 immediate_data_size,
6818 const void* cmd_data) {
6819 const gles2::cmds::ShaderSourceBucket& c =
6820 *static_cast<const gles2::cmds::ShaderSourceBucket*>(cmd_data);
[email protected]558847a2010-03-24 07:02:546821 Bucket* bucket = GetBucket(c.data_bucket_id);
6822 if (!bucket || bucket->size() == 0) {
6823 return error::kInvalidArguments;
6824 }
6825 return ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036826 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
[email protected]558847a2010-03-24 07:02:546827 bucket->size() - 1);
6828}
6829
[email protected]ae51d192010-04-27 00:48:036830void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:386831 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:426832 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
6833 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316834 return;
6835 }
[email protected]f57bb282010-11-12 00:51:346836 ShaderTranslator* translator = NULL;
[email protected]b1d2dcb2010-05-17 19:24:186837 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:426838 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]a550584e2010-09-17 18:01:456839 vertex_translator_.get() : fragment_translator_.get();
[email protected]de17df392010-04-23 21:09:416840 }
[email protected]de17df392010-04-23 21:09:416841
zmo576a0492014-09-13 01:12:326842 shader->DoCompile(
[email protected]b05955552014-02-06 18:41:186843 translator,
6844 feature_info_->feature_flags().angle_translated_shader_source ?
zmo576a0492014-09-13 01:12:326845 Shader::kANGLE : Shader::kGL);
vmiura8266ca72014-09-09 21:37:006846
6847 // CompileShader can be very slow. Exit command processing to allow for
6848 // context preemption and GPU watchdog checks.
6849 ExitCommandProcessingEarly();
6850}
[email protected]45bf5152010-02-12 00:11:316851
[email protected]ddd968b82010-03-02 00:44:296852void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:426853 GLuint shader_id, GLenum pname, GLint* params) {
6854 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
6855 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:296856 return;
6857 }
[email protected]8f1ccdac2010-05-19 21:01:486858 switch (pname) {
6859 case GL_SHADER_SOURCE_LENGTH:
zmo576a0492014-09-13 01:12:326860 *params = shader->source().size();
6861 if (*params)
6862 ++(*params);
[email protected]8f1ccdac2010-05-19 21:01:486863 return;
6864 case GL_COMPILE_STATUS:
zmo576a0492014-09-13 01:12:326865 *params = compile_shader_always_succeeds_ ? true : shader->valid();
[email protected]e5186162010-06-14 18:54:416866 return;
[email protected]8f1ccdac2010-05-19 21:01:486867 case GL_INFO_LOG_LENGTH:
zmo576a0492014-09-13 01:12:326868 *params = shader->log_info().size();
6869 if (*params)
6870 ++(*params);
[email protected]e5186162010-06-14 18:54:416871 return;
[email protected]d6a53e42011-10-05 00:09:366872 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
zmo576a0492014-09-13 01:12:326873 *params = shader->translated_source().size();
6874 if (*params)
6875 ++(*params);
[email protected]d6a53e42011-10-05 00:09:366876 return;
[email protected]8f1ccdac2010-05-19 21:01:486877 default:
6878 break;
[email protected]ddd968b82010-03-02 00:44:296879 }
[email protected]df37b9932013-03-08 05:21:426880 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:296881}
6882
vmiuracd108592014-09-08 14:36:346883error::Error GLES2DecoderImpl::HandleGetShaderSource(uint32 immediate_data_size,
6884 const void* cmd_data) {
6885 const gles2::cmds::GetShaderSource& c =
6886 *static_cast<const gles2::cmds::GetShaderSource*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:426887 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:036888 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6889 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426890 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
zmo576a0492014-09-13 01:12:326891 if (!shader || shader->source().empty()) {
[email protected]8eee29c2010-04-29 03:38:296892 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:296893 return error::kNoError;
6894 }
zmo576a0492014-09-13 01:12:326895 bucket->SetFromString(shader->source().c_str());
[email protected]ae51d192010-04-27 00:48:036896 return error::kNoError;
6897}
6898
[email protected]d6a53e42011-10-05 00:09:366899error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
6900 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:346901 const void* cmd_data) {
6902 const gles2::cmds::GetTranslatedShaderSourceANGLE& c =
6903 *static_cast<const gles2::cmds::GetTranslatedShaderSourceANGLE*>(
6904 cmd_data);
[email protected]df37b9932013-03-08 05:21:426905 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:366906 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6907 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426908 Shader* shader = GetShaderInfoNotProgram(
[email protected]caa13ed2014-02-17 11:29:206909 shader_id, "glGetTranslatedShaderSourceANGLE");
[email protected]df37b9932013-03-08 05:21:426910 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:366911 bucket->SetSize(0);
6912 return error::kNoError;
6913 }
6914
zmo576a0492014-09-13 01:12:326915 bucket->SetFromString(shader->translated_source().c_str());
[email protected]d6a53e42011-10-05 00:09:366916 return error::kNoError;
6917}
6918
[email protected]ae51d192010-04-27 00:48:036919error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
vmiuracd108592014-09-08 14:36:346920 uint32 immediate_data_size,
6921 const void* cmd_data) {
6922 const gles2::cmds::GetProgramInfoLog& c =
6923 *static_cast<const gles2::cmds::GetProgramInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:426924 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:586925 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6926 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426927 Program* program = GetProgramInfoNotShader(
6928 program_id, "glGetProgramInfoLog");
6929 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466930 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036931 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:316932 }
[email protected]df37b9932013-03-08 05:21:426933 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036934 return error::kNoError;
6935}
6936
6937error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
vmiuracd108592014-09-08 14:36:346938 uint32 immediate_data_size,
6939 const void* cmd_data) {
6940 const gles2::cmds::GetShaderInfoLog& c =
6941 *static_cast<const gles2::cmds::GetShaderInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:426942 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:586943 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6944 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426945 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
zmo576a0492014-09-13 01:12:326946 if (!shader) {
[email protected]9a14ae612011-08-08 17:51:466947 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036948 return error::kNoError;
6949 }
zmo576a0492014-09-13 01:12:326950 bucket->SetFromString(shader->log_info().c_str());
[email protected]ae51d192010-04-27 00:48:036951 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326952}
6953
[email protected]d058bca2012-11-26 10:27:266954bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
6955 return state_.GetEnabled(cap);
6956}
6957
[email protected]1958e0e2010-04-22 05:17:156958bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:216959 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106960 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156961}
6962
6963bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356964 const Framebuffer* framebuffer =
6965 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106966 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156967}
6968
6969bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366970 // IsProgram is true for programs as soon as they are created, until they are
6971 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:356972 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:106973 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156974}
6975
6976bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356977 const Renderbuffer* renderbuffer =
6978 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106979 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156980}
6981
6982bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366983 // IsShader is true for shaders as soon as they are created, until they
6984 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:356985 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:106986 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156987}
6988
6989bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:496990 const TextureRef* texture_ref = GetTexture(client_id);
6991 return texture_ref && texture_ref->texture()->IsValid();
[email protected]ae51d192010-04-27 00:48:036992}
6993
6994void GLES2DecoderImpl::DoAttachShader(
6995 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426996 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586997 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:426998 if (!program) {
[email protected]ae51d192010-04-27 00:48:036999 return;
[email protected]1958e0e2010-04-22 05:17:157000 }
[email protected]df37b9932013-03-08 05:21:427001 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
7002 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037003 return;
7004 }
[email protected]df37b9932013-03-08 05:21:427005 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517006 LOCAL_SET_GL_ERROR(
7007 GL_INVALID_OPERATION,
7008 "glAttachShader",
7009 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:317010 return;
7011 }
[email protected]df37b9932013-03-08 05:21:427012 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037013}
7014
7015void GLES2DecoderImpl::DoDetachShader(
7016 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:427017 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587018 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:427019 if (!program) {
[email protected]ae51d192010-04-27 00:48:037020 return;
7021 }
[email protected]df37b9932013-03-08 05:21:427022 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
7023 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037024 return;
7025 }
[email protected]df37b9932013-03-08 05:21:427026 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517027 LOCAL_SET_GL_ERROR(
7028 GL_INVALID_OPERATION,
7029 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:227030 return;
7031 }
[email protected]df37b9932013-03-08 05:21:427032 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037033}
7034
7035void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:427036 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587037 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:427038 if (!program) {
[email protected]ae51d192010-04-27 00:48:037039 return;
7040 }
[email protected]df37b9932013-03-08 05:21:427041 program->Validate();
[email protected]1958e0e2010-04-22 05:17:157042}
7043
[email protected]ac77603c72013-03-08 13:52:067044void GLES2DecoderImpl::GetVertexAttribHelper(
7045 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:247046 switch (pname) {
7047 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:067048 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:247049 if (buffer && !buffer->IsDeleted()) {
7050 GLuint client_id;
7051 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
7052 *params = client_id;
7053 }
7054 break;
7055 }
7056 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:067057 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:247058 break;
7059 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:067060 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:247061 break;
7062 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:067063 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:247064 break;
7065 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:067066 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:247067 break;
7068 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:067069 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:247070 break;
[email protected]c6aef902012-02-14 03:31:427071 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:067072 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:427073 break;
[email protected]ac77603c72013-03-08 13:52:067074 default:
7075 NOTREACHED();
7076 break;
7077 }
7078}
7079
[email protected]4c6f5462014-03-05 00:26:567080void GLES2DecoderImpl::DoGetTexParameterfv(
7081 GLenum target, GLenum pname, GLfloat* params) {
7082 InitTextureMaxAnisotropyIfNeeded(target, pname);
7083 glGetTexParameterfv(target, pname, params);
7084}
7085
7086void GLES2DecoderImpl::DoGetTexParameteriv(
7087 GLenum target, GLenum pname, GLint* params) {
7088 InitTextureMaxAnisotropyIfNeeded(target, pname);
7089 glGetTexParameteriv(target, pname, params);
7090}
7091
7092void GLES2DecoderImpl::InitTextureMaxAnisotropyIfNeeded(
7093 GLenum target, GLenum pname) {
7094 if (!workarounds().init_texture_max_anisotropy)
7095 return;
7096 if (pname != GL_TEXTURE_MAX_ANISOTROPY_EXT ||
7097 !validators_->texture_parameter.IsValid(pname)) {
7098 return;
7099 }
7100
7101 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
7102 &state_, target);
7103 if (!texture_ref) {
7104 LOCAL_SET_GL_ERROR(
7105 GL_INVALID_OPERATION,
7106 "glGetTexParamter{fi}v", "unknown texture for target");
7107 return;
7108 }
7109 Texture* texture = texture_ref->texture();
7110 texture->InitTextureMaxAnisotropyIfNeeded(target);
7111}
7112
[email protected]ac77603c72013-03-08 13:52:067113void GLES2DecoderImpl::DoGetVertexAttribfv(
7114 GLuint index, GLenum pname, GLfloat* params) {
7115 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7116 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517117 LOCAL_SET_GL_ERROR(
7118 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067119 return;
7120 }
7121 switch (pname) {
7122 case GL_CURRENT_VERTEX_ATTRIB: {
7123 const Vec4& value = state_.attrib_values[index];
7124 params[0] = value.v[0];
7125 params[1] = value.v[1];
7126 params[2] = value.v[2];
7127 params[3] = value.v[3];
7128 break;
7129 }
7130 default: {
7131 GLint value = 0;
7132 GetVertexAttribHelper(attrib, pname, &value);
7133 *params = static_cast<GLfloat>(value);
7134 break;
7135 }
7136 }
7137}
7138
7139void GLES2DecoderImpl::DoGetVertexAttribiv(
7140 GLuint index, GLenum pname, GLint* params) {
7141 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7142 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517143 LOCAL_SET_GL_ERROR(
7144 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067145 return;
7146 }
7147 switch (pname) {
[email protected]af6380962012-11-29 23:24:137148 case GL_CURRENT_VERTEX_ATTRIB: {
7149 const Vec4& value = state_.attrib_values[index];
7150 params[0] = static_cast<GLint>(value.v[0]);
7151 params[1] = static_cast<GLint>(value.v[1]);
7152 params[2] = static_cast<GLint>(value.v[2]);
7153 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:247154 break;
[email protected]af6380962012-11-29 23:24:137155 }
[email protected]b1122982010-05-17 23:04:247156 default:
[email protected]ac77603c72013-03-08 13:52:067157 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:247158 break;
7159 }
7160}
7161
[email protected]af6380962012-11-29 23:24:137162bool GLES2DecoderImpl::SetVertexAttribValue(
7163 const char* function_name, GLuint index, const GLfloat* value) {
7164 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:517165 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:137166 return false;
[email protected]b1122982010-05-17 23:04:247167 }
[email protected]af6380962012-11-29 23:24:137168 Vec4& v = state_.attrib_values[index];
7169 v.v[0] = value[0];
7170 v.v[1] = value[1];
7171 v.v[2] = value[2];
7172 v.v[3] = value[3];
7173 return true;
7174}
7175
7176void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
7177 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
7178 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
7179 glVertexAttrib1f(index, v0);
7180 }
[email protected]b1122982010-05-17 23:04:247181}
7182
7183void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:137184 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
7185 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
7186 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:247187 }
[email protected]b1122982010-05-17 23:04:247188}
7189
7190void GLES2DecoderImpl::DoVertexAttrib3f(
7191 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:137192 GLfloat v[4] = { v0, v1, v2, 1.0f, };
7193 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
7194 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:247195 }
[email protected]b1122982010-05-17 23:04:247196}
7197
7198void GLES2DecoderImpl::DoVertexAttrib4f(
7199 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:137200 GLfloat v[4] = { v0, v1, v2, v3, };
7201 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
7202 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:247203 }
[email protected]b1122982010-05-17 23:04:247204}
7205
7206void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137207 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
7208 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
7209 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:247210 }
[email protected]b1122982010-05-17 23:04:247211}
7212
7213void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137214 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
7215 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
7216 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:247217 }
[email protected]b1122982010-05-17 23:04:247218}
7219
7220void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137221 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
7222 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
7223 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:247224 }
[email protected]b1122982010-05-17 23:04:247225}
7226
7227void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137228 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
7229 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:247230 }
[email protected]b1122982010-05-17 23:04:247231}
7232
[email protected]f7a64ee2010-02-01 22:24:147233error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
vmiuracd108592014-09-08 14:36:347234 uint32 immediate_data_size,
7235 const void* cmd_data) {
7236 const gles2::cmds::VertexAttribPointer& c =
7237 *static_cast<const gles2::cmds::VertexAttribPointer*>(cmd_data);
[email protected]944b62f32012-09-27 02:20:467238
[email protected]7cd76fd2013-06-02 21:11:117239 if (!state_.bound_array_buffer.get() ||
7240 state_.bound_array_buffer->IsDeleted()) {
7241 if (state_.vertex_attrib_manager.get() ==
[email protected]81f20a622014-04-18 01:54:527242 state_.default_vertex_attrib_manager.get()) {
[email protected]ab09b612013-03-11 22:11:517243 LOCAL_SET_GL_ERROR(
7244 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:467245 return error::kNoError;
7246 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:517247 LOCAL_SET_GL_ERROR(
7248 GL_INVALID_VALUE,
7249 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:467250 return error::kNoError;
7251 }
[email protected]96449d2c2009-11-25 00:01:327252 }
[email protected]8eee29c2010-04-29 03:38:297253
7254 GLuint indx = c.indx;
7255 GLint size = c.size;
7256 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:327257 GLboolean normalized = static_cast<GLboolean>(c.normalized);
[email protected]8eee29c2010-04-29 03:38:297258 GLsizei stride = c.stride;
7259 GLsizei offset = c.offset;
7260 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:057261 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517262 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:297263 return error::kNoError;
7264 }
[email protected]9438b012010-06-15 22:55:057265 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:517266 LOCAL_SET_GL_ERROR(
7267 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:297268 return error::kNoError;
7269 }
7270 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517271 LOCAL_SET_GL_ERROR(
7272 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:297273 return error::kNoError;
7274 }
7275 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:517276 LOCAL_SET_GL_ERROR(
7277 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:297278 return error::kNoError;
7279 }
7280 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:517281 LOCAL_SET_GL_ERROR(
7282 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:297283 return error::kNoError;
7284 }
7285 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:517286 LOCAL_SET_GL_ERROR(
7287 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:297288 return error::kNoError;
7289 }
7290 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:317291 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]a07a23602014-08-05 11:36:127292 // component_size must be a power of two to use & as optimized modulo.
7293 DCHECK(GLES2Util::IsPOT(component_size));
7294 if (offset & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517295 LOCAL_SET_GL_ERROR(
7296 GL_INVALID_OPERATION,
7297 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:317298 return error::kNoError;
7299 }
[email protected]a07a23602014-08-05 11:36:127300 if (stride & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517301 LOCAL_SET_GL_ERROR(
7302 GL_INVALID_OPERATION,
7303 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:297304 return error::kNoError;
7305 }
[email protected]7cd76fd2013-06-02 21:11:117306 state_.vertex_attrib_manager
7307 ->SetAttribInfo(indx,
7308 state_.bound_array_buffer.get(),
7309 size,
7310 type,
7311 normalized,
7312 stride,
7313 stride != 0 ? stride : component_size * size,
7314 offset);
[email protected]8fbedc02010-11-18 18:43:407315 if (type != GL_FIXED) {
7316 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
7317 }
[email protected]f7a64ee2010-02-01 22:24:147318 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327319}
7320
[email protected]43410e92012-04-20 17:06:287321void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
7322 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:247323 state_.viewport_x = x;
7324 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:027325 state_.viewport_width = std::min(width, viewport_max_width_);
7326 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:287327 glViewport(x, y, width, height);
7328}
7329
[email protected]c6aef902012-02-14 03:31:427330error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
vmiuracd108592014-09-08 14:36:347331 uint32 immediate_data_size,
7332 const void* cmd_data) {
7333 const gles2::cmds::VertexAttribDivisorANGLE& c =
7334 *static_cast<const gles2::cmds::VertexAttribDivisorANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:157335 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517336 LOCAL_SET_GL_ERROR(
7337 GL_INVALID_OPERATION,
7338 "glVertexAttribDivisorANGLE", "function not available");
[email protected]cedee332014-05-23 07:07:537339 return error::kNoError;
[email protected]c6aef902012-02-14 03:31:427340 }
7341 GLuint index = c.index;
7342 GLuint divisor = c.divisor;
7343 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517344 LOCAL_SET_GL_ERROR(
7345 GL_INVALID_VALUE,
7346 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:427347 return error::kNoError;
7348 }
7349
[email protected]e259eb412012-10-13 05:47:247350 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:427351 index,
7352 divisor);
7353 glVertexAttribDivisorANGLE(index, divisor);
7354 return error::kNoError;
7355}
7356
[email protected]68586372013-12-11 01:27:597357template <typename pixel_data_type>
7358static void WriteAlphaData(
7359 void *pixels, uint32 row_count, uint32 channel_count,
7360 uint32 alpha_channel_index, uint32 unpadded_row_size,
7361 uint32 padded_row_size, pixel_data_type alpha_value) {
7362 DCHECK_GT(channel_count, 0U);
7363 DCHECK_EQ(unpadded_row_size % sizeof(pixel_data_type), 0U);
7364 uint32 unpadded_row_size_in_elements =
7365 unpadded_row_size / sizeof(pixel_data_type);
7366 DCHECK_EQ(padded_row_size % sizeof(pixel_data_type), 0U);
7367 uint32 padded_row_size_in_elements =
7368 padded_row_size / sizeof(pixel_data_type);
7369 pixel_data_type* dst =
7370 static_cast<pixel_data_type*>(pixels) + alpha_channel_index;
7371 for (uint32 yy = 0; yy < row_count; ++yy) {
7372 pixel_data_type* end = dst + unpadded_row_size_in_elements;
7373 for (pixel_data_type* d = dst; d < end; d += channel_count) {
7374 *d = alpha_value;
7375 }
7376 dst += padded_row_size_in_elements;
7377 }
7378}
7379
[email protected]5a36dc132013-07-23 23:17:557380void GLES2DecoderImpl::FinishReadPixels(
7381 const cmds::ReadPixels& c,
7382 GLuint buffer) {
7383 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels");
7384 GLsizei width = c.width;
7385 GLsizei height = c.height;
7386 GLenum format = c.format;
7387 GLenum type = c.type;
7388 typedef cmds::ReadPixels::Result Result;
7389 uint32 pixels_size;
7390 Result* result = NULL;
7391 if (c.result_shm_id != 0) {
7392 result = GetSharedMemoryAs<Result*>(
7393 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7394 if (!result) {
7395 if (buffer != 0) {
7396 glDeleteBuffersARB(1, &buffer);
7397 }
7398 return;
7399 }
7400 }
7401 GLES2Util::ComputeImageDataSizes(
7402 width, height, format, type, state_.pack_alignment, &pixels_size,
7403 NULL, NULL);
7404 void* pixels = GetSharedMemoryAs<void*>(
7405 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
7406 if (!pixels) {
7407 if (buffer != 0) {
7408 glDeleteBuffersARB(1, &buffer);
7409 }
7410 return;
7411 }
7412
7413 if (buffer != 0) {
7414 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
[email protected]e585f9e22013-08-27 02:50:337415 void* data;
7416 if (features().map_buffer_range) {
7417 data = glMapBufferRange(
7418 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT);
7419 } else {
7420 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
7421 }
[email protected]5a36dc132013-07-23 23:17:557422 memcpy(pixels, data, pixels_size);
7423 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't
7424 // have to restore the state.
7425 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
7426 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7427 glDeleteBuffersARB(1, &buffer);
7428 }
7429
7430 if (result != NULL) {
7431 *result = true;
7432 }
7433
7434 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7435 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7436 if ((channels_exist & 0x0008) == 0 &&
7437 workarounds().clear_alpha_in_readpixels) {
7438 // Set the alpha to 255 because some drivers are buggy in this regard.
7439 uint32 temp_size;
7440
7441 uint32 unpadded_row_size;
7442 uint32 padded_row_size;
7443 if (!GLES2Util::ComputeImageDataSizes(
7444 width, 2, format, type, state_.pack_alignment, &temp_size,
7445 &unpadded_row_size, &padded_row_size)) {
7446 return;
7447 }
[email protected]68586372013-12-11 01:27:597448
7449 uint32 channel_count = 0;
7450 uint32 alpha_channel = 0;
[email protected]5a36dc132013-07-23 23:17:557451 switch (format) {
7452 case GL_RGBA:
7453 case GL_BGRA_EXT:
[email protected]68586372013-12-11 01:27:597454 channel_count = 4;
7455 alpha_channel = 3;
[email protected]5a36dc132013-07-23 23:17:557456 break;
[email protected]68586372013-12-11 01:27:597457 case GL_ALPHA:
7458 channel_count = 1;
7459 alpha_channel = 0;
7460 break;
7461 }
7462
7463 if (channel_count > 0) {
7464 switch (type) {
7465 case GL_UNSIGNED_BYTE:
7466 WriteAlphaData<uint8>(
7467 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7468 padded_row_size, 0xFF);
7469 break;
7470 case GL_FLOAT:
7471 WriteAlphaData<float>(
7472 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7473 padded_row_size, 1.0f);
7474 break;
7475 case GL_HALF_FLOAT:
7476 WriteAlphaData<uint16>(
7477 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7478 padded_row_size, 0x3C00);
7479 break;
[email protected]5a36dc132013-07-23 23:17:557480 }
[email protected]5a36dc132013-07-23 23:17:557481 }
7482 }
7483}
7484
vmiuracd108592014-09-08 14:36:347485error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size,
7486 const void* cmd_data) {
7487 const gles2::cmds::ReadPixels& c =
7488 *static_cast<const gles2::cmds::ReadPixels*>(cmd_data);
[email protected]c959a09a2014-03-27 11:44:217489 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleReadPixels");
[email protected]c76fe672013-12-13 23:30:227490 error::Error fbo_error = WillAccessBoundFramebufferForRead();
7491 if (fbo_error != error::kNoError)
7492 return fbo_error;
[email protected]612d2f82009-12-08 20:49:317493 GLint x = c.x;
7494 GLint y = c.y;
7495 GLsizei width = c.width;
7496 GLsizei height = c.height;
7497 GLenum format = c.format;
7498 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:327499 GLboolean async = static_cast<GLboolean>(c.async);
[email protected]57f223832010-03-19 01:57:567500 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:517501 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:567502 return error::kNoError;
7503 }
[email protected]ed9f9cd2013-02-27 21:12:357504 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:187505 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347506 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247507 width, height, format, type, state_.pack_alignment, &pixels_size,
7508 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187509 return error::kOutOfBounds;
7510 }
[email protected]612d2f82009-12-08 20:49:317511 void* pixels = GetSharedMemoryAs<void*>(
7512 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:107513 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147514 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467515 }
[email protected]de43f082013-04-02 01:16:107516 Result* result = NULL;
7517 if (c.result_shm_id != 0) {
7518 result = GetSharedMemoryAs<Result*>(
7519 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7520 if (!result) {
7521 return error::kOutOfBounds;
7522 }
7523 }
[email protected]a51788e2010-02-24 21:54:257524
[email protected]9438b012010-06-15 22:55:057525 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517526 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:297527 return error::kNoError;
7528 }
[email protected]68586372013-12-11 01:27:597529 if (!validators_->read_pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517530 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:127531 return error::kNoError;
7532 }
[email protected]68586372013-12-11 01:27:597533 if ((format != GL_RGBA && format != GL_BGRA_EXT && format != GL_RGB &&
7534 format != GL_ALPHA) || type != GL_UNSIGNED_BYTE) {
7535 // format and type are acceptable enums but not guaranteed to be supported
7536 // for this framebuffer. Have to ask gl if they are valid.
7537 GLint preferred_format = 0;
7538 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &preferred_format);
7539 GLint preferred_type = 0;
7540 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &preferred_type);
7541 if (format != static_cast<GLenum>(preferred_format) ||
7542 type != static_cast<GLenum>(preferred_type)) {
7543 LOCAL_SET_GL_ERROR(
7544 GL_INVALID_OPERATION, "glReadPixels", "format and type incompatible "
7545 "with the current read framebuffer");
7546 return error::kNoError;
7547 }
7548 }
[email protected]57f223832010-03-19 01:57:567549 if (width == 0 || height == 0) {
7550 return error::kNoError;
7551 }
7552
[email protected]57f223832010-03-19 01:57:567553 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:307554 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:567555
[email protected]3aad1a32012-09-07 20:54:477556 int32 max_x;
7557 int32 max_y;
7558 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:517559 LOCAL_SET_GL_ERROR(
7560 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:147561 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:317562 }
[email protected]57f223832010-03-19 01:57:567563
[email protected]2ea5950d2014-07-09 18:20:347564 if (!CheckBoundReadFramebufferColorAttachment("glReadPixels")) {
7565 return error::kNoError;
7566 }
7567
[email protected]0d6bfdc2011-11-02 01:32:207568 if (!CheckBoundFramebuffersValid("glReadPixels")) {
7569 return error::kNoError;
7570 }
7571
[email protected]caa13ed2014-02-17 11:29:207572 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixels");
[email protected]a0b78dc2011-11-11 10:43:107573
7574 ScopedResolvedFrameBufferBinder binder(this, false, true);
7575
[email protected]d37231fa2010-04-09 21:16:027576 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:567577 // The user requested an out of range area. Get the results 1 line
7578 // at a time.
7579 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:347580 uint32 unpadded_row_size;
7581 uint32 padded_row_size;
7582 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247583 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:347584 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:517585 LOCAL_SET_GL_ERROR(
7586 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567587 return error::kNoError;
7588 }
7589
7590 GLint dest_x_offset = std::max(-x, 0);
7591 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:347592 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247593 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset,
7594 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:517595 LOCAL_SET_GL_ERROR(
7596 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567597 return error::kNoError;
7598 }
7599
7600 // Copy each row into the larger dest rect.
7601 int8* dst = static_cast<int8*>(pixels);
7602 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:027603 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:567604 GLint read_width = read_end_x - read_x;
7605 for (GLint yy = 0; yy < height; ++yy) {
7606 GLint ry = y + yy;
7607
7608 // Clear the row.
7609 memset(dst, 0, unpadded_row_size);
7610
7611 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:027612 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:567613 glReadPixels(
7614 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
7615 }
7616 dst += padded_row_size;
7617 }
7618 } else {
[email protected]5a36dc132013-07-23 23:17:557619 if (async && features().use_async_readpixels) {
7620 GLuint buffer;
7621 glGenBuffersARB(1, &buffer);
7622 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
7623 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, GL_STREAM_READ);
7624 GLenum error = glGetError();
7625 if (error == GL_NO_ERROR) {
7626 glReadPixels(x, y, width, height, format, type, 0);
7627 pending_readpixel_fences_.push(linked_ptr<FenceCallback>(
7628 new FenceCallback()));
7629 WaitForReadPixels(base::Bind(
7630 &GLES2DecoderImpl::FinishReadPixels,
7631 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr
7632 <GLES2DecoderImpl>(this),
7633 c, buffer));
7634 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7635 return error::kNoError;
[email protected]77bfe7442014-03-01 02:42:597636 } else {
7637 // On error, unbind pack buffer and fall through to sync readpixels
7638 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
[email protected]5a36dc132013-07-23 23:17:557639 }
7640 }
[email protected]57f223832010-03-19 01:57:567641 glReadPixels(x, y, width, height, format, type, pixels);
7642 }
[email protected]ab09b612013-03-11 22:11:517643 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:257644 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:107645 if (result != NULL) {
7646 *result = true;
7647 }
[email protected]5a36dc132013-07-23 23:17:557648 FinishReadPixels(c, 0);
[email protected]a51788e2010-02-24 21:54:257649 }
[email protected]4848b9f82011-03-10 18:37:567650
[email protected]f7a64ee2010-02-01 22:24:147651 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327652}
7653
vmiuracd108592014-09-08 14:36:347654error::Error GLES2DecoderImpl::HandlePixelStorei(uint32 immediate_data_size,
7655 const void* cmd_data) {
7656 const gles2::cmds::PixelStorei& c =
7657 *static_cast<const gles2::cmds::PixelStorei*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:197658 GLenum pname = c.pname;
7659 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:057660 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:517661 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:127662 return error::kNoError;
7663 }
[email protected]222471d2011-11-30 18:06:397664 switch (pname) {
7665 case GL_PACK_ALIGNMENT:
7666 case GL_UNPACK_ALIGNMENT:
7667 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:517668 LOCAL_SET_GL_ERROR(
[email protected]caa13ed2014-02-17 11:29:207669 GL_INVALID_VALUE, "glPixelStorei", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:397670 return error::kNoError;
7671 }
[email protected]164d6d52012-05-05 00:55:037672 break;
[email protected]0a1e9ad2012-05-04 21:13:037673 case GL_UNPACK_FLIP_Y_CHROMIUM:
7674 unpack_flip_y_ = (param != 0);
7675 return error::kNoError;
7676 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
7677 unpack_premultiply_alpha_ = (param != 0);
7678 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:177679 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
7680 unpack_unpremultiply_alpha_ = (param != 0);
7681 return error::kNoError;
[email protected]222471d2011-11-30 18:06:397682 default:
7683 break;
[email protected]b9849abf2009-11-25 19:13:197684 }
7685 glPixelStorei(pname, param);
7686 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:437687 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247688 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437689 break;
7690 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:427691 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:437692 break;
7693 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247694 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437695 break;
7696 default:
7697 // Validation should have prevented us from getting here.
7698 NOTREACHED();
7699 break;
[email protected]b9849abf2009-11-25 19:13:197700 }
[email protected]f7a64ee2010-02-01 22:24:147701 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197702}
7703
[email protected]1c75a3702011-11-11 14:15:287704error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
vmiuracd108592014-09-08 14:36:347705 uint32 immediate_data_size,
7706 const void* cmd_data) {
7707 const gles2::cmds::PostSubBufferCHROMIUM& c =
7708 *static_cast<const gles2::cmds::PostSubBufferCHROMIUM*>(cmd_data);
[email protected]43ed3a72012-05-30 22:55:387709 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]a36ed4832014-04-24 16:40:277710 {
7711 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
7712 }
[email protected]b381ee32014-03-22 02:43:437713 if (!supports_post_sub_buffer_) {
[email protected]ab09b612013-03-11 22:11:517714 LOCAL_SET_GL_ERROR(
7715 GL_INVALID_OPERATION,
7716 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:287717 return error::kNoError;
7718 }
[email protected]8f9b8dd2013-09-12 18:05:137719 bool is_tracing;
7720 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
7721 &is_tracing);
7722 if (is_tracing) {
7723 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
7724 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
7725 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
7726 is_offscreen ? offscreen_size_ : surface_->GetSize());
7727 }
[email protected]7794d512012-04-17 20:36:497728 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:287729 return error::kNoError;
[email protected]7794d512012-04-17 20:36:497730 } else {
7731 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:287732 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:497733 }
[email protected]1c75a3702011-11-11 14:15:287734}
7735
[email protected]957f0642014-04-09 16:50:017736error::Error GLES2DecoderImpl::HandleScheduleOverlayPlaneCHROMIUM(
7737 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:347738 const void* cmd_data) {
7739 const gles2::cmds::ScheduleOverlayPlaneCHROMIUM& c =
7740 *static_cast<const gles2::cmds::ScheduleOverlayPlaneCHROMIUM*>(cmd_data);
[email protected]d286ebbc2014-07-03 17:19:107741 TextureRef* ref = texture_manager()->GetTexture(c.overlay_texture_id);
7742 if (!ref) {
7743 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
7744 "glScheduleOverlayPlaneCHROMIUM",
7745 "unknown texture");
7746 return error::kNoError;
7747 }
7748 gfx::GLImage* image =
7749 ref->texture()->GetLevelImage(ref->texture()->target(), 0);
7750 if (!image) {
7751 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
7752 "glScheduleOverlayPlaneCHROMIUM",
7753 "unsupported texture format");
7754 return error::kNoError;
7755 }
7756 gfx::OverlayTransform transform = GetGFXOverlayTransform(c.plane_transform);
7757 if (transform == gfx::OVERLAY_TRANSFORM_INVALID) {
7758 LOCAL_SET_GL_ERROR(GL_INVALID_ENUM,
7759 "glScheduleOverlayPlaneCHROMIUM",
7760 "invalid transform enum");
7761 return error::kNoError;
7762 }
7763 if (!surface_->ScheduleOverlayPlane(
7764 c.plane_z_order,
7765 transform,
7766 image,
7767 gfx::Rect(c.bounds_x, c.bounds_y, c.bounds_width, c.bounds_height),
7768 gfx::RectF(c.uv_x, c.uv_y, c.uv_width, c.uv_height))) {
7769 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
7770 "glScheduleOverlayPlaneCHROMIUM",
7771 "failed to schedule overlay");
7772 }
[email protected]957f0642014-04-09 16:50:017773 return error::kNoError;
7774}
7775
[email protected]558847a2010-03-24 07:02:547776error::Error GLES2DecoderImpl::GetAttribLocationHelper(
7777 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7778 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577779 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517780 LOCAL_SET_GL_ERROR(
7781 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577782 return error::kNoError;
7783 }
[email protected]df37b9932013-03-08 05:21:427784 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587785 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:427786 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147787 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197788 }
[email protected]df37b9932013-03-08 05:21:427789 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517790 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437791 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257792 return error::kNoError;
7793 }
[email protected]b9849abf2009-11-25 19:13:197794 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547795 location_shm_id, location_shm_offset, sizeof(GLint));
7796 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147797 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197798 }
[email protected]558847a2010-03-24 07:02:547799 // Require the client to init this incase the context is lost and we are no
7800 // longer executing commands.
7801 if (*location != -1) {
7802 return error::kGenericError;
7803 }
[email protected]df37b9932013-03-08 05:21:427804 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147805 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197806}
7807
[email protected]558847a2010-03-24 07:02:547808error::Error GLES2DecoderImpl::HandleGetAttribLocation(
vmiuracd108592014-09-08 14:36:347809 uint32 immediate_data_size,
7810 const void* cmd_data) {
7811 const gles2::cmds::GetAttribLocation& c =
7812 *static_cast<const gles2::cmds::GetAttribLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:547813 Bucket* bucket = GetBucket(c.name_bucket_id);
7814 if (!bucket) {
7815 return error::kInvalidArguments;
7816 }
7817 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187818 if (!bucket->GetAsString(&name_str)) {
7819 return error::kInvalidArguments;
7820 }
[email protected]558847a2010-03-24 07:02:547821 return GetAttribLocationHelper(
7822 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7823}
7824
7825error::Error GLES2DecoderImpl::GetUniformLocationHelper(
7826 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7827 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577828 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517829 LOCAL_SET_GL_ERROR(
7830 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577831 return error::kNoError;
7832 }
[email protected]df37b9932013-03-08 05:21:427833 Program* program = GetProgramInfoNotShader(
[email protected]caa13ed2014-02-17 11:29:207834 client_id, "glGetUniformLocation");
[email protected]df37b9932013-03-08 05:21:427835 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147836 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197837 }
[email protected]df37b9932013-03-08 05:21:427838 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517839 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437840 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257841 return error::kNoError;
7842 }
[email protected]b9849abf2009-11-25 19:13:197843 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547844 location_shm_id, location_shm_offset, sizeof(GLint));
7845 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147846 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197847 }
[email protected]558847a2010-03-24 07:02:547848 // Require the client to init this incase the context is lost an we are no
7849 // longer executing commands.
7850 if (*location != -1) {
7851 return error::kGenericError;
7852 }
[email protected]df37b9932013-03-08 05:21:427853 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147854 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197855}
7856
[email protected]f7a64ee2010-02-01 22:24:147857error::Error GLES2DecoderImpl::HandleGetUniformLocation(
vmiuracd108592014-09-08 14:36:347858 uint32 immediate_data_size,
7859 const void* cmd_data) {
7860 const gles2::cmds::GetUniformLocation& c =
7861 *static_cast<const gles2::cmds::GetUniformLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:547862 Bucket* bucket = GetBucket(c.name_bucket_id);
7863 if (!bucket) {
7864 return error::kInvalidArguments;
7865 }
7866 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187867 if (!bucket->GetAsString(&name_str)) {
7868 return error::kInvalidArguments;
7869 }
[email protected]558847a2010-03-24 07:02:547870 return GetUniformLocationHelper(
7871 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197872}
7873
vmiuracd108592014-09-08 14:36:347874error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size,
7875 const void* cmd_data) {
7876 const gles2::cmds::GetString& c =
7877 *static_cast<const gles2::cmds::GetString*>(cmd_data);
[email protected]ddd968b82010-03-02 00:44:297878 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:057879 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:517880 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:297881 return error::kNoError;
7882 }
[email protected]959e9072013-09-20 16:58:387883 const char* str = reinterpret_cast<const char*>(glGetString(name));
[email protected]f0d74742011-10-03 16:31:047884 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:157885 switch (name) {
7886 case GL_VERSION:
7887 str = "OpenGL ES 2.0 Chromium";
7888 break;
7889 case GL_SHADING_LANGUAGE_VERSION:
7890 str = "OpenGL ES GLSL ES 1.0 Chromium";
7891 break;
[email protected]32939602012-05-09 06:25:167892 case GL_RENDERER:
[email protected]32939602012-05-09 06:25:167893 case GL_VENDOR:
[email protected]959e9072013-09-20 16:58:387894 // Return the unmasked VENDOR/RENDERER string for WebGL contexts.
7895 // They are used by WEBGL_debug_renderer_info.
7896 if (!force_webgl_glsl_validation_)
7897 str = "Chromium";
[email protected]32939602012-05-09 06:25:167898 break;
[email protected]1958e0e2010-04-22 05:17:157899 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:047900 {
[email protected]70dc60932013-06-04 03:33:497901 // For WebGL contexts, strip out the OES derivatives and
7902 // EXT frag depth extensions if they have not been enabled.
7903 if (force_webgl_glsl_validation_) {
[email protected]f0d74742011-10-03 16:31:047904 extensions = feature_info_->extensions();
[email protected]70dc60932013-06-04 03:33:497905 if (!derivatives_explicitly_enabled_) {
7906 size_t offset = extensions.find(kOESDerivativeExtension);
7907 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097908 extensions.replace(offset, arraysize(kOESDerivativeExtension),
[email protected]70dc60932013-06-04 03:33:497909 std::string());
7910 }
7911 }
7912 if (!frag_depth_explicitly_enabled_) {
7913 size_t offset = extensions.find(kEXTFragDepthExtension);
7914 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097915 extensions.replace(offset, arraysize(kEXTFragDepthExtension),
[email protected]70dc60932013-06-04 03:33:497916 std::string());
7917 }
[email protected]f0d74742011-10-03 16:31:047918 }
[email protected]aff39ac82013-06-08 04:53:137919 if (!draw_buffers_explicitly_enabled_) {
7920 size_t offset = extensions.find(kEXTDrawBuffersExtension);
7921 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097922 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension),
[email protected]aff39ac82013-06-08 04:53:137923 std::string());
7924 }
7925 }
[email protected]93c2fd82014-04-16 02:46:067926 if (!shader_texture_lod_explicitly_enabled_) {
7927 size_t offset = extensions.find(kEXTShaderTextureLodExtension);
7928 if (std::string::npos != offset) {
7929 extensions.replace(offset,
7930 arraysize(kEXTShaderTextureLodExtension),
7931 std::string());
7932 }
7933 }
[email protected]f0d74742011-10-03 16:31:047934 } else {
[email protected]6f5fac9d12012-06-26 21:02:457935 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:047936 }
[email protected]b381ee32014-03-22 02:43:437937 if (supports_post_sub_buffer_)
7938 extensions += " GL_CHROMIUM_post_sub_buffer";
[email protected]6f5fac9d12012-06-26 21:02:457939 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:047940 }
[email protected]1958e0e2010-04-22 05:17:157941 break;
7942 default:
[email protected]1958e0e2010-04-22 05:17:157943 break;
7944 }
[email protected]ddd968b82010-03-02 00:44:297945 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:157946 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:297947 return error::kNoError;
7948}
7949
vmiuracd108592014-09-08 14:36:347950error::Error GLES2DecoderImpl::HandleBufferData(uint32 immediate_data_size,
7951 const void* cmd_data) {
7952 const gles2::cmds::BufferData& c =
7953 *static_cast<const gles2::cmds::BufferData*>(cmd_data);
[email protected]0c86dbf2010-03-05 08:14:117954 GLenum target = static_cast<GLenum>(c.target);
7955 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
7956 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7957 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7958 GLenum usage = static_cast<GLenum>(c.usage);
7959 const void* data = NULL;
7960 if (data_shm_id != 0 || data_shm_offset != 0) {
7961 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
7962 if (!data) {
7963 return error::kOutOfBounds;
7964 }
7965 }
[email protected]0fbba3732013-07-17 15:40:137966 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:147967 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197968}
7969
[email protected]0c86dbf2010-03-05 08:14:117970void GLES2DecoderImpl::DoBufferSubData(
7971 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]0fbba3732013-07-17 15:40:137972 // Just delegate it. Some validation is actually done before this.
7973 buffer_manager()->ValidateAndDoBufferSubData(
7974 &state_, target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:197975}
7976
[email protected]0d6bfdc2011-11-02 01:32:207977bool GLES2DecoderImpl::ClearLevel(
7978 unsigned service_id,
7979 unsigned bind_target,
7980 unsigned target,
7981 int level,
[email protected]d8e6c9242014-02-20 16:56:257982 unsigned internal_format,
[email protected]0d6bfdc2011-11-02 01:32:207983 unsigned format,
7984 unsigned type,
7985 int width,
[email protected]4502e6492011-12-14 19:39:157986 int height,
7987 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:007988 uint32 channels = GLES2Util::GetChannelsForFormat(format);
[email protected]345ba902013-11-14 21:39:007989 if (feature_info_->feature_flags().angle_depth_texture &&
7990 (channels & GLES2Util::kDepth) != 0) {
[email protected]81375742012-06-08 00:04:007991 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
7992 // on depth formats.
7993 GLuint fb = 0;
7994 glGenFramebuffersEXT(1, &fb);
7995 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
7996
7997 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
7998 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
7999 GL_DEPTH_ATTACHMENT;
8000
8001 glFramebufferTexture2DEXT(
8002 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
8003 // ANGLE promises a depth only attachment ok.
8004 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
8005 GL_FRAMEBUFFER_COMPLETE) {
8006 return false;
8007 }
8008 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:478009 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
8010 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]81375742012-06-08 00:04:008011 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:458012 state_.SetDeviceDepthMask(GL_TRUE);
8013 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]81375742012-06-08 00:04:008014 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
8015
8016 RestoreClearState();
8017
8018 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:358019 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:008020 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
8021 GLuint fb_service_id =
8022 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
8023 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
8024 return true;
8025 }
8026
[email protected]45d15a62012-04-18 14:33:178027 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
8028
8029 uint32 size;
8030 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:348031 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248032 width, height, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:178033 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:208034 return false;
8035 }
[email protected]45d15a62012-04-18 14:33:178036
[email protected]a5d3dad2012-05-26 04:34:448037 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
8038
[email protected]45d15a62012-04-18 14:33:178039 int tile_height;
8040
8041 if (size > kMaxZeroSize) {
8042 if (kMaxZeroSize < padded_row_size) {
8043 // That'd be an awfully large texture.
8044 return false;
8045 }
8046 // We should never have a large total size with a zero row size.
8047 DCHECK_GT(padded_row_size, 0U);
8048 tile_height = kMaxZeroSize / padded_row_size;
8049 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248050 width, tile_height, format, type, state_.unpack_alignment, &size,
8051 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:178052 return false;
8053 }
[email protected]4502e6492011-12-14 19:39:158054 } else {
[email protected]45d15a62012-04-18 14:33:178055 tile_height = height;
8056 }
8057
8058 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:558059 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:178060 memset(zero.get(), 0, size);
8061 glBindTexture(bind_target, service_id);
8062
8063 GLint y = 0;
8064 while (y < height) {
8065 GLint h = y + tile_height > height ? height - y : tile_height;
8066 if (is_texture_immutable || h != height) {
8067 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
8068 } else {
[email protected]8f1d2aa2013-05-10 23:45:388069 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:258070 target, level, internal_format, width, h, 0, format, type,
8071 zero.get());
[email protected]45d15a62012-04-18 14:33:178072 }
8073 y += tile_height;
[email protected]4502e6492011-12-14 19:39:158074 }
[email protected]c986af502013-08-14 01:04:448075 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
8076 &state_, bind_target);
[email protected]02965c22013-03-09 02:40:078077 glBindTexture(bind_target, texture ? texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:208078 return true;
8079}
8080
[email protected]ad84a3a2012-06-08 21:42:438081namespace {
8082
8083const int kS3TCBlockWidth = 4;
8084const int kS3TCBlockHeight = 4;
8085const int kS3TCDXT1BlockSize = 8;
8086const int kS3TCDXT3AndDXT5BlockSize = 16;
8087
8088bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:518089 return (size == 1) ||
8090 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:438091}
8092
[email protected]8aec81ec2014-04-29 01:04:518093bool IsValidPVRTCSize(GLint level, GLsizei size) {
[email protected]a07a23602014-08-05 11:36:128094 return GLES2Util::IsPOT(size);
[email protected]8aec81ec2014-04-29 01:04:518095}
8096
[email protected]ad84a3a2012-06-08 21:42:438097} // anonymous namespace.
8098
8099bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
8100 const char* function_name,
8101 GLsizei width, GLsizei height, GLenum format, size_t size) {
8102 unsigned int bytes_required = 0;
8103
8104 switch (format) {
[email protected]8aec81ec2014-04-29 01:04:518105 case GL_ATC_RGB_AMD:
[email protected]ad84a3a2012-06-08 21:42:438106 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
[email protected]8aec81ec2014-04-29 01:04:518107 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8108 case GL_ETC1_RGB8_OES: {
[email protected]ad84a3a2012-06-08 21:42:438109 int num_blocks_across =
8110 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8111 int num_blocks_down =
8112 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8113 int num_blocks = num_blocks_across * num_blocks_down;
8114 bytes_required = num_blocks * kS3TCDXT1BlockSize;
8115 break;
8116 }
[email protected]8aec81ec2014-04-29 01:04:518117 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8118 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
[email protected]ad84a3a2012-06-08 21:42:438119 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8120 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8121 int num_blocks_across =
8122 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8123 int num_blocks_down =
8124 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8125 int num_blocks = num_blocks_across * num_blocks_down;
8126 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
8127 break;
8128 }
[email protected]8aec81ec2014-04-29 01:04:518129 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8130 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: {
8131 bytes_required = (std::max(width, 8) * std::max(height, 8) * 4 + 7)/8;
8132 break;
8133 }
8134 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8135 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8136 bytes_required = (std::max(width, 16) * std::max(height, 8) * 2 + 7)/8;
[email protected]2d3765b2012-10-03 00:31:078137 break;
8138 }
[email protected]ad84a3a2012-06-08 21:42:438139 default:
[email protected]ab09b612013-03-11 22:11:518140 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:438141 return false;
8142 }
8143
8144 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:518145 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438146 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
8147 return false;
8148 }
8149
8150 return true;
8151}
8152
8153bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
8154 const char* function_name,
8155 GLint level, GLsizei width, GLsizei height, GLenum format) {
8156 switch (format) {
8157 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8158 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8159 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8160 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8161 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:518162 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438163 GL_INVALID_OPERATION, function_name,
8164 "width or height invalid for level");
8165 return false;
8166 }
8167 return true;
8168 }
[email protected]8aec81ec2014-04-29 01:04:518169 case GL_ATC_RGB_AMD:
8170 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8171 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
8172 case GL_ETC1_RGB8_OES: {
[email protected]2d3765b2012-10-03 00:31:078173 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:518174 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078175 GL_INVALID_OPERATION, function_name,
8176 "width or height invalid for level");
8177 return false;
8178 }
8179 return true;
[email protected]8aec81ec2014-04-29 01:04:518180 }
8181 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8182 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8183 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8184 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8185 if (!IsValidPVRTCSize(level, width) ||
8186 !IsValidPVRTCSize(level, height)) {
8187 LOCAL_SET_GL_ERROR(
8188 GL_INVALID_OPERATION, function_name,
8189 "width or height invalid for level");
8190 return false;
8191 }
8192 return true;
8193 }
[email protected]ad84a3a2012-06-08 21:42:438194 default:
8195 return false;
8196 }
8197}
8198
8199bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
8200 const char* function_name,
8201 GLenum target, GLint level, GLint xoffset, GLint yoffset,
8202 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:358203 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:438204 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:518205 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438206 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
8207 return false;
8208 }
8209
8210 switch (format) {
8211 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8212 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8213 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8214 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8215 const int kBlockWidth = 4;
8216 const int kBlockHeight = 4;
8217 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:518218 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438219 GL_INVALID_OPERATION, function_name,
8220 "xoffset or yoffset not multiple of 4");
8221 return false;
8222 }
8223 GLsizei tex_width = 0;
8224 GLsizei tex_height = 0;
8225 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8226 width - xoffset > tex_width ||
8227 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:518228 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438229 GL_INVALID_OPERATION, function_name, "dimensions out of range");
8230 return false;
8231 }
8232 return ValidateCompressedTexDimensions(
8233 function_name, level, width, height, format);
8234 }
[email protected]8aec81ec2014-04-29 01:04:518235 case GL_ATC_RGB_AMD:
8236 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8237 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: {
8238 LOCAL_SET_GL_ERROR(
8239 GL_INVALID_OPERATION, function_name,
8240 "not supported for ATC textures");
8241 return false;
8242 }
[email protected]2d3765b2012-10-03 00:31:078243 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:518244 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078245 GL_INVALID_OPERATION, function_name,
[email protected]caa13ed2014-02-17 11:29:208246 "not supported for ECT1_RGB8_OES textures");
[email protected]2d3765b2012-10-03 00:31:078247 return false;
8248 }
[email protected]8aec81ec2014-04-29 01:04:518249 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 ((xoffset != 0) || (yoffset != 0)) {
8254 LOCAL_SET_GL_ERROR(
8255 GL_INVALID_OPERATION, function_name,
8256 "xoffset and yoffset must be zero");
8257 return false;
8258 }
8259 GLsizei tex_width = 0;
8260 GLsizei tex_height = 0;
8261 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8262 width != tex_width ||
8263 height != tex_height) {
8264 LOCAL_SET_GL_ERROR(
8265 GL_INVALID_OPERATION, function_name,
8266 "dimensions must match existing texture level dimensions");
8267 return false;
8268 }
8269 return ValidateCompressedTexDimensions(
8270 function_name, level, width, height, format);
8271 }
[email protected]ad84a3a2012-06-08 21:42:438272 default:
8273 return false;
8274 }
8275}
8276
[email protected]a93bb842010-02-16 23:03:478277error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
8278 GLenum target,
8279 GLint level,
8280 GLenum internal_format,
8281 GLsizei width,
8282 GLsizei height,
8283 GLint border,
8284 GLsizei image_size,
8285 const void* data) {
[email protected]a93bb842010-02-16 23:03:478286 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:058287 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518288 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8289 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:298290 return error::kNoError;
8291 }
[email protected]9438b012010-06-15 22:55:058292 if (!validators_->compressed_texture_format.IsValid(
8293 internal_format)) {
[email protected]ab09b612013-03-11 22:11:518294 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538295 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:478296 return error::kNoError;
8297 }
[email protected]80eb6b52012-01-19 00:14:418298 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:478299 border != 0) {
[email protected]ab09b612013-03-11 22:11:518300 LOCAL_SET_GL_ERROR(
8301 GL_INVALID_VALUE,
8302 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:478303 return error::kNoError;
8304 }
[email protected]c986af502013-08-14 01:04:448305 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8306 &state_, target);
[email protected]370eaf12013-05-18 09:19:498307 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518308 LOCAL_SET_GL_ERROR(
8309 GL_INVALID_VALUE,
8310 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:478311 return error::kNoError;
8312 }
[email protected]370eaf12013-05-18 09:19:498313 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078314 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518315 LOCAL_SET_GL_ERROR(
8316 GL_INVALID_OPERATION,
8317 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:438318 return error::kNoError;
8319 }
8320
8321 if (!ValidateCompressedTexDimensions(
8322 "glCompressedTexImage2D", level, width, height, internal_format) ||
8323 !ValidateCompressedTexFuncData(
8324 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:178325 return error::kNoError;
8326 }
[email protected]968351b2011-12-20 08:26:518327
[email protected]7989c9e2013-01-23 06:39:268328 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:518329 LOCAL_SET_GL_ERROR(
8330 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:268331 return error::kNoError;
8332 }
8333
[email protected]02965c22013-03-09 02:40:078334 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448335 framebuffer_state_.clear_state_dirty = true;
[email protected]968351b2011-12-20 08:26:518336 }
8337
[email protected]40d90a22013-04-09 03:39:558338 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:478339 if (!data) {
8340 zero.reset(new int8[image_size]);
8341 memset(zero.get(), 0, image_size);
8342 data = zero.get();
8343 }
[email protected]ab09b612013-03-11 22:11:518344 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:478345 glCompressedTexImage2D(
8346 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:518347 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438348 if (error == GL_NO_ERROR) {
8349 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498350 texture_ref, target, level, internal_format,
8351 width, height, 1, border, 0, 0, true);
[email protected]cadde4a2010-07-31 17:10:438352 }
vmiura8266ca72014-09-09 21:37:008353
8354 // This may be a slow command. Exit command processing to allow for
8355 // context preemption and GPU watchdog checks.
8356 ExitCommandProcessingEarly();
[email protected]a93bb842010-02-16 23:03:478357 return error::kNoError;
8358}
8359
[email protected]f7a64ee2010-02-01 22:24:148360error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
vmiuracd108592014-09-08 14:36:348361 uint32 immediate_data_size,
8362 const void* cmd_data) {
8363 const gles2::cmds::CompressedTexImage2D& c =
8364 *static_cast<const gles2::cmds::CompressedTexImage2D*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:198365 GLenum target = static_cast<GLenum>(c.target);
8366 GLint level = static_cast<GLint>(c.level);
8367 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8368 GLsizei width = static_cast<GLsizei>(c.width);
8369 GLsizei height = static_cast<GLsizei>(c.height);
8370 GLint border = static_cast<GLint>(c.border);
8371 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
8372 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8373 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8374 const void* data = NULL;
8375 if (data_shm_id != 0 || data_shm_offset != 0) {
8376 data = GetSharedMemoryAs<const void*>(
8377 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:468378 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:148379 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198380 }
8381 }
[email protected]a93bb842010-02-16 23:03:478382 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:198383 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:198384}
8385
[email protected]b6140d02010-05-17 14:47:168386error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
vmiuracd108592014-09-08 14:36:348387 uint32 immediate_data_size,
8388 const void* cmd_data) {
8389 const gles2::cmds::CompressedTexImage2DBucket& c =
8390 *static_cast<const gles2::cmds::CompressedTexImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:168391 GLenum target = static_cast<GLenum>(c.target);
8392 GLint level = static_cast<GLint>(c.level);
8393 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8394 GLsizei width = static_cast<GLsizei>(c.width);
8395 GLsizei height = static_cast<GLsizei>(c.height);
8396 GLint border = static_cast<GLint>(c.border);
8397 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288398 if (!bucket) {
8399 return error::kInvalidArguments;
8400 }
8401 uint32 data_size = bucket->size();
8402 GLsizei imageSize = data_size;
8403 const void* data = bucket->GetData(0, data_size);
8404 if (!data) {
8405 return error::kInvalidArguments;
8406 }
[email protected]b6140d02010-05-17 14:47:168407 return DoCompressedTexImage2D(
8408 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:288409 imageSize, data);
[email protected]b6140d02010-05-17 14:47:168410}
8411
8412error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
8413 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:348414 const void* cmd_data) {
8415 const gles2::cmds::CompressedTexSubImage2DBucket& c =
8416 *static_cast<const gles2::cmds::CompressedTexSubImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:168417 GLenum target = static_cast<GLenum>(c.target);
8418 GLint level = static_cast<GLint>(c.level);
8419 GLint xoffset = static_cast<GLint>(c.xoffset);
8420 GLint yoffset = static_cast<GLint>(c.yoffset);
8421 GLsizei width = static_cast<GLsizei>(c.width);
8422 GLsizei height = static_cast<GLsizei>(c.height);
8423 GLenum format = static_cast<GLenum>(c.format);
8424 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288425 if (!bucket) {
8426 return error::kInvalidArguments;
8427 }
[email protected]b6140d02010-05-17 14:47:168428 uint32 data_size = bucket->size();
8429 GLsizei imageSize = data_size;
8430 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:288431 if (!data) {
8432 return error::kInvalidArguments;
8433 }
[email protected]9438b012010-06-15 22:55:058434 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518435 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:538436 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:168437 return error::kNoError;
8438 }
[email protected]9438b012010-06-15 22:55:058439 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518440 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8441 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:058442 return error::kNoError;
8443 }
[email protected]b6140d02010-05-17 14:47:168444 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518445 LOCAL_SET_GL_ERROR(
8446 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:168447 return error::kNoError;
8448 }
8449 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518450 LOCAL_SET_GL_ERROR(
8451 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:168452 return error::kNoError;
8453 }
8454 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:518455 LOCAL_SET_GL_ERROR(
8456 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:168457 return error::kNoError;
8458 }
[email protected]cadde4a2010-07-31 17:10:438459 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:168460 target, level, xoffset, yoffset, width, height, format, imageSize, data);
8461 return error::kNoError;
8462}
8463
vmiuracd108592014-09-08 14:36:348464error::Error GLES2DecoderImpl::HandleTexImage2D(uint32 immediate_data_size,
8465 const void* cmd_data) {
8466 const gles2::cmds::TexImage2D& c =
8467 *static_cast<const gles2::cmds::TexImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:138468 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D",
8469 "width", c.width, "height", c.height);
[email protected]c986af502013-08-14 01:04:448470 // Set as failed for now, but if it successed, this will be set to not failed.
8471 texture_state_.tex_image_2d_failed = true;
[email protected]b9849abf2009-11-25 19:13:198472 GLenum target = static_cast<GLenum>(c.target);
8473 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:448474 // TODO(kloveless): Change TexImage2D command to use unsigned integer
8475 // for internalformat.
8476 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:198477 GLsizei width = static_cast<GLsizei>(c.width);
8478 GLsizei height = static_cast<GLsizei>(c.height);
8479 GLint border = static_cast<GLint>(c.border);
8480 GLenum format = static_cast<GLenum>(c.format);
8481 GLenum type = static_cast<GLenum>(c.type);
8482 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
8483 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:188484 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:348485 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248486 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
[email protected]3458a64a2012-04-10 17:39:348487 NULL)) {
[email protected]a76b0052010-03-05 00:33:188488 return error::kOutOfBounds;
8489 }
[email protected]b9849abf2009-11-25 19:13:198490 const void* pixels = NULL;
8491 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
8492 pixels = GetSharedMemoryAs<const void*>(
8493 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:468494 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:148495 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198496 }
8497 }
[email protected]f598f422012-12-07 08:30:038498
[email protected]c986af502013-08-14 01:04:448499 TextureManager::DoTextImage2DArguments args = {
8500 target, level, internal_format, width, height, border, format, type,
8501 pixels, pixels_size};
8502 texture_manager()->ValidateAndDoTexImage2D(
8503 &texture_state_, &state_, &framebuffer_state_, args);
vmiura8266ca72014-09-09 21:37:008504
8505 // This may be a slow command. Exit command processing to allow for
8506 // context preemption and GPU watchdog checks.
8507 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:038508 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198509}
8510
[email protected]cadde4a2010-07-31 17:10:438511void GLES2DecoderImpl::DoCompressedTexSubImage2D(
8512 GLenum target,
8513 GLint level,
8514 GLint xoffset,
8515 GLint yoffset,
8516 GLsizei width,
8517 GLsizei height,
8518 GLenum format,
8519 GLsizei image_size,
8520 const void * data) {
[email protected]c986af502013-08-14 01:04:448521 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8522 &state_, target);
[email protected]370eaf12013-05-18 09:19:498523 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518524 LOCAL_SET_GL_ERROR(
8525 GL_INVALID_OPERATION,
8526 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438527 return;
8528 }
[email protected]370eaf12013-05-18 09:19:498529 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438530 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:528531 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078532 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518533 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528534 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438535 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:528536 return;
8537 }
8538 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:518539 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528540 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438541 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:528542 return;
8543 }
[email protected]02965c22013-03-09 02:40:078544 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528545 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518546 LOCAL_SET_GL_ERROR(
8547 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438548 return;
8549 }
[email protected]ad84a3a2012-06-08 21:42:438550
8551 if (!ValidateCompressedTexFuncData(
8552 "glCompressedTexSubImage2D", width, height, format, image_size) ||
8553 !ValidateCompressedTexSubDimensions(
8554 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:078555 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:438556 return;
8557 }
8558
8559
[email protected]0d6bfdc2011-11-02 01:32:208560 // Note: There is no need to deal with texture cleared tracking here
8561 // because the validation above means you can only get here if the level
8562 // is already a matching compressed format and in that case
8563 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:438564 glCompressedTexSubImage2D(
8565 target, level, xoffset, yoffset, width, height, format, image_size, data);
vmiura8266ca72014-09-09 21:37:008566
8567 // This may be a slow command. Exit command processing to allow for
8568 // context preemption and GPU watchdog checks.
8569 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:438570}
8571
[email protected]6e288612010-12-21 20:45:038572static void Clip(
8573 GLint start, GLint range, GLint sourceRange,
8574 GLint* out_start, GLint* out_range) {
8575 DCHECK(out_start);
8576 DCHECK(out_range);
8577 if (start < 0) {
8578 range += start;
8579 start = 0;
8580 }
8581 GLint end = start + range;
8582 if (end > sourceRange) {
8583 range -= end - sourceRange;
8584 }
8585 *out_start = start;
8586 *out_range = range;
8587}
8588
[email protected]cadde4a2010-07-31 17:10:438589void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:448590 GLenum target,
8591 GLint level,
8592 GLenum internal_format,
8593 GLint x,
8594 GLint y,
8595 GLsizei width,
8596 GLsizei height,
8597 GLint border) {
[email protected]09e17272012-11-30 10:30:448598 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:448599 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8600 &state_, target);
[email protected]370eaf12013-05-18 09:19:498601 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518602 LOCAL_SET_GL_ERROR(
8603 GL_INVALID_OPERATION,
8604 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438605 return;
8606 }
[email protected]370eaf12013-05-18 09:19:498607 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078608 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518609 LOCAL_SET_GL_ERROR(
8610 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]cedee332014-05-23 07:07:538611 return;
[email protected]97dc7cbe2011-12-06 17:26:178612 }
[email protected]80eb6b52012-01-19 00:14:418613 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:188614 border != 0) {
[email protected]ab09b612013-03-11 22:11:518615 LOCAL_SET_GL_ERROR(
8616 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:188617 return;
8618 }
[email protected]17a961192014-02-14 15:20:528619 if (!texture_manager()->ValidateFormatAndTypeCombination(
8620 state_.GetErrorState(), "glCopyTexImage2D", internal_format,
8621 GL_UNSIGNED_BYTE)) {
[email protected]81375742012-06-08 00:04:008622 return;
8623 }
[email protected]f5719fb2010-08-04 18:27:188624
[email protected]9edc6b22010-12-23 02:00:268625 // Check we have compatible formats.
8626 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8627 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8628 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
8629
8630 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518631 LOCAL_SET_GL_ERROR(
8632 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268633 return;
8634 }
8635
[email protected]81375742012-06-08 00:04:008636 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518637 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008638 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:268639 "glCopyTexImage2D", "can not be used with depth or stencil textures");
8640 return;
8641 }
8642
8643 uint32 estimated_size = 0;
8644 if (!GLES2Util::ComputeImageDataSizes(
8645 width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment,
8646 &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518647 LOCAL_SET_GL_ERROR(
8648 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:268649 return;
8650 }
8651
8652 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:518653 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:008654 return;
8655 }
8656
[email protected]2ea5950d2014-07-09 18:20:348657 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexImage2D")) {
8658 return;
8659 }
8660
zmo383512cf2014-10-14 00:11:008661 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
8662 LOCAL_SET_GL_ERROR(
8663 GL_INVALID_OPERATION,
8664 "glCopyTexImage2D", "source and destination textures are the same");
8665 return;
8666 }
8667
[email protected]a0b78dc2011-11-11 10:43:108668 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
8669 return;
8670 }
8671
[email protected]ab09b612013-03-11 22:11:518672 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:278673 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038674 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:268675
[email protected]02965c22013-03-09 02:40:078676 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448677 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:468678 }
8679
[email protected]9edc6b22010-12-23 02:00:268680 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:038681 GLint copyX = 0;
8682 GLint copyY = 0;
8683 GLint copyWidth = 0;
8684 GLint copyHeight = 0;
8685 Clip(x, width, size.width(), &copyX, &copyWidth);
8686 Clip(y, height, size.height(), &copyY, &copyHeight);
8687
8688 if (copyX != x ||
8689 copyY != y ||
8690 copyWidth != width ||
8691 copyHeight != height) {
8692 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:208693 if (!ClearLevel(
[email protected]02965c22013-03-09 02:40:078694 texture->service_id(), texture->target(),
[email protected]d8e6c9242014-02-20 16:56:258695 target, level, internal_format, internal_format, GL_UNSIGNED_BYTE,
8696 width, height, texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:518697 LOCAL_SET_GL_ERROR(
8698 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:038699 return;
8700 }
[email protected]6e288612010-12-21 20:45:038701 if (copyHeight > 0 && copyWidth > 0) {
8702 GLint dx = copyX - x;
8703 GLint dy = copyY - y;
8704 GLint destX = dx;
8705 GLint destY = dy;
[email protected]00c2cf92014-03-14 00:08:378706 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038707 glCopyTexSubImage2D(target, level,
8708 destX, destY, copyX, copyY,
8709 copyWidth, copyHeight);
8710 }
8711 } else {
[email protected]00c2cf92014-03-14 00:08:378712 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038713 glCopyTexImage2D(target, level, internal_format,
8714 copyX, copyY, copyWidth, copyHeight, border);
8715 }
[email protected]ab09b612013-03-11 22:11:518716 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438717 if (error == GL_NO_ERROR) {
8718 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498719 texture_ref, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:208720 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:438721 }
vmiura8266ca72014-09-09 21:37:008722
8723 // This may be a slow command. Exit command processing to allow for
8724 // context preemption and GPU watchdog checks.
8725 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:438726}
8727
8728void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:448729 GLenum target,
8730 GLint level,
8731 GLint xoffset,
8732 GLint yoffset,
8733 GLint x,
8734 GLint y,
8735 GLsizei width,
8736 GLsizei height) {
[email protected]09e17272012-11-30 10:30:448737 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:448738 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8739 &state_, target);
[email protected]370eaf12013-05-18 09:19:498740 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518741 LOCAL_SET_GL_ERROR(
8742 GL_INVALID_OPERATION,
8743 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438744 return;
8745 }
[email protected]370eaf12013-05-18 09:19:498746 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438747 GLenum type = 0;
8748 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:078749 if (!texture->GetLevelType(target, level, &type, &format) ||
8750 !texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528751 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518752 LOCAL_SET_GL_ERROR(
8753 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438754 return;
8755 }
[email protected]85a4ac22013-05-31 01:58:478756 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518757 LOCAL_SET_GL_ERROR(
8758 GL_INVALID_OPERATION,
8759 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598760 return;
8761 }
[email protected]9edc6b22010-12-23 02:00:268762
8763 // Check we have compatible formats.
8764 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8765 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8766 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
8767
[email protected]2d3765b2012-10-03 00:31:078768 if (!channels_needed ||
8769 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518770 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438771 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268772 return;
8773 }
8774
[email protected]81375742012-06-08 00:04:008775 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518776 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008777 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438778 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:008779 return;
8780 }
8781
[email protected]2ea5950d2014-07-09 18:20:348782 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexSubImage2D")) {
8783 return;
8784 }
8785
zmo383512cf2014-10-14 00:11:008786 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
8787 LOCAL_SET_GL_ERROR(
8788 GL_INVALID_OPERATION,
8789 "glCopyTexSubImage2D", "source and destination textures are the same");
8790 return;
8791 }
8792
[email protected]a0b78dc2011-11-11 10:43:108793 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
8794 return;
8795 }
8796
[email protected]de26b3c2011-08-03 21:54:278797 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038798 gfx::Size size = GetBoundReadFrameBufferSize();
8799 GLint copyX = 0;
8800 GLint copyY = 0;
8801 GLint copyWidth = 0;
8802 GLint copyHeight = 0;
8803 Clip(x, width, size.width(), &copyX, &copyWidth);
8804 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:208805
[email protected]370eaf12013-05-18 09:19:498806 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, level)) {
[email protected]ab09b612013-03-11 22:11:518807 LOCAL_SET_GL_ERROR(
8808 GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big");
[email protected]0d6bfdc2011-11-02 01:32:208809 return;
8810 }
8811
[email protected]6e288612010-12-21 20:45:038812 if (copyX != x ||
8813 copyY != y ||
8814 copyWidth != width ||
8815 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:208816 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:038817 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:348818 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248819 width, height, format, type, state_.unpack_alignment, &pixels_size,
8820 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518821 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438822 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:038823 return;
8824 }
[email protected]40d90a22013-04-09 03:39:558825 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:038826 memset(zero.get(), 0, pixels_size);
[email protected]00c2cf92014-03-14 00:08:378827 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038828 glTexSubImage2D(
8829 target, level, xoffset, yoffset, width, height,
8830 format, type, zero.get());
8831 }
[email protected]0d6bfdc2011-11-02 01:32:208832
[email protected]6e288612010-12-21 20:45:038833 if (copyHeight > 0 && copyWidth > 0) {
8834 GLint dx = copyX - x;
8835 GLint dy = copyY - y;
8836 GLint destX = xoffset + dx;
8837 GLint destY = yoffset + dy;
[email protected]00c2cf92014-03-14 00:08:378838 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038839 glCopyTexSubImage2D(target, level,
8840 destX, destY, copyX, copyY,
8841 copyWidth, copyHeight);
8842 }
vmiura8266ca72014-09-09 21:37:008843
8844 // This may be a slow command. Exit command processing to allow for
8845 // context preemption and GPU watchdog checks.
8846 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:438847}
8848
[email protected]f598f422012-12-07 08:30:038849bool GLES2DecoderImpl::ValidateTexSubImage2D(
8850 error::Error* error,
8851 const char* function_name,
8852 GLenum target,
8853 GLint level,
8854 GLint xoffset,
8855 GLint yoffset,
8856 GLsizei width,
8857 GLsizei height,
8858 GLenum format,
8859 GLenum type,
8860 const void * data) {
8861 (*error) = error::kNoError;
8862 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518863 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:038864 return false;
8865 }
8866 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518867 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:038868 return false;
8869 }
8870 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518871 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:038872 return false;
8873 }
[email protected]c986af502013-08-14 01:04:448874 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8875 &state_, target);
[email protected]370eaf12013-05-18 09:19:498876 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518877 LOCAL_SET_GL_ERROR(
8878 GL_INVALID_OPERATION,
8879 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:038880 return false;
[email protected]cadde4a2010-07-31 17:10:438881 }
[email protected]370eaf12013-05-18 09:19:498882 Texture* texture = texture_ref->texture();
[email protected]df6cf1ad2011-01-29 01:20:528883 GLenum current_type = 0;
8884 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078885 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518886 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:038887 GL_INVALID_OPERATION, function_name, "level does not exist.");
8888 return false;
[email protected]df6cf1ad2011-01-29 01:20:528889 }
[email protected]17a961192014-02-14 15:20:528890 if (!texture_manager()->ValidateTextureParameters(state_.GetErrorState(),
8891 function_name, format, type, internal_format, level)) {
[email protected]f598f422012-12-07 08:30:038892 return false;
[email protected]df6cf1ad2011-01-29 01:20:528893 }
8894 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:518895 LOCAL_SET_GL_ERROR(
8896 GL_INVALID_OPERATION,
8897 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:038898 return false;
[email protected]df6cf1ad2011-01-29 01:20:528899 }
[email protected]85a4ac22013-05-31 01:58:478900 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518901 LOCAL_SET_GL_ERROR(
8902 GL_INVALID_OPERATION,
8903 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598904 return false;
8905 }
[email protected]02965c22013-03-09 02:40:078906 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528907 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518908 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:038909 return false;
[email protected]cadde4a2010-07-31 17:10:438910 }
[email protected]81375742012-06-08 00:04:008911 if ((GLES2Util::GetChannelsForFormat(format) &
8912 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518913 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008914 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038915 function_name, "can not supply data for depth or stencil textures");
8916 return false;
[email protected]81375742012-06-08 00:04:008917 }
[email protected]f598f422012-12-07 08:30:038918 if (data == NULL) {
8919 (*error) = error::kOutOfBounds;
8920 return false;
8921 }
8922 return true;
8923}
[email protected]81375742012-06-08 00:04:008924
[email protected]f598f422012-12-07 08:30:038925error::Error GLES2DecoderImpl::DoTexSubImage2D(
8926 GLenum target,
8927 GLint level,
8928 GLint xoffset,
8929 GLint yoffset,
8930 GLsizei width,
8931 GLsizei height,
8932 GLenum format,
8933 GLenum type,
8934 const void * data) {
8935 error::Error error = error::kNoError;
8936 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
8937 xoffset, yoffset, width, height, format, type, data)) {
8938 return error;
8939 }
[email protected]c986af502013-08-14 01:04:448940 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8941 &state_, target);
[email protected]370eaf12013-05-18 09:19:498942 Texture* texture = texture_ref->texture();
[email protected]4502e6492011-12-14 19:39:158943 GLsizei tex_width = 0;
8944 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:078945 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:158946 DCHECK(ok);
8947 if (xoffset != 0 || yoffset != 0 ||
8948 width != tex_width || height != tex_height) {
[email protected]370eaf12013-05-18 09:19:498949 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
8950 target, level)) {
[email protected]ab09b612013-03-11 22:11:518951 LOCAL_SET_GL_ERROR(
8952 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:038953 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:308954 }
[email protected]c986af502013-08-14 01:04:448955 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:158956 glTexSubImage2D(
8957 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:038958 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:208959 }
[email protected]4502e6492011-12-14 19:39:158960
[email protected]345ba902013-11-14 21:39:008961 if (!texture_state_.texsubimage2d_faster_than_teximage2d &&
[email protected]c986af502013-08-14 01:04:448962 !texture->IsImmutable()) {
8963 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]d8e6c9242014-02-20 16:56:258964 GLenum internal_format;
8965 GLenum tex_type;
8966 texture->GetLevelType(target, level, &tex_type, &internal_format);
8967 // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need
8968 // to look it up.
[email protected]8f1d2aa2013-05-10 23:45:388969 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:258970 target, level, internal_format, width, height, 0, format, type, data);
[email protected]4502e6492011-12-14 19:39:158971 } else {
[email protected]c986af502013-08-14 01:04:448972 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:158973 glTexSubImage2D(
8974 target, level, xoffset, yoffset, width, height, format, type, data);
8975 }
[email protected]370eaf12013-05-18 09:19:498976 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
vmiura8266ca72014-09-09 21:37:008977
8978 // This may be a slow command. Exit command processing to allow for
8979 // context preemption and GPU watchdog checks.
8980 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:038981 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:438982}
8983
vmiuracd108592014-09-08 14:36:348984error::Error GLES2DecoderImpl::HandleTexSubImage2D(uint32 immediate_data_size,
8985 const void* cmd_data) {
8986 const gles2::cmds::TexSubImage2D& c =
8987 *static_cast<const gles2::cmds::TexSubImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:138988 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage2D",
8989 "width", c.width, "height", c.height);
[email protected]b493ee622011-04-13 23:52:008990 GLboolean internal = static_cast<GLboolean>(c.internal);
[email protected]c986af502013-08-14 01:04:448991 if (internal == GL_TRUE && texture_state_.tex_image_2d_failed)
[email protected]b493ee622011-04-13 23:52:008992 return error::kNoError;
8993
8994 GLenum target = static_cast<GLenum>(c.target);
8995 GLint level = static_cast<GLint>(c.level);
8996 GLint xoffset = static_cast<GLint>(c.xoffset);
8997 GLint yoffset = static_cast<GLint>(c.yoffset);
8998 GLsizei width = static_cast<GLsizei>(c.width);
8999 GLsizei height = static_cast<GLsizei>(c.height);
9000 GLenum format = static_cast<GLenum>(c.format);
9001 GLenum type = static_cast<GLenum>(c.type);
9002 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:349003 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:249004 width, height, format, type, state_.unpack_alignment, &data_size,
9005 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:009006 return error::kOutOfBounds;
9007 }
9008 const void* pixels = GetSharedMemoryAs<const void*>(
9009 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:039010 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:009011 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:009012}
9013
[email protected]f7a64ee2010-02-01 22:24:149014error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
vmiuracd108592014-09-08 14:36:349015 uint32 immediate_data_size,
9016 const void* cmd_data) {
9017 const gles2::cmds::GetVertexAttribPointerv& c =
9018 *static_cast<const gles2::cmds::GetVertexAttribPointerv*>(cmd_data);
[email protected]8bf5a3e2010-01-29 04:21:369019 GLuint index = static_cast<GLuint>(c.index);
9020 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:359021 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:259022 Result* result = GetSharedMemoryAs<Result*>(
9023 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:369024 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:149025 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:369026 }
[email protected]07d0cc82010-02-17 04:51:409027 // Check that the client initialized the result.
9028 if (result->size != 0) {
9029 return error::kInvalidArguments;
9030 }
[email protected]9438b012010-06-15 22:55:059031 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:519032 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9033 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:149034 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369035 }
[email protected]3916c97e2010-02-25 03:20:509036 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:519037 LOCAL_SET_GL_ERROR(
9038 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:149039 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369040 }
[email protected]0bfd9882010-02-05 23:02:259041 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:089042 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:359043 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:149044 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329045}
9046
[email protected]f7b85372010-02-03 01:11:379047bool GLES2DecoderImpl::GetUniformSetup(
[email protected]df37b9932013-03-08 05:21:429048 GLuint program_id, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:379049 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:129050 error::Error* error, GLint* real_location,
9051 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:109052 DCHECK(error);
9053 DCHECK(service_id);
9054 DCHECK(result_pointer);
9055 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:129056 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:379057 *error = error::kNoError;
9058 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:259059 SizedResult<GLint>* result;
9060 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9061 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
9062 if (!result) {
[email protected]f7b85372010-02-03 01:11:379063 *error = error::kOutOfBounds;
9064 return false;
9065 }
[email protected]0bfd9882010-02-05 23:02:259066 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:379067 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:259068 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:429069 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
9070 if (!program) {
[email protected]ae51d192010-04-27 00:48:039071 return false;
9072 }
[email protected]df37b9932013-03-08 05:21:429073 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:379074 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:519075 LOCAL_SET_GL_ERROR(
9076 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:379077 return false;
9078 }
[email protected]df37b9932013-03-08 05:21:429079 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:369080 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:359081 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:429082 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:129083 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:369084 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:379085 // No such location.
[email protected]ab09b612013-03-11 22:11:519086 LOCAL_SET_GL_ERROR(
9087 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:379088 return false;
9089 }
[email protected]43c2f1f2011-03-25 18:35:369090 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:509091 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:379092 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:519093 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:379094 return false;
9095 }
[email protected]0bfd9882010-02-05 23:02:259096 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9097 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
9098 if (!result) {
[email protected]f7b85372010-02-03 01:11:379099 *error = error::kOutOfBounds;
9100 return false;
9101 }
[email protected]0bfd9882010-02-05 23:02:259102 result->size = size;
[email protected]939e7362010-05-13 20:49:109103 *result_type = type;
[email protected]f7b85372010-02-03 01:11:379104 return true;
9105}
9106
vmiuracd108592014-09-08 14:36:349107error::Error GLES2DecoderImpl::HandleGetUniformiv(uint32 immediate_data_size,
9108 const void* cmd_data) {
9109 const gles2::cmds::GetUniformiv& c =
9110 *static_cast<const gles2::cmds::GetUniformiv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379111 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339112 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379113 GLuint service_id;
[email protected]939e7362010-05-13 20:49:109114 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:129115 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379116 Error error;
[email protected]0bfd9882010-02-05 23:02:259117 void* result;
[email protected]f7b85372010-02-03 01:11:379118 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:129119 program, fake_location, c.params_shm_id, c.params_shm_offset,
9120 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:259121 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:129122 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:359123 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:379124 }
9125 return error;
[email protected]96449d2c2009-11-25 00:01:329126}
9127
vmiuracd108592014-09-08 14:36:349128error::Error GLES2DecoderImpl::HandleGetUniformfv(uint32 immediate_data_size,
9129 const void* cmd_data) {
9130 const gles2::cmds::GetUniformfv& c =
9131 *static_cast<const gles2::cmds::GetUniformfv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379132 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339133 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379134 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:129135 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379136 Error error;
[email protected]ed9f9cd2013-02-27 21:12:359137 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:109138 Result* result;
9139 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:379140 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:129141 program, fake_location, c.params_shm_id, c.params_shm_offset,
9142 &error, &real_location, &service_id,
9143 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:109144 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
9145 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
9146 GLsizei num_values = result->GetNumResults();
[email protected]40d90a22013-04-09 03:39:559147 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:129148 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:109149 GLfloat* dst = result->GetData();
9150 for (GLsizei ii = 0; ii < num_values; ++ii) {
9151 dst[ii] = (temp[ii] != 0);
9152 }
9153 } else {
[email protected]1b0a6752012-02-22 03:44:129154 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:109155 }
[email protected]f7b85372010-02-03 01:11:379156 }
9157 return error;
[email protected]96449d2c2009-11-25 00:01:329158}
9159
[email protected]f7a64ee2010-02-01 22:24:149160error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
vmiuracd108592014-09-08 14:36:349161 uint32 immediate_data_size,
9162 const void* cmd_data) {
9163 const gles2::cmds::GetShaderPrecisionFormat& c =
9164 *static_cast<const gles2::cmds::GetShaderPrecisionFormat*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259165 GLenum shader_type = static_cast<GLenum>(c.shadertype);
9166 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:359167 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:259168 Result* result = GetSharedMemoryAs<Result*>(
9169 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9170 if (!result) {
9171 return error::kOutOfBounds;
9172 }
[email protected]07d0cc82010-02-17 04:51:409173 // Check that the client initialized the result.
9174 if (result->success != 0) {
9175 return error::kInvalidArguments;
9176 }
[email protected]9438b012010-06-15 22:55:059177 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:519178 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539179 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:299180 return error::kNoError;
9181 }
[email protected]9438b012010-06-15 22:55:059182 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:519183 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539184 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:299185 return error::kNoError;
9186 }
9187
9188 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:409189
[email protected]46c86752013-05-21 05:08:399190 GLint range[2] = { 0, 0 };
[email protected]d8bc3ec2013-03-07 06:28:409191 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:219192 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:409193
9194 result->min_range = range[0];
9195 result->max_range = range[1];
9196 result->precision = precision;
9197
[email protected]f7a64ee2010-02-01 22:24:149198 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329199}
9200
[email protected]f7a64ee2010-02-01 22:24:149201error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
vmiuracd108592014-09-08 14:36:349202 uint32 immediate_data_size,
9203 const void* cmd_data) {
9204 const gles2::cmds::GetAttachedShaders& c =
9205 *static_cast<const gles2::cmds::GetAttachedShaders*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259206 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:429207 GLuint program_id = static_cast<GLuint>(c.program);
9208 Program* program = GetProgramInfoNotShader(
9209 program_id, "glGetAttachedShaders");
9210 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259211 return error::kNoError;
9212 }
[email protected]ed9f9cd2013-02-27 21:12:359213 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:259214 uint32 max_count = Result::ComputeMaxResults(result_size);
9215 Result* result = GetSharedMemoryAs<Result*>(
9216 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
9217 if (!result) {
9218 return error::kOutOfBounds;
9219 }
[email protected]07d0cc82010-02-17 04:51:409220 // Check that the client initialized the result.
9221 if (result->size != 0) {
9222 return error::kInvalidArguments;
9223 }
[email protected]0bfd9882010-02-05 23:02:259224 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:039225 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:429226 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:259227 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:039228 if (!shader_manager()->GetClientId(result->GetData()[ii],
9229 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:259230 NOTREACHED();
9231 return error::kGenericError;
9232 }
9233 }
9234 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:149235 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329236}
9237
[email protected]f7a64ee2010-02-01 22:24:149238error::Error GLES2DecoderImpl::HandleGetActiveUniform(
vmiuracd108592014-09-08 14:36:349239 uint32 immediate_data_size,
9240 const void* cmd_data) {
9241 const gles2::cmds::GetActiveUniform& c =
9242 *static_cast<const gles2::cmds::GetActiveUniform*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429243 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:259244 GLuint index = c.index;
9245 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:359246 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:259247 Result* result = GetSharedMemoryAs<Result*>(
9248 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9249 if (!result) {
9250 return error::kOutOfBounds;
9251 }
[email protected]07d0cc82010-02-17 04:51:409252 // Check that the client initialized the result.
9253 if (result->success != 0) {
9254 return error::kInvalidArguments;
9255 }
[email protected]df37b9932013-03-08 05:21:429256 Program* program = GetProgramInfoNotShader(
9257 program_id, "glGetActiveUniform");
9258 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259259 return error::kNoError;
9260 }
[email protected]ed9f9cd2013-02-27 21:12:359261 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:429262 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:259263 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:519264 LOCAL_SET_GL_ERROR(
9265 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:259266 return error::kNoError;
9267 }
9268 result->success = 1; // true.
9269 result->size = uniform_info->size;
9270 result->type = uniform_info->type;
9271 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:299272 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:149273 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329274}
9275
vmiuracd108592014-09-08 14:36:349276error::Error GLES2DecoderImpl::HandleGetActiveAttrib(uint32 immediate_data_size,
9277 const void* cmd_data) {
9278 const gles2::cmds::GetActiveAttrib& c =
9279 *static_cast<const gles2::cmds::GetActiveAttrib*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429280 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:259281 GLuint index = c.index;
9282 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:359283 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:259284 Result* result = GetSharedMemoryAs<Result*>(
9285 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9286 if (!result) {
9287 return error::kOutOfBounds;
9288 }
[email protected]07d0cc82010-02-17 04:51:409289 // Check that the client initialized the result.
9290 if (result->success != 0) {
9291 return error::kInvalidArguments;
9292 }
[email protected]df37b9932013-03-08 05:21:429293 Program* program = GetProgramInfoNotShader(
9294 program_id, "glGetActiveAttrib");
9295 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259296 return error::kNoError;
9297 }
[email protected]ed9f9cd2013-02-27 21:12:359298 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:429299 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:259300 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:519301 LOCAL_SET_GL_ERROR(
9302 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:259303 return error::kNoError;
9304 }
9305 result->success = 1; // true.
9306 result->size = attrib_info->size;
9307 result->type = attrib_info->type;
9308 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:299309 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:149310 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329311}
9312
vmiuracd108592014-09-08 14:36:349313error::Error GLES2DecoderImpl::HandleShaderBinary(uint32 immediate_data_size,
9314 const void* cmd_data) {
[email protected]b273e432010-04-12 17:23:589315#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:519316 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:589317 return error::kNoError;
9318#else
9319 GLsizei n = static_cast<GLsizei>(c.n);
9320 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:519321 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:589322 return error::kNoError;
9323 }
9324 GLsizei length = static_cast<GLsizei>(c.length);
9325 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:519326 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:589327 return error::kNoError;
9328 }
9329 uint32 data_size;
9330 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
9331 return error::kOutOfBounds;
9332 }
9333 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
9334 c.shaders_shm_id, c.shaders_shm_offset, data_size);
9335 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
9336 const void* binary = GetSharedMemoryAs<const void*>(
9337 c.binary_shm_id, c.binary_shm_offset, length);
9338 if (shaders == NULL || binary == NULL) {
9339 return error::kOutOfBounds;
9340 }
[email protected]0782b14b2014-05-24 13:04:169341 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]b273e432010-04-12 17:23:589342 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:429343 Shader* shader = GetShader(shaders[ii]);
9344 if (!shader) {
[email protected]ab09b612013-03-11 22:11:519345 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:589346 return error::kNoError;
9347 }
[email protected]df37b9932013-03-08 05:21:429348 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:589349 }
9350 // TODO(gman): call glShaderBinary
9351 return error::kNoError;
9352#endif
9353}
9354
[email protected]6d792ee12013-05-15 00:40:569355void GLES2DecoderImpl::DoSwapBuffers() {
[email protected]64ace852011-05-19 21:49:499356 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:089357
[email protected]64ace852011-05-19 21:49:499358 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:429359 // TRACE_EVENT for gpu tests:
9360 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:429361 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:429362 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
9363 "width", (is_offscreen ? offscreen_size_.width() :
9364 surface_->GetSize().width()));
[email protected]6d792ee12013-05-15 00:40:569365 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
[email protected]64ace852011-05-19 21:49:499366 "offscreen", is_offscreen,
9367 "frame", this_frame_number);
[email protected]b2e92592014-01-10 15:47:159368 {
[email protected]a36ed4832014-04-24 16:40:279369 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
[email protected]b2e92592014-01-10 15:47:159370 }
9371
[email protected]8f9b8dd2013-09-12 18:05:139372 bool is_tracing;
9373 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
9374 &is_tracing);
9375 if (is_tracing) {
9376 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
9377 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
9378 is_offscreen ? offscreen_size_ : surface_->GetSize());
9379 }
9380
[email protected]6217d392010-03-25 22:08:359381 // If offscreen then don't actually SwapBuffers to the display. Just copy
9382 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:499383 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:319384 TRACE_EVENT2("gpu", "Offscreen",
9385 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:539386 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
9387 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
9388 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
9389 // fix this.
[email protected]62e155e2012-10-23 22:43:159390 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:539391 offscreen_saved_frame_buffer_->Create();
9392 glFinish();
9393 }
9394
9395 // Allocate the offscreen saved color texture.
9396 DCHECK(offscreen_saved_color_format_);
9397 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:099398 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:539399
9400 offscreen_saved_frame_buffer_->AttachRenderTexture(
9401 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:059402 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
9403 if (offscreen_saved_frame_buffer_->CheckStatus() !=
9404 GL_FRAMEBUFFER_COMPLETE) {
9405 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
9406 << "because offscreen saved FBO was incomplete.";
[email protected]6d792ee12013-05-15 00:40:569407 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
9408 return;
[email protected]f0cfe752013-01-14 01:09:059409 }
[email protected]1fb8c482011-08-31 01:01:539410
[email protected]f0cfe752013-01-14 01:09:059411 // Clear the offscreen color texture.
9412 // TODO(piman): Is this still necessary?
9413 {
9414 ScopedFrameBufferBinder binder(this,
9415 offscreen_saved_frame_buffer_->id());
9416 glClearColor(0, 0, 0, 0);
[email protected]454157e2014-05-03 02:49:459417 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
9418 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f0cfe752013-01-14 01:09:059419 glClear(GL_COLOR_BUFFER_BIT);
9420 RestoreClearState();
9421 }
[email protected]1fb8c482011-08-31 01:01:539422 }
9423
9424 UpdateParentTextureInfo();
9425 }
9426
[email protected]f0cfe752013-01-14 01:09:059427 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
[email protected]6d792ee12013-05-15 00:40:569428 return;
[email protected]ab09b612013-03-11 22:11:519429 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:309430 "GLES2DecoderImpl::DoSwapBuffers", GetErrorState());
[email protected]6217d392010-03-25 22:08:359431
[email protected]34ff8b0c2010-10-01 20:06:029432 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:139433 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:279434 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]b86b14982010-10-11 18:45:489435 } else {
[email protected]069944672012-04-25 20:52:239436 ScopedFrameBufferBinder binder(this,
9437 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:139438
[email protected]069944672012-04-25 20:52:239439 if (offscreen_target_buffer_preserved_) {
9440 // Copy the target frame buffer to the saved offscreen texture.
9441 offscreen_saved_color_texture_->Copy(
9442 offscreen_saved_color_texture_->size(),
9443 offscreen_saved_color_format_);
9444 } else {
9445 // Flip the textures in the parent context via the texture manager.
9446 if (!!offscreen_saved_color_texture_info_.get())
[email protected]370eaf12013-05-18 09:19:499447 offscreen_saved_color_texture_info_->texture()->
[email protected]069944672012-04-25 20:52:239448 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:569449
[email protected]069944672012-04-25 20:52:239450 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
9451 offscreen_target_frame_buffer_->AttachRenderTexture(
9452 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:489453 }
[email protected]069944672012-04-25 20:52:239454
9455 // Ensure the side effects of the copy are visible to the parent
9456 // context. There is no need to do this for ANGLE because it uses a
9457 // single D3D device for all contexts.
[email protected]f42f05b2013-11-15 21:46:189458 if (!feature_info_->feature_flags().is_angle)
[email protected]069944672012-04-25 20:52:239459 glFlush();
[email protected]0c8c9d22010-06-25 17:36:399460 }
[email protected]6217d392010-03-25 22:08:359461 } else {
[email protected]f62a5ab2011-05-23 20:34:159462 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:019463 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]6d792ee12013-05-15 00:40:569464 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]d0498742010-09-20 20:27:019465 }
[email protected]6217d392010-03-25 22:08:359466 }
vmiura8266ca72014-09-09 21:37:009467
9468 // This may be a slow command. Exit command processing to allow for
9469 // context preemption and GPU watchdog checks.
9470 ExitCommandProcessingEarly();
[email protected]6217d392010-03-25 22:08:359471}
9472
[email protected]d4239852011-08-12 04:51:229473error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
vmiuracd108592014-09-08 14:36:349474 uint32 immediate_data_size,
9475 const void* cmd_data) {
9476 const gles2::cmds::EnableFeatureCHROMIUM& c =
9477 *static_cast<const gles2::cmds::EnableFeatureCHROMIUM*>(cmd_data);
[email protected]b1d2dcb2010-05-17 19:24:189478 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289479 if (!bucket || bucket->size() == 0) {
9480 return error::kInvalidArguments;
9481 }
[email protected]ed9f9cd2013-02-27 21:12:359482 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:189483 Result* result = GetSharedMemoryAs<Result*>(
9484 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9485 if (!result) {
9486 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:109487 }
[email protected]b1d2dcb2010-05-17 19:24:189488 // Check that the client initialized the result.
9489 if (*result != 0) {
9490 return error::kInvalidArguments;
9491 }
9492 std::string feature_str;
9493 if (!bucket->GetAsString(&feature_str)) {
9494 return error::kInvalidArguments;
9495 }
9496
9497 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:229498 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:189499 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:229500 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
[email protected]8fbedc02010-11-18 18:43:409501 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
9502 // TODO(gman): decide how to remove the need for this const_cast.
9503 // I could make validators_ non const but that seems bad as this is the only
9504 // place it is needed. I could make some special friend class of validators
9505 // just to allow this to set them. That seems silly. I could refactor this
9506 // code to use the extension mechanism or the initialization attributes to
9507 // turn this feature on. Given that the only real point of this is to make
9508 // the conformance tests pass and given that there is lots of real work that
9509 // needs to be done it seems like refactoring for one to one of those
9510 // methods is a very low priority.
9511 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:049512 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
9513 force_webgl_glsl_validation_ = true;
9514 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:189515 } else {
9516 return error::kNoError;
9517 }
9518
9519 *result = 1; // true.
9520 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:109521}
9522
[email protected]c2f8c8402010-12-06 18:07:249523error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
9524 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:349525 const void* cmd_data) {
9526 const gles2::cmds::GetRequestableExtensionsCHROMIUM& c =
9527 *static_cast<const gles2::cmds::GetRequestableExtensionsCHROMIUM*>(
9528 cmd_data);
[email protected]c2f8c8402010-12-06 18:07:249529 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:359530 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]956aec52013-09-05 15:41:199531 info->Initialize(disallowed_features_);
[email protected]c2f8c8402010-12-06 18:07:249532 bucket->SetFromString(info->extensions().c_str());
9533 return error::kNoError;
9534}
9535
9536error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
vmiuracd108592014-09-08 14:36:349537 uint32 immediate_data_size,
9538 const void* cmd_data) {
9539 const gles2::cmds::RequestExtensionCHROMIUM& c =
9540 *static_cast<const gles2::cmds::RequestExtensionCHROMIUM*>(cmd_data);
[email protected]c2f8c8402010-12-06 18:07:249541 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289542 if (!bucket || bucket->size() == 0) {
9543 return error::kInvalidArguments;
9544 }
[email protected]c2f8c8402010-12-06 18:07:249545 std::string feature_str;
9546 if (!bucket->GetAsString(&feature_str)) {
9547 return error::kInvalidArguments;
9548 }
9549
[email protected]4b7eba92013-01-08 02:23:569550 bool desire_webgl_glsl_validation =
9551 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
9552 bool desire_standard_derivatives = false;
[email protected]70dc60932013-06-04 03:33:499553 bool desire_frag_depth = false;
[email protected]aff39ac82013-06-08 04:53:139554 bool desire_draw_buffers = false;
[email protected]93c2fd82014-04-16 02:46:069555 bool desire_shader_texture_lod = false;
[email protected]4b7eba92013-01-08 02:23:569556 if (force_webgl_glsl_validation_) {
9557 desire_standard_derivatives =
9558 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]70dc60932013-06-04 03:33:499559 desire_frag_depth =
9560 feature_str.find("GL_EXT_frag_depth") != std::string::npos;
[email protected]aff39ac82013-06-08 04:53:139561 desire_draw_buffers =
9562 feature_str.find("GL_EXT_draw_buffers") != std::string::npos;
[email protected]93c2fd82014-04-16 02:46:069563 desire_shader_texture_lod =
9564 feature_str.find("GL_EXT_shader_texture_lod") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:049565 }
9566
[email protected]4b7eba92013-01-08 02:23:569567 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
[email protected]70dc60932013-06-04 03:33:499568 desire_standard_derivatives != derivatives_explicitly_enabled_ ||
[email protected]aff39ac82013-06-08 04:53:139569 desire_frag_depth != frag_depth_explicitly_enabled_ ||
9570 desire_draw_buffers != draw_buffers_explicitly_enabled_) {
[email protected]70dc60932013-06-04 03:33:499571 force_webgl_glsl_validation_ |= desire_webgl_glsl_validation;
9572 derivatives_explicitly_enabled_ |= desire_standard_derivatives;
9573 frag_depth_explicitly_enabled_ |= desire_frag_depth;
[email protected]aff39ac82013-06-08 04:53:139574 draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
[email protected]93c2fd82014-04-16 02:46:069575 shader_texture_lod_explicitly_enabled_ |= desire_shader_texture_lod;
[email protected]c2f8c8402010-12-06 18:07:249576 InitializeShaderTranslator();
9577 }
9578
[email protected]302ce6d2011-07-07 23:28:119579 UpdateCapabilities();
9580
[email protected]c2f8c8402010-12-06 18:07:249581 return error::kNoError;
9582}
9583
[email protected]372e0412011-06-28 16:08:569584error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
vmiuracd108592014-09-08 14:36:349585 uint32 immediate_data_size,
9586 const void* cmd_data) {
9587 const gles2::cmds::GetMultipleIntegervCHROMIUM& c =
9588 *static_cast<const gles2::cmds::GetMultipleIntegervCHROMIUM*>(cmd_data);
[email protected]372e0412011-06-28 16:08:569589 GLuint count = c.count;
9590 uint32 pnames_size;
9591 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
9592 return error::kOutOfBounds;
9593 }
9594 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>(
9595 c.pnames_shm_id, c.pnames_shm_offset, pnames_size);
9596 if (pnames == NULL) {
9597 return error::kOutOfBounds;
9598 }
9599
9600 // We have to copy them since we use them twice so the client
9601 // can't change them between the time we validate them and the time we use
9602 // them.
[email protected]40d90a22013-04-09 03:39:559603 scoped_ptr<GLenum[]> enums(new GLenum[count]);
[email protected]372e0412011-06-28 16:08:569604 memcpy(enums.get(), pnames, pnames_size);
9605
9606 // Count up the space needed for the result.
9607 uint32 num_results = 0;
9608 for (GLuint ii = 0; ii < count; ++ii) {
9609 uint32 num = util_.GLGetNumValuesReturned(enums[ii]);
9610 if (num == 0) {
[email protected]ab09b612013-03-11 22:11:519611 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]caa13ed2014-02-17 11:29:209612 "glGetMultipleCHROMIUM", enums[ii], "pname");
[email protected]372e0412011-06-28 16:08:569613 return error::kNoError;
9614 }
9615 // Num will never be more than 4.
9616 DCHECK_LE(num, 4u);
[email protected]3aad1a32012-09-07 20:54:479617 if (!SafeAddUint32(num_results, num, &num_results)) {
[email protected]372e0412011-06-28 16:08:569618 return error::kOutOfBounds;
9619 }
9620 }
9621
9622 uint32 result_size = 0;
9623 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) {
9624 return error::kOutOfBounds;
9625 }
9626
9627 if (result_size != static_cast<uint32>(c.size)) {
[email protected]ab09b612013-03-11 22:11:519628 LOCAL_SET_GL_ERROR(
9629 GL_INVALID_VALUE,
[email protected]caa13ed2014-02-17 11:29:209630 "glGetMultipleCHROMIUM", "bad size GL_INVALID_VALUE");
[email protected]372e0412011-06-28 16:08:569631 return error::kNoError;
9632 }
9633
9634 GLint* results = GetSharedMemoryAs<GLint*>(
9635 c.results_shm_id, c.results_shm_offset, result_size);
9636 if (results == NULL) {
9637 return error::kOutOfBounds;
9638 }
9639
9640 // Check the results have been cleared in case the context was lost.
9641 for (uint32 ii = 0; ii < num_results; ++ii) {
9642 if (results[ii]) {
9643 return error::kInvalidArguments;
9644 }
9645 }
9646
9647 // Get each result.
9648 GLint* start = results;
9649 for (GLuint ii = 0; ii < count; ++ii) {
9650 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:269651 if (!state_.GetStateAsGLint(enums[ii], results, &num_written) &&
[email protected]f63b1232012-10-31 07:03:539652 !GetHelper(enums[ii], results, &num_written)) {
[email protected]b0ce0982013-05-13 18:51:489653 DoGetIntegerv(enums[ii], results);
[email protected]372e0412011-06-28 16:08:569654 }
9655 results += num_written;
9656 }
9657
9658 // Just to verify. Should this be a DCHECK?
9659 if (static_cast<uint32>(results - start) != num_results) {
9660 return error::kOutOfBounds;
9661 }
9662
9663 return error::kNoError;
9664}
9665
[email protected]2318d342011-07-11 22:27:429666error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
vmiuracd108592014-09-08 14:36:349667 uint32 immediate_data_size,
9668 const void* cmd_data) {
9669 const gles2::cmds::GetProgramInfoCHROMIUM& c =
9670 *static_cast<const gles2::cmds::GetProgramInfoCHROMIUM*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429671 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:429672 uint32 bucket_id = c.bucket_id;
9673 Bucket* bucket = CreateBucket(bucket_id);
9674 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:429675 Program* program = NULL;
9676 program = GetProgram(program_id);
9677 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:469678 return error::kNoError;
[email protected]2318d342011-07-11 22:27:429679 }
[email protected]df37b9932013-03-08 05:21:429680 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:429681 return error::kNoError;
9682}
9683
[email protected]38d139d2011-07-14 00:38:439684error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
9685 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:439686 case GL_NO_ERROR:
9687 // TODO(kbr): improve the precision of the error code in this case.
9688 // Consider delegating to context for error code if MakeCurrent fails.
9689 return error::kUnknown;
9690 case GL_GUILTY_CONTEXT_RESET_ARB:
9691 return error::kGuilty;
9692 case GL_INNOCENT_CONTEXT_RESET_ARB:
9693 return error::kInnocent;
9694 case GL_UNKNOWN_CONTEXT_RESET_ARB:
9695 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:439696 }
9697
9698 NOTREACHED();
9699 return error::kUnknown;
9700}
9701
jbauman7a059312014-10-16 19:30:549702void GLES2DecoderImpl::MaybeExitOnContextLost() {
9703 // Some D3D drivers cannot recover from device lost in the GPU process
9704 // sandbox. Allow a new GPU process to launch.
9705 if (workarounds().exit_on_context_lost) {
9706 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
9707 << " a D3D device in the Chrome GPU process sandbox.";
9708#if defined(OS_WIN)
9709 base::win::SetShouldCrashOnProcessDetach(false);
9710#endif
9711 exit(0);
9712 }
9713}
9714
[email protected]38d139d2011-07-14 00:38:439715bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:099716 if (reset_status_ != GL_NO_ERROR) {
jbauman7a059312014-10-16 19:30:549717 MaybeExitOnContextLost();
[email protected]c4485aad62012-12-17 10:19:099718 return true;
9719 }
[email protected]706b69f2012-07-27 04:59:309720 if (context_->WasAllocatedUsingRobustnessExtension()) {
9721 GLenum status = GL_NO_ERROR;
9722 if (has_robustness_extension_)
9723 status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:439724 if (status != GL_NO_ERROR) {
9725 // The graphics card was reset. Signal a lost context to the application.
9726 reset_status_ = status;
[email protected]93a7d98f2013-07-11 00:04:229727 reset_by_robustness_extension_ = true;
[email protected]38d139d2011-07-14 00:38:439728 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:099729 << " context lost via ARB/EXT_robustness. Reset status = "
9730 << GLES2Util::GetStringEnum(status);
jbauman7a059312014-10-16 19:30:549731 MaybeExitOnContextLost();
[email protected]38d139d2011-07-14 00:38:439732 return true;
9733 }
9734 }
9735 return false;
9736}
9737
[email protected]93a7d98f2013-07-11 00:04:229738bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() {
9739 return WasContextLost() && reset_by_robustness_extension_;
9740}
9741
[email protected]c4485aad62012-12-17 10:19:099742void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
9743 // Only loses the context once.
9744 if (reset_status_ != GL_NO_ERROR) {
9745 return;
9746 }
9747
9748 // Marks this context as lost.
9749 reset_status_ = reset_status;
9750 current_decoder_error_ = error::kLostContext;
[email protected]c4485aad62012-12-17 10:19:099751}
9752
[email protected]b096d032013-03-08 03:08:019753error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:349754 uint32 immediate_data_size,
9755 const void* cmd_data) {
[email protected]b096d032013-03-08 03:08:019756 return error::kUnknownCommand;
9757}
9758
[email protected]840a7e462013-02-27 01:29:519759error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:349760 uint32 immediate_data_size,
9761 const void* cmd_data) {
9762 const gles2::cmds::WaitSyncPointCHROMIUM& c =
9763 *static_cast<const gles2::cmds::WaitSyncPointCHROMIUM*>(cmd_data);
[email protected]00c2cf92014-03-14 00:08:379764 group_->mailbox_manager()->PullTextureUpdates();
[email protected]840a7e462013-02-27 01:29:519765 if (wait_sync_point_callback_.is_null())
9766 return error::kNoError;
9767
9768 return wait_sync_point_callback_.Run(c.sync_point) ?
9769 error::kNoError : error::kDeferCommandUntilLater;
9770}
9771
[email protected]5dfc457b2013-12-13 11:13:079772error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM(
vmiuracd108592014-09-08 14:36:349773 uint32 immediate_data_size,
9774 const void* cmd_data) {
[email protected]5dfc457b2013-12-13 11:13:079775 if (surface_->DeferDraws())
9776 return error::kDeferCommandUntilLater;
9777 if (!surface_->SetBackbufferAllocation(false))
9778 return error::kLostContext;
9779 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
9780 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
9781 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
9782 return error::kNoError;
9783}
9784
[email protected]882ba1e22012-03-08 19:02:539785bool GLES2DecoderImpl::GenQueriesEXTHelper(
9786 GLsizei n, const GLuint* client_ids) {
9787 for (GLsizei ii = 0; ii < n; ++ii) {
9788 if (query_manager_->GetQuery(client_ids[ii])) {
9789 return false;
9790 }
9791 }
[email protected]4eea7e62014-04-22 21:14:439792 query_manager_->GenQueries(n, client_ids);
[email protected]882ba1e22012-03-08 19:02:539793 return true;
9794}
9795
9796void GLES2DecoderImpl::DeleteQueriesEXTHelper(
9797 GLsizei n, const GLuint* client_ids) {
9798 for (GLsizei ii = 0; ii < n; ++ii) {
9799 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
9800 if (query && !query->IsDeleted()) {
[email protected]8ebd46c2014-01-08 12:06:139801 ContextState::QueryMap::iterator it =
9802 state_.current_queries.find(query->target());
9803 if (it != state_.current_queries.end())
9804 state_.current_queries.erase(it);
9805
[email protected]c45f1972012-03-14 07:27:369806 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:539807 }
[email protected]4eea7e62014-04-22 21:14:439808 query_manager_->RemoveQuery(client_ids[ii]);
[email protected]882ba1e22012-03-08 19:02:539809 }
9810}
9811
[email protected]22e3f552012-03-13 01:54:199812bool GLES2DecoderImpl::ProcessPendingQueries() {
9813 if (query_manager_.get() == NULL) {
9814 return false;
9815 }
[email protected]c45f1972012-03-14 07:27:369816 if (!query_manager_->ProcessPendingQueries()) {
[email protected]22e3f552012-03-13 01:54:199817 current_decoder_error_ = error::kOutOfBounds;
9818 }
9819 return query_manager_->HavePendingQueries();
9820}
9821
[email protected]5a36dc132013-07-23 23:17:559822// Note that if there are no pending readpixels right now,
9823// this function will call the callback immediately.
9824void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) {
9825 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) {
9826 pending_readpixel_fences_.back()->callbacks.push_back(callback);
9827 } else {
9828 callback.Run();
9829 }
9830}
9831
9832void GLES2DecoderImpl::ProcessPendingReadPixels() {
9833 while (!pending_readpixel_fences_.empty() &&
9834 pending_readpixel_fences_.front()->fence->HasCompleted()) {
9835 std::vector<base::Closure> callbacks =
9836 pending_readpixel_fences_.front()->callbacks;
9837 pending_readpixel_fences_.pop();
9838 for (size_t i = 0; i < callbacks.size(); i++) {
9839 callbacks[i].Run();
9840 }
9841 }
9842}
9843
[email protected]2b1767cf2013-03-16 09:25:059844bool GLES2DecoderImpl::HasMoreIdleWork() {
[email protected]5a36dc132013-07-23 23:17:559845 return !pending_readpixel_fences_.empty() ||
9846 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059847}
9848
9849void GLES2DecoderImpl::PerformIdleWork() {
[email protected]5a36dc132013-07-23 23:17:559850 ProcessPendingReadPixels();
[email protected]b68b100752013-06-05 08:34:489851 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
[email protected]2b1767cf2013-03-16 09:25:059852 return;
[email protected]b68b100752013-06-05 08:34:489853 async_pixel_transfer_manager_->ProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059854 ProcessFinishedAsyncTransfers();
9855}
9856
vmiuracd108592014-09-08 14:36:349857error::Error GLES2DecoderImpl::HandleBeginQueryEXT(uint32 immediate_data_size,
9858 const void* cmd_data) {
9859 const gles2::cmds::BeginQueryEXT& c =
9860 *static_cast<const gles2::cmds::BeginQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:539861 GLenum target = static_cast<GLenum>(c.target);
9862 GLuint client_id = static_cast<GLuint>(c.id);
9863 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
9864 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
9865
[email protected]c45f1972012-03-14 07:27:369866 switch (target) {
9867 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:559868 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]5537605d2013-08-27 05:22:319869 case GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM:
9870 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:009871 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:369872 break;
[email protected]6a25ae422014-04-17 23:48:279873 case GL_COMMANDS_COMPLETED_CHROMIUM:
9874 if (!features().chromium_sync_query) {
9875 LOCAL_SET_GL_ERROR(
9876 GL_INVALID_OPERATION, "glBeginQueryEXT",
9877 "not enabled for commands completed queries");
9878 return error::kNoError;
9879 }
9880 break;
[email protected]c45f1972012-03-14 07:27:369881 default:
[email protected]62e155e2012-10-23 22:43:159882 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:519883 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:009884 GL_INVALID_OPERATION, "glBeginQueryEXT",
9885 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:369886 return error::kNoError;
9887 }
9888 break;
[email protected]882ba1e22012-03-08 19:02:539889 }
9890
[email protected]8ebd46c2014-01-08 12:06:139891 if (state_.current_queries.find(target) != state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:519892 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439893 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:539894 return error::kNoError;
9895 }
9896
9897 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:519898 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:539899 return error::kNoError;
9900 }
9901
9902 QueryManager::Query* query = query_manager_->GetQuery(client_id);
9903 if (!query) {
[email protected]4eea7e62014-04-22 21:14:439904 if (!query_manager_->IsValidQuery(client_id)) {
9905 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
9906 "glBeginQueryEXT",
9907 "id not made by glGenQueriesEXT");
9908 return error::kNoError;
9909 }
[email protected]c45f1972012-03-14 07:27:369910 query = query_manager_->CreateQuery(
9911 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:539912 }
9913
[email protected]c45f1972012-03-14 07:27:369914 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:519915 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439916 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:539917 return error::kNoError;
9918 } else if (query->shm_id() != sync_shm_id ||
9919 query->shm_offset() != sync_shm_offset) {
9920 DLOG(ERROR) << "Shared memory used by query not the same as before";
9921 return error::kInvalidArguments;
9922 }
9923
[email protected]c45f1972012-03-14 07:27:369924 if (!query_manager_->BeginQuery(query)) {
9925 return error::kOutOfBounds;
9926 }
[email protected]882ba1e22012-03-08 19:02:539927
[email protected]8ebd46c2014-01-08 12:06:139928 state_.current_queries[target] = query;
[email protected]882ba1e22012-03-08 19:02:539929 return error::kNoError;
9930}
9931
vmiuracd108592014-09-08 14:36:349932error::Error GLES2DecoderImpl::HandleEndQueryEXT(uint32 immediate_data_size,
9933 const void* cmd_data) {
9934 const gles2::cmds::EndQueryEXT& c =
9935 *static_cast<const gles2::cmds::EndQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:539936 GLenum target = static_cast<GLenum>(c.target);
9937 uint32 submit_count = static_cast<GLuint>(c.submit_count);
[email protected]8ebd46c2014-01-08 12:06:139938 ContextState::QueryMap::iterator it = state_.current_queries.find(target);
[email protected]882ba1e22012-03-08 19:02:539939
[email protected]8ebd46c2014-01-08 12:06:139940 if (it == state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:519941 LOCAL_SET_GL_ERROR(
9942 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:539943 return error::kNoError;
9944 }
[email protected]882ba1e22012-03-08 19:02:539945
[email protected]8ebd46c2014-01-08 12:06:139946 QueryManager::Query* query = it->second.get();
9947 if (!query_manager_->EndQuery(query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:369948 return error::kOutOfBounds;
9949 }
9950
[email protected]fe8d73c2013-02-16 22:37:329951 query_manager_->ProcessPendingTransferQueries();
9952
[email protected]8ebd46c2014-01-08 12:06:139953 state_.current_queries.erase(it);
[email protected]882ba1e22012-03-08 19:02:539954 return error::kNoError;
9955}
9956
[email protected]944b62f32012-09-27 02:20:469957bool GLES2DecoderImpl::GenVertexArraysOESHelper(
9958 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469959 for (GLsizei ii = 0; ii < n; ++ii) {
9960 if (GetVertexAttribManager(client_ids[ii])) {
9961 return false;
9962 }
9963 }
[email protected]ab4fd7282012-10-12 16:25:579964
[email protected]62e155e2012-10-23 22:43:159965 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579966 // Emulated VAO
9967 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:489968 CreateVertexAttribManager(client_ids[ii], 0, true);
[email protected]ab4fd7282012-10-12 16:25:579969 }
9970 } else {
[email protected]40d90a22013-04-09 03:39:559971 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:579972
9973 glGenVertexArraysOES(n, service_ids.get());
9974 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:489975 CreateVertexAttribManager(client_ids[ii], service_ids[ii], true);
[email protected]ab4fd7282012-10-12 16:25:579976 }
[email protected]944b62f32012-09-27 02:20:469977 }
[email protected]ab4fd7282012-10-12 16:25:579978
[email protected]944b62f32012-09-27 02:20:469979 return true;
9980}
9981
9982void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
9983 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469984 for (GLsizei ii = 0; ii < n; ++ii) {
9985 VertexAttribManager* vao =
9986 GetVertexAttribManager(client_ids[ii]);
9987 if (vao && !vao->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:119988 if (state_.vertex_attrib_manager.get() == vao) {
[email protected]242c9822014-04-15 21:36:119989 DoBindVertexArrayOES(0);
[email protected]944b62f32012-09-27 02:20:469990 }
9991 RemoveVertexAttribManager(client_ids[ii]);
9992 }
9993 }
9994}
9995
9996void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469997 VertexAttribManager* vao = NULL;
[email protected]944b62f32012-09-27 02:20:469998 if (client_id != 0) {
9999 vao = GetVertexAttribManager(client_id);
10000 if (!vao) {
10001 // Unlike most Bind* methods, the spec explicitly states that VertexArray
10002 // only allows names that have been previously generated. As such, we do
10003 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:5110004 LOCAL_SET_GL_ERROR(
10005 GL_INVALID_OPERATION,
10006 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:4610007 current_decoder_error_ = error::kNoError;
10008 return;
[email protected]944b62f32012-09-27 02:20:4610009 }
[email protected]944b62f32012-09-27 02:20:4610010 } else {
[email protected]81f20a622014-04-18 01:54:5210011 vao = state_.default_vertex_attrib_manager.get();
[email protected]944b62f32012-09-27 02:20:4610012 }
10013
[email protected]ab4fd7282012-10-12 16:25:5710014 // Only set the VAO state if it's changed
[email protected]7cd76fd2013-06-02 21:11:1110015 if (state_.vertex_attrib_manager.get() != vao) {
[email protected]e259eb412012-10-13 05:47:2410016 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:1510017 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:5710018 EmulateVertexArrayState();
10019 } else {
[email protected]da364812014-05-09 21:39:4810020 GLuint service_id = vao->service_id();
[email protected]ab4fd7282012-10-12 16:25:5710021 glBindVertexArrayOES(service_id);
10022 }
10023 }
10024}
10025
10026// Used when OES_vertex_array_object isn't natively supported
10027void GLES2DecoderImpl::EmulateVertexArrayState() {
10028 // Setup the Vertex attribute state
10029 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
[email protected]3fc38e22014-05-30 00:13:2310030 RestoreStateForAttrib(vv, true);
[email protected]ab4fd7282012-10-12 16:25:5710031 }
10032
10033 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:2110034 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:2410035 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:5710036 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
10037 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:4610038}
10039
10040bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:4610041 const VertexAttribManager* vao =
10042 GetVertexAttribManager(client_id);
10043 return vao && vao->IsValid() && !vao->IsDeleted();
10044}
10045
[email protected]e51bdf32011-11-23 22:21:4610046#if defined(OS_MACOSX)
10047void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
10048 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
10049 texture_id);
10050 if (it != texture_to_io_surface_map_.end()) {
10051 // Found a previous IOSurface bound to this texture; release it.
[email protected]c3a6b4a2014-06-04 09:25:5310052 IOSurfaceRef surface = it->second;
[email protected]e51bdf32011-11-23 22:21:4610053 CFRelease(surface);
10054 texture_to_io_surface_map_.erase(it);
10055 }
10056}
10057#endif
10058
10059void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
10060 GLenum target, GLsizei width, GLsizei height,
10061 GLuint io_surface_id, GLuint plane) {
10062#if defined(OS_MACOSX)
10063 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:5110064 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310065 GL_INVALID_OPERATION,
10066 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:4610067 return;
10068 }
10069
[email protected]e51bdf32011-11-23 22:21:4610070 if (target != GL_TEXTURE_RECTANGLE_ARB) {
10071 // This might be supported in the future, and if we could require
10072 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
10073 // could delete a lot of code. For now, perform strict validation so we
10074 // know what's going on.
[email protected]ab09b612013-03-11 22:11:5110075 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4610076 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310077 "glTexImageIOSurface2DCHROMIUM",
10078 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:4610079 return;
10080 }
10081
[email protected]09d50362012-10-18 20:54:3710082 // Default target might be conceptually valid, but disallow it to avoid
10083 // accidents.
[email protected]c986af502013-08-14 01:04:4410084 TextureRef* texture_ref =
10085 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910086 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110087 LOCAL_SET_GL_ERROR(
10088 GL_INVALID_OPERATION,
10089 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:4610090 return;
10091 }
[email protected]e51bdf32011-11-23 22:21:4610092
10093 // Look up the new IOSurface. Note that because of asynchrony
10094 // between processes this might fail; during live resizing the
10095 // plugin process might allocate and release an IOSurface before
10096 // this process gets a chance to look it up. Hold on to any old
10097 // IOSurface in this case.
[email protected]c3a6b4a2014-06-04 09:25:5310098 IOSurfaceRef surface = IOSurfaceLookup(io_surface_id);
[email protected]e51bdf32011-11-23 22:21:4610099 if (!surface) {
[email protected]ab09b612013-03-11 22:11:5110100 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310101 GL_INVALID_OPERATION,
10102 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:4610103 return;
10104 }
10105
10106 // Release any IOSurface previously bound to this texture.
[email protected]370eaf12013-05-18 09:19:4910107 ReleaseIOSurfaceForTexture(texture_ref->service_id());
[email protected]e51bdf32011-11-23 22:21:4610108
10109 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
10110 texture_to_io_surface_map_.insert(
[email protected]370eaf12013-05-18 09:19:4910111 std::make_pair(texture_ref->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:4610112
10113 CGLContextObj context =
10114 static_cast<CGLContextObj>(context_->GetHandle());
10115
[email protected]c3a6b4a2014-06-04 09:25:5310116 CGLError err = CGLTexImageIOSurface2D(
[email protected]e51bdf32011-11-23 22:21:4610117 context,
10118 target,
10119 GL_RGBA,
10120 width,
10121 height,
10122 GL_BGRA,
10123 GL_UNSIGNED_INT_8_8_8_8_REV,
10124 surface,
10125 plane);
10126
10127 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:5110128 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4610129 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310130 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:4610131 return;
10132 }
10133
10134 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910135 texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:4610136 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
10137
10138#else
[email protected]ab09b612013-03-11 22:11:5110139 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310140 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:4610141#endif
10142}
10143
[email protected]97dc7cbe2011-12-06 17:26:1710144static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
10145 switch (internalformat) {
10146 case GL_RGB565:
10147 return GL_RGB;
10148 case GL_RGBA4:
10149 return GL_RGBA;
10150 case GL_RGB5_A1:
10151 return GL_RGBA;
10152 case GL_RGB8_OES:
10153 return GL_RGB;
10154 case GL_RGBA8_OES:
10155 return GL_RGBA;
10156 case GL_LUMINANCE8_ALPHA8_EXT:
10157 return GL_LUMINANCE_ALPHA;
10158 case GL_LUMINANCE8_EXT:
10159 return GL_LUMINANCE;
10160 case GL_ALPHA8_EXT:
10161 return GL_ALPHA;
10162 case GL_RGBA32F_EXT:
10163 return GL_RGBA;
10164 case GL_RGB32F_EXT:
10165 return GL_RGB;
10166 case GL_ALPHA32F_EXT:
10167 return GL_ALPHA;
10168 case GL_LUMINANCE32F_EXT:
10169 return GL_LUMINANCE;
10170 case GL_LUMINANCE_ALPHA32F_EXT:
10171 return GL_LUMINANCE_ALPHA;
10172 case GL_RGBA16F_EXT:
10173 return GL_RGBA;
10174 case GL_RGB16F_EXT:
10175 return GL_RGB;
10176 case GL_ALPHA16F_EXT:
10177 return GL_ALPHA;
10178 case GL_LUMINANCE16F_EXT:
10179 return GL_LUMINANCE;
10180 case GL_LUMINANCE_ALPHA16F_EXT:
10181 return GL_LUMINANCE_ALPHA;
10182 case GL_BGRA8_EXT:
10183 return GL_BGRA_EXT;
bajones2a2ea232014-10-13 21:38:5910184 case GL_SRGB8_ALPHA8_EXT:
10185 return GL_SRGB_ALPHA_EXT;
[email protected]97dc7cbe2011-12-06 17:26:1710186 default:
10187 return GL_NONE;
10188 }
10189}
10190
[email protected]43410e92012-04-20 17:06:2810191void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:0310192 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
[email protected]a4a6bdd12013-04-19 20:46:5410193 GLenum internal_format, GLenum dest_type) {
[email protected]1e24dc7f2014-04-14 02:40:0810194 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM");
10195
[email protected]370eaf12013-05-18 09:19:4910196 TextureRef* dest_texture_ref = GetTexture(dest_id);
10197 TextureRef* source_texture_ref = GetTexture(source_id);
[email protected]43410e92012-04-20 17:06:2810198
[email protected]370eaf12013-05-18 09:19:4910199 if (!source_texture_ref || !dest_texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110200 LOCAL_SET_GL_ERROR(
10201 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:2810202 return;
10203 }
10204
10205 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110206 LOCAL_SET_GL_ERROR(
10207 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:2810208 return;
10209 }
10210
[email protected]370eaf12013-05-18 09:19:4910211 Texture* source_texture = source_texture_ref->texture();
10212 Texture* dest_texture = dest_texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0710213 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:2510214 (source_texture->target() != GL_TEXTURE_2D &&
[email protected]041d463f2014-04-30 05:38:3410215 source_texture->target() != GL_TEXTURE_RECTANGLE_ARB &&
10216 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
[email protected]3ecc1052013-09-26 08:59:0010217 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
10218 "glCopyTextureCHROMIUM",
10219 "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:0310220 return;
10221 }
10222
[email protected]43410e92012-04-20 17:06:2810223 int source_width, source_height, dest_width, dest_height;
[email protected]43410e92012-04-20 17:06:2810224
[email protected]3e0dfd72014-02-21 06:28:4110225 gfx::GLImage* image =
10226 source_texture->GetLevelImage(source_texture->target(), 0);
10227 if (image) {
[email protected]7bffe9e12014-01-27 23:02:5510228 gfx::Size size = image->GetSize();
[email protected]377976552013-05-14 23:32:5610229 source_width = size.width();
10230 source_height = size.height();
10231 if (source_width <= 0 || source_height <= 0) {
10232 LOCAL_SET_GL_ERROR(
10233 GL_INVALID_VALUE,
[email protected]7bffe9e12014-01-27 23:02:5510234 "glCopyTextureChromium", "invalid image size");
[email protected]377976552013-05-14 23:32:5610235 return;
10236 }
[email protected]3ecc1052013-09-26 08:59:0010237 } else {
10238 if (!source_texture->GetLevelSize(
10239 source_texture->target(), 0, &source_width, &source_height)) {
10240 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
10241 "glCopyTextureChromium",
10242 "source texture has no level 0");
10243 return;
10244 }
10245
10246 // Check that this type of texture is allowed.
10247 if (!texture_manager()->ValidForTarget(
10248 source_texture->target(), level, source_width, source_height, 1)) {
10249 LOCAL_SET_GL_ERROR(
10250 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions");
10251 return;
10252 }
[email protected]377976552013-05-14 23:32:5610253 }
10254
[email protected]04b5b37d2014-02-07 02:11:5110255 // Clear the source texture if necessary.
10256 if (!texture_manager()->ClearTextureLevel(
10257 this, source_texture_ref, source_texture->target(), 0)) {
10258 LOCAL_SET_GL_ERROR(
10259 GL_OUT_OF_MEMORY, "glCopyTextureCHROMIUM", "dimensions too big");
10260 return;
10261 }
10262
[email protected]a6e3d282014-08-22 22:20:4410263 GLenum source_type = 0;
10264 GLenum source_internal_format = 0;
10265 source_texture->GetLevelType(
10266 source_texture->target(), 0, &source_type, &source_internal_format);
10267
10268 // The destination format should be GL_RGB, or GL_RGBA. GL_ALPHA,
10269 // GL_LUMINANCE, and GL_LUMINANCE_ALPHA are not supported because they are not
10270 // renderable on some platforms.
reveman6b0fbe42014-09-04 00:55:0310271 bool valid_dest_format = internal_format == GL_RGB ||
10272 internal_format == GL_RGBA ||
10273 internal_format == GL_BGRA_EXT;
[email protected]a6e3d282014-08-22 22:20:4410274 bool valid_source_format = source_internal_format == GL_ALPHA ||
10275 source_internal_format == GL_RGB ||
10276 source_internal_format == GL_RGBA ||
10277 source_internal_format == GL_LUMINANCE ||
10278 source_internal_format == GL_LUMINANCE_ALPHA ||
10279 source_internal_format == GL_BGRA_EXT;
10280 if (!valid_source_format || !valid_dest_format) {
10281 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10282 "glCopyTextureCHROMIUM",
10283 "invalid internal format");
10284 return;
10285 }
10286
[email protected]cf6b8f62012-05-25 21:43:3710287 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
10288 // needed because it takes 10s of milliseconds to initialize.
10289 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:5110290 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:3710291 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:2710292 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:3710293 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:5110294 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:3710295 return;
10296 }
10297
[email protected]efc87712014-07-09 00:22:4710298 GLenum dest_type_previous = dest_type;
10299 GLenum dest_internal_format = internal_format;
[email protected]02965c22013-03-09 02:40:0710300 bool dest_level_defined = dest_texture->GetLevelSize(
10301 GL_TEXTURE_2D, level, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:2810302
[email protected]0a1e9ad2012-05-04 21:13:0310303 if (dest_level_defined) {
[email protected]a4a6bdd12013-04-19 20:46:5410304 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous,
[email protected]02965c22013-03-09 02:40:0710305 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:0310306 }
10307
10308 // Resize the destination texture to the dimensions of the source texture.
10309 if (!dest_level_defined || dest_width != source_width ||
10310 dest_height != source_height ||
[email protected]a4a6bdd12013-04-19 20:46:5410311 dest_internal_format != internal_format ||
10312 dest_type_previous != dest_type) {
[email protected]43410e92012-04-20 17:06:2810313 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:5110314 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:0710315 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
[email protected]8f1d2aa2013-05-10 23:45:3810316 glTexImage2D(
[email protected]43410e92012-04-20 17:06:2810317 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:0310318 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:5110319 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:0310320 if (error != GL_NO_ERROR) {
[email protected]2b10c02d2014-01-29 16:43:0210321 RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D);
[email protected]43410e92012-04-20 17:06:2810322 return;
[email protected]0a1e9ad2012-05-04 21:13:0310323 }
[email protected]43410e92012-04-20 17:06:2810324
10325 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910326 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:0310327 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:2510328 } else {
[email protected]02965c22013-03-09 02:40:0710329 texture_manager()->SetLevelCleared(
[email protected]370eaf12013-05-18 09:19:4910330 dest_texture_ref, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:2810331 }
10332
[email protected]00c2cf92014-03-14 00:08:3710333 ScopedModifyPixels modify(dest_texture_ref);
[email protected]91c94eb2013-10-22 10:32:5410334
revemance8fbe82014-09-05 02:19:5210335 // Try using GLImage::CopyTexImage when possible.
10336 bool unpack_premultiply_alpha_change =
10337 unpack_premultiply_alpha_ ^ unpack_unpremultiply_alpha_;
10338 if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change && !level) {
10339 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
10340 if (image->CopyTexImage(GL_TEXTURE_2D))
10341 return;
10342 }
10343
10344 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
10345
[email protected]5394a4102013-04-18 05:41:3710346 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
10347 // before presenting.
10348 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
10349 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
10350 // instead of using default matrix crbug.com/226218.
10351 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
10352 0.0f, 1.0f, 0.0f, 0.0f,
10353 0.0f, 0.0f, 1.0f, 0.0f,
10354 0.0f, 0.0f, 0.0f, 1.0f};
10355 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
10356 this,
10357 source_texture->target(),
[email protected]5394a4102013-04-18 05:41:3710358 source_texture->service_id(),
[email protected]90f7d30d2014-08-13 02:51:5710359 dest_texture->service_id(),
10360 level,
10361 source_width,
10362 source_height,
[email protected]5394a4102013-04-18 05:41:3710363 unpack_flip_y_,
10364 unpack_premultiply_alpha_,
10365 unpack_unpremultiply_alpha_,
10366 default_matrix);
10367 } else {
[email protected]90f7d30d2014-08-13 02:51:5710368 copy_texture_CHROMIUM_->DoCopyTexture(this,
10369 source_texture->target(),
10370 source_texture->service_id(),
10371 source_internal_format,
10372 dest_texture->service_id(),
10373 level,
10374 internal_format,
10375 source_width,
10376 source_height,
10377 unpack_flip_y_,
10378 unpack_premultiply_alpha_,
10379 unpack_unpremultiply_alpha_);
[email protected]5394a4102013-04-18 05:41:3710380 }
[email protected]91c94eb2013-10-22 10:32:5410381
10382 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
[email protected]43410e92012-04-20 17:06:2810383}
10384
[email protected]97dc7cbe2011-12-06 17:26:1710385static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
10386 switch (internalformat) {
10387 case GL_RGB565:
10388 return GL_UNSIGNED_SHORT_5_6_5;
10389 case GL_RGBA4:
10390 return GL_UNSIGNED_SHORT_4_4_4_4;
10391 case GL_RGB5_A1:
10392 return GL_UNSIGNED_SHORT_5_5_5_1;
10393 case GL_RGB8_OES:
10394 return GL_UNSIGNED_BYTE;
10395 case GL_RGBA8_OES:
10396 return GL_UNSIGNED_BYTE;
10397 case GL_LUMINANCE8_ALPHA8_EXT:
10398 return GL_UNSIGNED_BYTE;
10399 case GL_LUMINANCE8_EXT:
10400 return GL_UNSIGNED_BYTE;
10401 case GL_ALPHA8_EXT:
10402 return GL_UNSIGNED_BYTE;
10403 case GL_RGBA32F_EXT:
10404 return GL_FLOAT;
10405 case GL_RGB32F_EXT:
10406 return GL_FLOAT;
10407 case GL_ALPHA32F_EXT:
10408 return GL_FLOAT;
10409 case GL_LUMINANCE32F_EXT:
10410 return GL_FLOAT;
10411 case GL_LUMINANCE_ALPHA32F_EXT:
10412 return GL_FLOAT;
10413 case GL_RGBA16F_EXT:
10414 return GL_HALF_FLOAT_OES;
10415 case GL_RGB16F_EXT:
10416 return GL_HALF_FLOAT_OES;
10417 case GL_ALPHA16F_EXT:
10418 return GL_HALF_FLOAT_OES;
10419 case GL_LUMINANCE16F_EXT:
10420 return GL_HALF_FLOAT_OES;
10421 case GL_LUMINANCE_ALPHA16F_EXT:
10422 return GL_HALF_FLOAT_OES;
10423 case GL_BGRA8_EXT:
10424 return GL_UNSIGNED_BYTE;
10425 default:
10426 return GL_NONE;
10427 }
10428}
10429
10430void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:4410431 GLenum target,
10432 GLint levels,
10433 GLenum internal_format,
10434 GLsizei width,
10435 GLsizei height) {
[email protected]67f929422014-05-17 15:33:1310436 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT",
10437 "width", width, "height", height);
[email protected]80eb6b52012-01-19 00:14:4110438 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]3ecc1052013-09-26 08:59:0010439 TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:5110440 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310441 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:1710442 return;
10443 }
[email protected]c986af502013-08-14 01:04:4410444 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10445 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910446 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110447 LOCAL_SET_GL_ERROR(
10448 GL_INVALID_OPERATION,
10449 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:1710450 return;
10451 }
[email protected]370eaf12013-05-18 09:19:4910452 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0710453 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:4410454 framebuffer_state_.clear_state_dirty = true;
[email protected]97dc7cbe2011-12-06 17:26:1710455 }
[email protected]02965c22013-03-09 02:40:0710456 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:5110457 LOCAL_SET_GL_ERROR(
10458 GL_INVALID_OPERATION,
10459 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:1710460 return;
10461 }
[email protected]7989c9e2013-01-23 06:39:2610462
10463 GLenum format = ExtractFormatFromStorageFormat(internal_format);
10464 GLenum type = ExtractTypeFromStorageFormat(internal_format);
10465
10466 {
10467 GLsizei level_width = width;
10468 GLsizei level_height = height;
10469 uint32 estimated_size = 0;
10470 for (int ii = 0; ii < levels; ++ii) {
10471 uint32 level_size = 0;
10472 if (!GLES2Util::ComputeImageDataSizes(
10473 level_width, level_height, format, type, state_.unpack_alignment,
10474 &estimated_size, NULL, NULL) ||
10475 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5110476 LOCAL_SET_GL_ERROR(
10477 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:2610478 return;
10479 }
10480 level_width = std::max(1, level_width >> 1);
10481 level_height = std::max(1, level_height >> 1);
10482 }
10483 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5110484 LOCAL_SET_GL_ERROR(
10485 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2610486 return;
10487 }
10488 }
10489
[email protected]ab09b612013-03-11 22:11:5110490 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]8f1d2aa2013-05-10 23:45:3810491 glTexStorage2DEXT(target, levels, internal_format, width, height);
[email protected]ab09b612013-03-11 22:11:5110492 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:1710493 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:1510494 GLsizei level_width = width;
10495 GLsizei level_height = height;
10496 for (int ii = 0; ii < levels; ++ii) {
10497 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910498 texture_ref, target, ii, format,
10499 level_width, level_height, 1, 0, format, type, false);
[email protected]4502e6492011-12-14 19:39:1510500 level_width = std::max(1, level_width >> 1);
10501 level_height = std::max(1, level_height >> 1);
10502 }
[email protected]02965c22013-03-09 02:40:0710503 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:1710504 }
[email protected]97dc7cbe2011-12-06 17:26:1710505}
[email protected]e51bdf32011-11-23 22:21:4610506
[email protected]78b514b2012-05-01 21:50:5910507error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
vmiuracd108592014-09-08 14:36:3410508 uint32 immediate_data_size,
10509 const void* cmd_data) {
[email protected]baed42c2013-10-01 05:06:3510510 return error::kUnknownCommand;
[email protected]78b514b2012-05-01 21:50:5910511}
10512
10513void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3710514 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0210515 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3210516 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3710517 "mailbox[0]", static_cast<unsigned char>(data[0]));
10518
[email protected]43f253da2014-06-10 17:51:2210519 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10520 &state_, target);
10521 ProduceTextureRef("glProduceTextureCHROMIUM", texture_ref, target, data);
10522}
10523
10524void GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM(GLuint client_id,
10525 GLenum target, const GLbyte* data) {
10526 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM",
10527 "context", logger_.GetLogPrefix(),
10528 "mailbox[0]", static_cast<unsigned char>(data[0]));
10529
10530 ProduceTextureRef("glProduceTextureDirectCHROMIUM", GetTexture(client_id),
10531 target, data);
10532}
10533
10534void GLES2DecoderImpl::ProduceTextureRef(std::string func_name,
10535 TextureRef* texture_ref, GLenum target, const GLbyte* data) {
[email protected]64ba52f2014-02-15 14:22:3710536 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
[email protected]43f253da2014-06-10 17:51:2210537 DLOG_IF(ERROR, !mailbox.Verify()) << func_name << " was passed a "
[email protected]64ba52f2014-02-15 14:22:3710538 "mailbox that was not generated by "
10539 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0210540
[email protected]370eaf12013-05-18 09:19:4910541 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110542 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2210543 GL_INVALID_OPERATION, func_name.c_str(), "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5910544 return;
10545 }
10546
[email protected]62e65f02013-05-29 22:28:1010547 Texture* produced = texture_manager()->Produce(texture_ref);
10548 if (!produced) {
[email protected]ab09b612013-03-11 22:11:5110549 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2210550 GL_INVALID_OPERATION, func_name.c_str(), "invalid texture");
10551 return;
10552 }
10553
10554 if (produced->target() != target) {
10555 LOCAL_SET_GL_ERROR(
10556 GL_INVALID_OPERATION, func_name.c_str(), "invalid target");
[email protected]78b514b2012-05-01 21:50:5910557 return;
10558 }
10559
[email protected]64ba52f2014-02-15 14:22:3710560 group_->mailbox_manager()->ProduceTexture(target, mailbox, produced);
[email protected]78b514b2012-05-01 21:50:5910561}
10562
10563void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3710564 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0210565 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3210566 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3710567 "mailbox[0]", static_cast<unsigned char>(data[0]));
10568 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
10569 DLOG_IF(ERROR, !mailbox.Verify()) << "ConsumeTextureCHROMIUM was passed a "
10570 "mailbox that was not generated by "
10571 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0210572
[email protected]62e65f02013-05-29 22:28:1010573 scoped_refptr<TextureRef> texture_ref =
[email protected]c986af502013-08-14 01:04:4410574 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]7cd76fd2013-06-02 21:11:1110575 if (!texture_ref.get()) {
10576 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10577 "glConsumeTextureCHROMIUM",
10578 "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5910579 return;
10580 }
[email protected]62e65f02013-05-29 22:28:1010581 GLuint client_id = texture_ref->client_id();
10582 if (!client_id) {
10583 LOCAL_SET_GL_ERROR(
10584 GL_INVALID_OPERATION,
10585 "glConsumeTextureCHROMIUM", "unknown texture for target");
10586 return;
10587 }
[email protected]64ba52f2014-02-15 14:22:3710588 Texture* texture = group_->mailbox_manager()->ConsumeTexture(target, mailbox);
[email protected]62e65f02013-05-29 22:28:1010589 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5110590 LOCAL_SET_GL_ERROR(
10591 GL_INVALID_OPERATION,
10592 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:5910593 return;
10594 }
[email protected]62e65f02013-05-29 22:28:1010595 if (texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:5110596 LOCAL_SET_GL_ERROR(
10597 GL_INVALID_OPERATION,
[email protected]62e65f02013-05-29 22:28:1010598 "glConsumeTextureCHROMIUM", "invalid target");
[email protected]78b514b2012-05-01 21:50:5910599 return;
10600 }
[email protected]62e65f02013-05-29 22:28:1010601
10602 DeleteTexturesHelper(1, &client_id);
10603 texture_ref = texture_manager()->Consume(client_id, texture);
10604 glBindTexture(target, texture_ref->service_id());
10605
10606 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
10607 unit.bind_target = target;
10608 switch (target) {
10609 case GL_TEXTURE_2D:
10610 unit.bound_texture_2d = texture_ref;
10611 break;
10612 case GL_TEXTURE_CUBE_MAP:
10613 unit.bound_texture_cube_map = texture_ref;
10614 break;
10615 case GL_TEXTURE_EXTERNAL_OES:
10616 unit.bound_texture_external_oes = texture_ref;
10617 break;
10618 case GL_TEXTURE_RECTANGLE_ARB:
10619 unit.bound_texture_rectangle_arb = texture_ref;
10620 break;
10621 default:
10622 NOTREACHED(); // Validation should prevent us getting here.
10623 break;
10624 }
[email protected]78b514b2012-05-01 21:50:5910625}
10626
[email protected]43f253da2014-06-10 17:51:2210627error::Error GLES2DecoderImpl::HandleCreateAndConsumeTextureCHROMIUMImmediate(
10628 uint32_t immediate_data_size,
vmiuracd108592014-09-08 14:36:3410629 const void* cmd_data) {
10630 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate& c =
10631 *static_cast<
10632 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate*>(
10633 cmd_data);
[email protected]43f253da2014-06-10 17:51:2210634 GLenum target = static_cast<GLenum>(c.target);
10635 uint32_t data_size;
10636 if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
10637 return error::kOutOfBounds;
10638 }
10639 if (data_size > immediate_data_size) {
10640 return error::kOutOfBounds;
10641 }
10642 const GLbyte* mailbox =
10643 GetImmediateDataAs<const GLbyte*>(c, data_size, immediate_data_size);
10644 if (!validators_->texture_bind_target.IsValid(target)) {
10645 LOCAL_SET_GL_ERROR_INVALID_ENUM(
10646 "glCreateAndConsumeTextureCHROMIUM", target, "target");
10647 return error::kNoError;
10648 }
10649 if (mailbox == NULL) {
10650 return error::kOutOfBounds;
10651 }
10652 uint32_t client_id = c.client_id;
10653 DoCreateAndConsumeTextureCHROMIUM(target, mailbox, client_id);
10654 return error::kNoError;
10655}
10656
10657void GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM(GLenum target,
10658 const GLbyte* data, GLuint client_id) {
10659 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM",
10660 "context", logger_.GetLogPrefix(),
10661 "mailbox[0]", static_cast<unsigned char>(data[0]));
10662 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
10663 DLOG_IF(ERROR, !mailbox.Verify()) << "CreateAndConsumeTextureCHROMIUM was "
10664 "passed a mailbox that was not "
10665 "generated by GenMailboxCHROMIUM.";
10666
10667 TextureRef* texture_ref = GetTexture(client_id);
10668 if (texture_ref) {
10669 LOCAL_SET_GL_ERROR(
10670 GL_INVALID_OPERATION,
10671 "glCreateAndConsumeTextureCHROMIUM", "client id already in use");
10672 return;
10673 }
10674 Texture* texture = group_->mailbox_manager()->ConsumeTexture(target, mailbox);
10675 if (!texture) {
10676 LOCAL_SET_GL_ERROR(
10677 GL_INVALID_OPERATION,
10678 "glCreateAndConsumeTextureCHROMIUM", "invalid mailbox name");
10679 return;
10680 }
10681 if (texture->target() != target) {
10682 LOCAL_SET_GL_ERROR(
10683 GL_INVALID_OPERATION,
10684 "glCreateAndConsumeTextureCHROMIUM", "invalid target");
10685 return;
10686 }
10687
[email protected]43f253da2014-06-10 17:51:2210688 texture_ref = texture_manager()->Consume(client_id, texture);
10689}
10690
[email protected]d2a0e1a2012-08-12 02:25:0110691void GLES2DecoderImpl::DoInsertEventMarkerEXT(
10692 GLsizei length, const GLchar* marker) {
10693 if (!marker) {
10694 marker = "";
10695 }
10696 debug_marker_manager_.SetMarker(
10697 length ? std::string(marker, length) : std::string(marker));
10698}
10699
10700void GLES2DecoderImpl::DoPushGroupMarkerEXT(
10701 GLsizei length, const GLchar* marker) {
10702 if (!marker) {
10703 marker = "";
10704 }
[email protected]cac16542014-01-15 17:53:5110705 std::string name = length ? std::string(marker, length) : std::string(marker);
10706 debug_marker_manager_.PushGroup(name);
10707 gpu_tracer_->Begin(name, kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0110708}
10709
10710void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
10711 debug_marker_manager_.PopGroup();
[email protected]cac16542014-01-15 17:53:5110712 gpu_tracer_->End(kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0110713}
10714
[email protected]09d50362012-10-18 20:54:3710715void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
10716 GLenum target, GLint image_id) {
10717 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3710718
[email protected]bc26e8d2014-01-29 00:40:3010719 if (target == GL_TEXTURE_CUBE_MAP) {
10720 LOCAL_SET_GL_ERROR(
10721 GL_INVALID_ENUM,
10722 "glBindTexImage2DCHROMIUM", "invalid target");
10723 return;
10724 }
10725
[email protected]09d50362012-10-18 20:54:3710726 // Default target might be conceptually valid, but disallow it to avoid
10727 // accidents.
[email protected]c986af502013-08-14 01:04:4410728 TextureRef* texture_ref =
10729 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910730 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110731 LOCAL_SET_GL_ERROR(
10732 GL_INVALID_OPERATION,
10733 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710734 return;
10735 }
10736
10737 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10738 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110739 LOCAL_SET_GL_ERROR(
10740 GL_INVALID_OPERATION,
10741 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710742 return;
10743 }
10744
[email protected]b8160812013-04-09 00:41:0410745 {
10746 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010747 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2610748 if (!gl_image->BindTexImage(target)) {
[email protected]b8160812013-04-09 00:41:0410749 LOCAL_SET_GL_ERROR(
10750 GL_INVALID_OPERATION,
10751 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
10752 return;
10753 }
[email protected]09d50362012-10-18 20:54:3710754 }
10755
10756 gfx::Size size = gl_image->GetSize();
10757 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910758 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:3710759 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]370eaf12013-05-18 09:19:4910760 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:3710761}
10762
10763void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
10764 GLenum target, GLint image_id) {
10765 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3710766
10767 // 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 "glReleaseTexImage2DCHROMIUM", "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 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710783 return;
10784 }
10785
10786 // Do nothing when image is not currently bound.
[email protected]370eaf12013-05-18 09:19:4910787 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3710788 return;
10789
[email protected]b8160812013-04-09 00:41:0410790 {
10791 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010792 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2610793 gl_image->ReleaseTexImage(target);
[email protected]b8160812013-04-09 00:41:0410794 }
[email protected]09d50362012-10-18 20:54:3710795
10796 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910797 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:3710798 GL_RGBA, GL_UNSIGNED_BYTE, false);
10799}
[email protected]d2a0e1a2012-08-12 02:25:0110800
[email protected]94307712012-11-16 23:26:1110801error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
vmiuracd108592014-09-08 14:36:3410802 uint32 immediate_data_size,
10803 const void* cmd_data) {
10804 const gles2::cmds::TraceBeginCHROMIUM& c =
10805 *static_cast<const gles2::cmds::TraceBeginCHROMIUM*>(cmd_data);
[email protected]94307712012-11-16 23:26:1110806 Bucket* bucket = GetBucket(c.bucket_id);
10807 if (!bucket || bucket->size() == 0) {
10808 return error::kInvalidArguments;
10809 }
10810 std::string command_name;
10811 if (!bucket->GetAsString(&command_name)) {
10812 return error::kInvalidArguments;
10813 }
[email protected]fb97b662013-02-20 23:02:1410814 TRACE_EVENT_COPY_ASYNC_BEGIN0("gpu", command_name.c_str(), this);
[email protected]cac16542014-01-15 17:53:5110815 if (!gpu_tracer_->Begin(command_name, kTraceCHROMIUM)) {
[email protected]ab09b612013-03-11 22:11:5110816 LOCAL_SET_GL_ERROR(
10817 GL_INVALID_OPERATION,
10818 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1410819 return error::kNoError;
10820 }
[email protected]94307712012-11-16 23:26:1110821 return error::kNoError;
10822}
10823
10824void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
[email protected]fb97b662013-02-20 23:02:1410825 if (gpu_tracer_->CurrentName().empty()) {
[email protected]ab09b612013-03-11 22:11:5110826 LOCAL_SET_GL_ERROR(
10827 GL_INVALID_OPERATION,
10828 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1110829 return;
10830 }
[email protected]fb97b662013-02-20 23:02:1410831 TRACE_EVENT_COPY_ASYNC_END0("gpu", gpu_tracer_->CurrentName().c_str(), this);
[email protected]cac16542014-01-15 17:53:5110832 gpu_tracer_->End(kTraceCHROMIUM);
[email protected]94307712012-11-16 23:26:1110833}
10834
[email protected]2f143d482013-03-14 18:04:4910835void GLES2DecoderImpl::DoDrawBuffersEXT(
10836 GLsizei count, const GLenum* bufs) {
10837 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
10838 LOCAL_SET_GL_ERROR(
10839 GL_INVALID_VALUE,
10840 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
10841 return;
10842 }
10843
10844 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
10845 if (framebuffer) {
10846 for (GLsizei i = 0; i < count; ++i) {
10847 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
10848 bufs[i] != GL_NONE) {
10849 LOCAL_SET_GL_ERROR(
10850 GL_INVALID_OPERATION,
10851 "glDrawBuffersEXT",
10852 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
10853 return;
10854 }
10855 }
10856 glDrawBuffersARB(count, bufs);
10857 framebuffer->SetDrawBuffers(count, bufs);
10858 } else { // backbuffer
10859 if (count > 1 ||
10860 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
10861 LOCAL_SET_GL_ERROR(
10862 GL_INVALID_OPERATION,
10863 "glDrawBuffersEXT",
10864 "more than one buffer or bufs not GL_NONE or GL_BACK");
10865 return;
10866 }
10867 GLenum mapped_buf = bufs[0];
10868 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
10869 bufs[0] == GL_BACK) {
10870 mapped_buf = GL_COLOR_ATTACHMENT0;
10871 }
10872 glDrawBuffersARB(count, &mapped_buf);
10873 group_->set_draw_buffer(bufs[0]);
10874 }
10875}
10876
[email protected]a6a09f852014-05-23 13:05:0310877void GLES2DecoderImpl::DoLoseContextCHROMIUM(GLenum current, GLenum other) {
10878 group_->LoseContexts(other);
10879 reset_status_ = current;
10880 current_decoder_error_ = error::kLostContext;
10881}
10882
kkinnunen337d59632014-08-26 10:19:5710883void GLES2DecoderImpl::DoMatrixLoadfCHROMIUM(GLenum matrix_mode,
10884 const GLfloat* matrix) {
10885 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
10886 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
10887 if (!features().chromium_path_rendering) {
10888 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10889 "glMatrixLoadfCHROMIUM",
10890 "function not available");
10891 return;
10892 }
10893
10894 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
10895 ? state_.projection_matrix
10896 : state_.modelview_matrix;
10897 memcpy(target_matrix, matrix, sizeof(GLfloat) * 16);
10898 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
10899 // since the values of the _NV and _CHROMIUM tokens match.
10900 glMatrixLoadfEXT(matrix_mode, matrix);
10901}
10902
10903void GLES2DecoderImpl::DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode) {
10904 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
10905 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
10906
10907 if (!features().chromium_path_rendering) {
10908 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10909 "glMatrixLoadIdentityCHROMIUM",
10910 "function not available");
10911 return;
10912 }
10913
10914 static GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
10915 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
10916 0.0f, 0.0f, 0.0f, 1.0f};
10917
10918 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
10919 ? state_.projection_matrix
10920 : state_.modelview_matrix;
10921 memcpy(target_matrix, kIdentityMatrix, sizeof(kIdentityMatrix));
10922 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
10923 // since the values of the _NV and _CHROMIUM tokens match.
10924 glMatrixLoadIdentityEXT(matrix_mode);
10925}
10926
[email protected]32145a92012-12-17 09:01:5910927bool GLES2DecoderImpl::ValidateAsyncTransfer(
10928 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:4710929 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:5910930 GLenum target,
10931 GLint level,
10932 const void * data) {
10933 // We only support async uploads to 2D textures for now.
10934 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110935 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5910936 return false;
10937 }
10938 // We only support uploads to level zero for now.
10939 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5110940 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5910941 return false;
10942 }
10943 // A transfer buffer must be bound, even for asyncTexImage2D.
10944 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5110945 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5910946 return false;
10947 }
10948 // We only support one async transfer in progress.
[email protected]85a4ac22013-05-31 01:58:4710949 if (!texture_ref ||
10950 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5110951 LOCAL_SET_GL_ERROR(
10952 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910953 function_name, "transfer already in progress");
10954 return false;
10955 }
10956 return true;
10957}
10958
[email protected]e3c4a9ab2014-03-31 09:07:0210959base::Closure GLES2DecoderImpl::AsyncUploadTokenCompletionClosure(
10960 uint32 async_upload_token,
10961 uint32 sync_data_shm_id,
10962 uint32 sync_data_shm_offset) {
10963 scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_data_shm_id);
Daniel Cheng3d7ce9f2014-08-26 00:26:2510964 if (!buffer.get() ||
10965 !buffer->GetDataAddress(sync_data_shm_offset, sizeof(AsyncUploadSync)))
[email protected]e3c4a9ab2014-03-31 09:07:0210966 return base::Closure();
10967
10968 AsyncMemoryParams mem_params(buffer,
10969 sync_data_shm_offset,
10970 sizeof(AsyncUploadSync));
10971
10972 scoped_refptr<AsyncUploadTokenCompletionObserver> observer(
10973 new AsyncUploadTokenCompletionObserver(async_upload_token));
10974
10975 return base::Bind(
10976 &AsyncPixelTransferManager::AsyncNotifyCompletion,
10977 base::Unretained(GetAsyncPixelTransferManager()),
10978 mem_params,
10979 observer);
10980}
10981
[email protected]69023942012-11-30 19:57:1610982error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3410983 uint32 immediate_data_size,
10984 const void* cmd_data) {
10985 const gles2::cmds::AsyncTexImage2DCHROMIUM& c =
10986 *static_cast<const gles2::cmds::AsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1610987 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610988 GLenum target = static_cast<GLenum>(c.target);
10989 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:4410990 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]69023942012-11-30 19:57:1610991 GLsizei width = static_cast<GLsizei>(c.width);
10992 GLsizei height = static_cast<GLsizei>(c.height);
10993 GLint border = static_cast<GLint>(c.border);
10994 GLenum format = static_cast<GLenum>(c.format);
10995 GLenum type = static_cast<GLenum>(c.type);
10996 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
10997 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
10998 uint32 pixels_size;
[email protected]e3c4a9ab2014-03-31 09:07:0210999 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
11000 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
11001 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
11002
11003 base::ScopedClosureRunner scoped_completion_callback;
11004 if (async_upload_token) {
11005 base::Closure completion_closure =
11006 AsyncUploadTokenCompletionClosure(async_upload_token,
11007 sync_data_shm_id,
11008 sync_data_shm_offset);
11009 if (completion_closure.is_null())
11010 return error::kInvalidArguments;
11011
11012 scoped_completion_callback.Reset(completion_closure);
11013 }
[email protected]32145a92012-12-17 09:01:5911014
11015 // TODO(epenner): Move this and copies of this memory validation
11016 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1611017 if (!GLES2Util::ComputeImageDataSizes(
11018 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
11019 NULL)) {
11020 return error::kOutOfBounds;
11021 }
11022 const void* pixels = NULL;
11023 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
11024 pixels = GetSharedMemoryAs<const void*>(
11025 pixels_shm_id, pixels_shm_offset, pixels_size);
11026 if (!pixels) {
11027 return error::kOutOfBounds;
11028 }
11029 }
11030
[email protected]c986af502013-08-14 01:04:4411031 TextureManager::DoTextImage2DArguments args = {
11032 target, level, internal_format, width, height, border, format, type,
11033 pixels, pixels_size};
11034 TextureRef* texture_ref;
[email protected]32145a92012-12-17 09:01:5911035 // All the normal glTexSubImage2D validation.
[email protected]c986af502013-08-14 01:04:4411036 if (!texture_manager()->ValidateTexImage2D(
11037 &state_, "glAsyncTexImage2DCHROMIUM", args, &texture_ref)) {
[email protected]32145a92012-12-17 09:01:5911038 return error::kNoError;
11039 }
11040
11041 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4911042 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5911043 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4711044 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5911045 return error::kNoError;
11046
11047 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0711048 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5111049 LOCAL_SET_GL_ERROR(
11050 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5911051 "glAsyncTexImage2DCHROMIUM", "already defined");
11052 return error::kNoError;
11053 }
11054
[email protected]7989c9e2013-01-23 06:39:2611055 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5111056 LOCAL_SET_GL_ERROR(
11057 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2611058 return error::kNoError;
11059 }
11060
[email protected]5b3a8e02013-03-13 05:36:4411061 // Setup the parameters.
[email protected]8f1d2aa2013-05-10 23:45:3811062 AsyncTexImage2DParams tex_params = {
11063 target, level, static_cast<GLenum>(internal_format),
11064 width, height, border, format, type};
[email protected]c8021e02014-03-27 06:10:1211065 AsyncMemoryParams mem_params(
11066 GetSharedMemoryBuffer(c.pixels_shm_id), c.pixels_shm_offset, pixels_size);
[email protected]32145a92012-12-17 09:01:5911067
[email protected]5b3a8e02013-03-13 05:36:4411068 // Set up the async state if needed, and make the texture
11069 // immutable so the async state stays valid. The level info
11070 // is set up lazily when the transfer completes.
[email protected]896425e2013-06-12 17:27:1811071 AsyncPixelTransferDelegate* delegate =
11072 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref,
11073 tex_params);
[email protected]5b3a8e02013-03-13 05:36:4411074 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5911075
[email protected]896425e2013-06-12 17:27:1811076 delegate->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4411077 tex_params,
11078 mem_params,
11079 base::Bind(&TextureManager::SetLevelInfoFromParams,
[email protected]370eaf12013-05-18 09:19:4911080 // The callback is only invoked if the transfer delegate still
11081 // exists, which implies through manager->texture_ref->state
[email protected]5b3a8e02013-03-13 05:36:4411082 // ownership that both of these pointers are valid.
11083 base::Unretained(texture_manager()),
[email protected]370eaf12013-05-18 09:19:4911084 base::Unretained(texture_ref),
[email protected]5b3a8e02013-03-13 05:36:4411085 tex_params));
[email protected]f598f422012-12-07 08:30:0311086 return error::kNoError;
[email protected]69023942012-11-30 19:57:1611087}
11088
11089error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411090 uint32 immediate_data_size,
11091 const void* cmd_data) {
11092 const gles2::cmds::AsyncTexSubImage2DCHROMIUM& c =
11093 *static_cast<const gles2::cmds::AsyncTexSubImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1611094 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1611095 GLenum target = static_cast<GLenum>(c.target);
11096 GLint level = static_cast<GLint>(c.level);
11097 GLint xoffset = static_cast<GLint>(c.xoffset);
11098 GLint yoffset = static_cast<GLint>(c.yoffset);
11099 GLsizei width = static_cast<GLsizei>(c.width);
11100 GLsizei height = static_cast<GLsizei>(c.height);
11101 GLenum format = static_cast<GLenum>(c.format);
11102 GLenum type = static_cast<GLenum>(c.type);
[email protected]e3c4a9ab2014-03-31 09:07:0211103 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
11104 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
11105 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
11106
11107 base::ScopedClosureRunner scoped_completion_callback;
11108 if (async_upload_token) {
11109 base::Closure completion_closure =
11110 AsyncUploadTokenCompletionClosure(async_upload_token,
11111 sync_data_shm_id,
11112 sync_data_shm_offset);
11113 if (completion_closure.is_null())
11114 return error::kInvalidArguments;
11115
11116 scoped_completion_callback.Reset(completion_closure);
11117 }
[email protected]32145a92012-12-17 09:01:5911118
11119 // TODO(epenner): Move this and copies of this memory validation
11120 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1611121 uint32 data_size;
11122 if (!GLES2Util::ComputeImageDataSizes(
11123 width, height, format, type, state_.unpack_alignment, &data_size,
11124 NULL, NULL)) {
11125 return error::kOutOfBounds;
11126 }
11127 const void* pixels = GetSharedMemoryAs<const void*>(
11128 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5911129
11130 // All the normal glTexSubImage2D validation.
11131 error::Error error = error::kNoError;
11132 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
11133 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
11134 return error;
[email protected]69023942012-11-30 19:57:1611135 }
11136
[email protected]32145a92012-12-17 09:01:5911137 // Extra async validation.
[email protected]c986af502013-08-14 01:04:4411138 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11139 &state_, target);
[email protected]370eaf12013-05-18 09:19:4911140 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5911141 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4711142 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5911143 return error::kNoError;
11144
11145 // Guarantee async textures are always 'cleared' as follows:
11146 // - AsyncTexImage2D can not redefine an existing texture
11147 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
11148 // - AsyncTexSubImage2D clears synchronously if not already cleared.
11149 // - Textures become immutable after an async call.
11150 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0711151 if (!texture->SafeToRenderFrom()) {
[email protected]370eaf12013-05-18 09:19:4911152 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
11153 target, level)) {
[email protected]ab09b612013-03-11 22:11:5111154 LOCAL_SET_GL_ERROR(
11155 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2511156 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5911157 return error::kNoError;
11158 }
11159 }
11160
[email protected]5b3a8e02013-03-13 05:36:4411161 // Setup the parameters.
[email protected]2a7568a2013-05-09 23:12:0311162 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
[email protected]32145a92012-12-17 09:01:5911163 width, height, format, type};
[email protected]c8021e02014-03-27 06:10:1211164 AsyncMemoryParams mem_params(
11165 GetSharedMemoryBuffer(c.data_shm_id), c.data_shm_offset, data_size);
[email protected]896425e2013-06-12 17:27:1811166 AsyncPixelTransferDelegate* delegate =
11167 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
11168 if (!delegate) {
[email protected]5b3a8e02013-03-13 05:36:4411169 // TODO(epenner): We may want to enforce exclusive use
11170 // of async APIs in which case this should become an error,
11171 // (the texture should have been async defined).
[email protected]2a7568a2013-05-09 23:12:0311172 AsyncTexImage2DParams define_params = {target, level,
[email protected]5b3a8e02013-03-13 05:36:4411173 0, 0, 0, 0, 0, 0};
11174 texture->GetLevelSize(target, level, &define_params.width,
11175 &define_params.height);
11176 texture->GetLevelType(target, level, &define_params.type,
11177 &define_params.internal_format);
11178 // Set up the async state if needed, and make the texture
11179 // immutable so the async state stays valid.
[email protected]896425e2013-06-12 17:27:1811180 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate(
[email protected]85a4ac22013-05-31 01:58:4711181 texture_ref, define_params);
[email protected]5b3a8e02013-03-13 05:36:4411182 texture->SetImmutable(true);
11183 }
11184
[email protected]896425e2013-06-12 17:27:1811185 delegate->AsyncTexSubImage2D(tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5911186 return error::kNoError;
[email protected]69023942012-11-30 19:57:1611187}
11188
[email protected]a00c1f742013-03-05 17:02:1611189error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411190 uint32 immediate_data_size,
11191 const void* cmd_data) {
11192 const gles2::cmds::WaitAsyncTexImage2DCHROMIUM& c =
11193 *static_cast<const gles2::cmds::WaitAsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]a00c1f742013-03-05 17:02:1611194 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
11195 GLenum target = static_cast<GLenum>(c.target);
11196
11197 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5111198 LOCAL_SET_GL_ERROR(
11199 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1611200 return error::kNoError;
11201 }
[email protected]c986af502013-08-14 01:04:4411202 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11203 &state_, target);
[email protected]370eaf12013-05-18 09:19:4911204 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111205 LOCAL_SET_GL_ERROR(
11206 GL_INVALID_OPERATION,
11207 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1611208 return error::kNoError;
11209 }
[email protected]896425e2013-06-12 17:27:1811210 AsyncPixelTransferDelegate* delegate =
11211 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
11212 if (!delegate) {
[email protected]370eaf12013-05-18 09:19:4911213 LOCAL_SET_GL_ERROR(
11214 GL_INVALID_OPERATION,
11215 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
11216 return error::kNoError;
11217 }
[email protected]896425e2013-06-12 17:27:1811218 delegate->WaitForTransferCompletion();
[email protected]69a8701e2013-03-07 21:31:0911219 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1611220 return error::kNoError;
11221}
11222
[email protected]e3c4a9ab2014-03-31 09:07:0211223error::Error GLES2DecoderImpl::HandleWaitAllAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411224 uint32 immediate_data_size,
11225 const void* data) {
[email protected]e3c4a9ab2014-03-31 09:07:0211226 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
11227
11228 GetAsyncPixelTransferManager()->WaitAllAsyncTexImage2D();
11229 ProcessFinishedAsyncTransfers();
11230 return error::kNoError;
11231}
11232
[email protected]91c94eb2013-10-22 10:32:5411233void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer(
11234 TextureRef* texture_ref) {
11235 Texture* texture = texture_ref->texture();
11236 DoDidUseTexImageIfNeeded(texture, texture->target());
11237}
11238
[email protected]828a3932014-04-02 14:43:1311239void GLES2DecoderImpl::OnOutOfMemoryError() {
11240 if (lose_context_when_out_of_memory_) {
11241 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB);
11242 LoseContext(GL_GUILTY_CONTEXT_RESET_ARB);
11243 }
11244}
11245
[email protected]96449d2c2009-11-25 00:01:3211246// Include the auto-generated part of this file. We split this because it means
11247// we can easily edit the non-auto generated parts right here in this file
11248// instead of having to edit some template or the code generator.
11249#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
11250
11251} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2511252} // namespace gpu