blob: f4db4d70d85fcb52485fe5b2453954fc6e8cb669 [file] [log] [blame]
Geoff Langf9a6f082015-01-22 13:32:49 -05001//
2// Copyright 2015 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// RendererGL.cpp: Implements the class methods for RendererGL.
8
9#include "libANGLE/renderer/gl/RendererGL.h"
10
Jamie Madill39fcf262015-06-08 14:39:07 -040011#include <EGL/eglext.h>
12
Geoff Langf9a6f082015-01-22 13:32:49 -050013#include "common/debug.h"
Jamie Madill39fcf262015-06-08 14:39:07 -040014#include "libANGLE/AttributeMap.h"
Geoff Langc4152832015-02-20 09:57:29 -050015#include "libANGLE/Data.h"
Geoff Lang4ad17092015-03-10 16:47:44 -040016#include "libANGLE/Surface.h"
Geoff Lang53b8aec2015-08-24 10:33:25 -040017#include "libANGLE/renderer/gl/BlitGL.h"
Geoff Langf9a6f082015-01-22 13:32:49 -050018#include "libANGLE/renderer/gl/BufferGL.h"
19#include "libANGLE/renderer/gl/CompilerGL.h"
Geoff Langf9a6f082015-01-22 13:32:49 -050020#include "libANGLE/renderer/gl/FenceNVGL.h"
21#include "libANGLE/renderer/gl/FenceSyncGL.h"
22#include "libANGLE/renderer/gl/FramebufferGL.h"
Geoff Lang56cf9af2015-02-17 10:16:49 -050023#include "libANGLE/renderer/gl/FunctionsGL.h"
Geoff Langf9a6f082015-01-22 13:32:49 -050024#include "libANGLE/renderer/gl/ProgramGL.h"
25#include "libANGLE/renderer/gl/QueryGL.h"
26#include "libANGLE/renderer/gl/RenderbufferGL.h"
27#include "libANGLE/renderer/gl/ShaderGL.h"
Geoff Lang94463d52015-02-18 13:09:37 -050028#include "libANGLE/renderer/gl/StateManagerGL.h"
Geoff Lang4ad17092015-03-10 16:47:44 -040029#include "libANGLE/renderer/gl/SurfaceGL.h"
Geoff Langf9a6f082015-01-22 13:32:49 -050030#include "libANGLE/renderer/gl/TextureGL.h"
31#include "libANGLE/renderer/gl/TransformFeedbackGL.h"
32#include "libANGLE/renderer/gl/VertexArrayGL.h"
Geoff Langddc74462015-02-25 11:48:09 -050033#include "libANGLE/renderer/gl/renderergl_utils.h"
Geoff Langf9a6f082015-01-22 13:32:49 -050034
Geoff Langb80360f2015-05-04 15:01:31 -040035#ifndef NDEBUG
36static void INTERNAL_GL_APIENTRY LogGLDebugMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
37 const GLchar *message, const void *userParam)
38{
39 std::string sourceText;
40 switch (source)
41 {
42 case GL_DEBUG_SOURCE_API: sourceText = "OpenGL"; break;
43 case GL_DEBUG_SOURCE_WINDOW_SYSTEM: sourceText = "Windows"; break;
44 case GL_DEBUG_SOURCE_SHADER_COMPILER: sourceText = "Shader Compiler"; break;
45 case GL_DEBUG_SOURCE_THIRD_PARTY: sourceText = "Third Party"; break;
46 case GL_DEBUG_SOURCE_APPLICATION: sourceText = "Application"; break;
47 case GL_DEBUG_SOURCE_OTHER: sourceText = "Other"; break;
48 default: sourceText = "UNKNOWN"; break;
49 }
50
51 std::string typeText;
52 switch (type)
53 {
54 case GL_DEBUG_TYPE_ERROR: typeText = "Error"; break;
55 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: typeText = "Deprecated behavior"; break;
56 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: typeText = "Undefined behavior"; break;
57 case GL_DEBUG_TYPE_PORTABILITY: typeText = "Portability"; break;
58 case GL_DEBUG_TYPE_PERFORMANCE: typeText = "Performance"; break;
59 case GL_DEBUG_TYPE_OTHER: typeText = "Other"; break;
60 case GL_DEBUG_TYPE_MARKER: typeText = "Marker"; break;
61 default: typeText = "UNKNOWN"; break;
62 }
63
64 std::string severityText;
65 switch (severity)
66 {
67 case GL_DEBUG_SEVERITY_HIGH: severityText = "High"; break;
68 case GL_DEBUG_SEVERITY_MEDIUM: severityText = "Medium"; break;
69 case GL_DEBUG_SEVERITY_LOW: severityText = "Low"; break;
70 case GL_DEBUG_SEVERITY_NOTIFICATION: severityText = "Notification"; break;
71 default: severityText = "UNKNOWN"; break;
72 }
73
74 ERR("\n\tSource: %s\n\tType: %s\n\tID: %d\n\tSeverity: %s\n\tMessage: %s", sourceText.c_str(), typeText.c_str(), id,
75 severityText.c_str(), message);
76}
77#endif
78
Geoff Langf9a6f082015-01-22 13:32:49 -050079namespace rx
80{
81
Jamie Madill39fcf262015-06-08 14:39:07 -040082RendererGL::RendererGL(const FunctionsGL *functions, const egl::AttributeMap &attribMap)
Geoff Lang56cf9af2015-02-17 10:16:49 -050083 : Renderer(),
Geoff Lang862c0ba2015-05-25 15:31:16 -040084 mMaxSupportedESVersion(0, 0),
Geoff Lang94463d52015-02-18 13:09:37 -050085 mFunctions(functions),
Jamie Madill39fcf262015-06-08 14:39:07 -040086 mStateManager(nullptr),
Geoff Lang53b8aec2015-08-24 10:33:25 -040087 mBlitter(nullptr),
Jamie Madill39fcf262015-06-08 14:39:07 -040088 mSkipDrawCalls(false)
Geoff Lang56cf9af2015-02-17 10:16:49 -050089{
90 ASSERT(mFunctions);
Geoff Langc05f7062015-03-10 09:50:57 -070091 mStateManager = new StateManagerGL(mFunctions, getRendererCaps());
Geoff Langcab7e1d2015-07-27 11:20:41 -040092 nativegl_gl::GenerateWorkarounds(mFunctions, &mWorkarounds);
Geoff Lang53b8aec2015-08-24 10:33:25 -040093 mBlitter = new BlitGL(functions, mWorkarounds, mStateManager);
Geoff Langb80360f2015-05-04 15:01:31 -040094
95#ifndef NDEBUG
96 if (mFunctions->debugMessageControl && mFunctions->debugMessageCallback)
97 {
98 mFunctions->enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
99 mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0, nullptr, GL_TRUE);
100 mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM, 0, nullptr, GL_TRUE);
101 mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, nullptr, GL_FALSE);
102 mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, GL_FALSE);
103 mFunctions->debugMessageCallback(&LogGLDebugMessage, nullptr);
104 }
105#endif
Jamie Madill39fcf262015-06-08 14:39:07 -0400106
107 EGLint deviceType = attribMap.get(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_NONE);
108 if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE)
109 {
110 mSkipDrawCalls = true;
111 }
Geoff Lang56cf9af2015-02-17 10:16:49 -0500112}
Geoff Langf9a6f082015-01-22 13:32:49 -0500113
114RendererGL::~RendererGL()
Geoff Lang94463d52015-02-18 13:09:37 -0500115{
116 SafeDelete(mStateManager);
Geoff Lang53b8aec2015-08-24 10:33:25 -0400117 SafeDelete(mBlitter);
Geoff Lang94463d52015-02-18 13:09:37 -0500118}
Geoff Langf9a6f082015-01-22 13:32:49 -0500119
120gl::Error RendererGL::flush()
121{
Geoff Lang2c919142015-04-01 14:44:13 -0400122 mFunctions->flush();
123 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500124}
125
126gl::Error RendererGL::finish()
127{
Geoff Lang2c919142015-04-01 14:44:13 -0400128 mFunctions->finish();
129 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500130}
131
Geoff Langf6db0982015-08-25 13:04:00 -0400132gl::Error RendererGL::drawArrays(const gl::Data &data, GLenum mode, GLint first, GLsizei count)
Geoff Langf9a6f082015-01-22 13:32:49 -0500133{
Geoff Lang3cf12ce2015-08-27 14:40:48 -0400134 gl::Error error = mStateManager->setDrawArraysState(data, first, count, 0);
Geoff Lang7c82bc42015-03-09 16:18:08 -0400135 if (error.isError())
136 {
137 return error;
138 }
139
Jamie Madill39fcf262015-06-08 14:39:07 -0400140 if (!mSkipDrawCalls)
141 {
142 mFunctions->drawArrays(mode, first, count);
143 }
Geoff Langd6e50872015-02-24 12:42:26 -0500144
145 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500146}
147
Geoff Langf6db0982015-08-25 13:04:00 -0400148gl::Error RendererGL::drawArraysInstanced(const gl::Data &data,
149 GLenum mode,
150 GLint first,
151 GLsizei count,
152 GLsizei instanceCount)
153{
Geoff Lang3cf12ce2015-08-27 14:40:48 -0400154 gl::Error error = mStateManager->setDrawArraysState(data, first, count, instanceCount);
155 if (error.isError())
156 {
157 return error;
158 }
159
160 if (!mSkipDrawCalls)
161 {
162 mFunctions->drawArraysInstanced(mode, first, count, instanceCount);
163 }
164
Geoff Langf6db0982015-08-25 13:04:00 -0400165 return gl::Error(GL_NO_ERROR);
166}
167
168gl::Error RendererGL::drawElements(const gl::Data &data,
169 GLenum mode,
170 GLsizei count,
171 GLenum type,
172 const GLvoid *indices,
Geoff Lang831b1952015-05-05 11:02:27 -0400173 const gl::RangeUI &indexRange)
Geoff Langf9a6f082015-01-22 13:32:49 -0500174{
Geoff Lang7c82bc42015-03-09 16:18:08 -0400175 const GLvoid *drawIndexPointer = nullptr;
Geoff Lang3cf12ce2015-08-27 14:40:48 -0400176 gl::Error error =
177 mStateManager->setDrawElementsState(data, count, type, indices, 0, &drawIndexPointer);
Geoff Lang7c82bc42015-03-09 16:18:08 -0400178 if (error.isError())
179 {
180 return error;
181 }
182
Jamie Madill39fcf262015-06-08 14:39:07 -0400183 if (!mSkipDrawCalls)
184 {
185 mFunctions->drawElements(mode, count, type, drawIndexPointer);
186 }
Geoff Langd6e50872015-02-24 12:42:26 -0500187
188 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -0500189}
190
Geoff Langf6db0982015-08-25 13:04:00 -0400191gl::Error RendererGL::drawElementsInstanced(const gl::Data &data,
192 GLenum mode,
193 GLsizei count,
194 GLenum type,
195 const GLvoid *indices,
196 GLsizei instances,
197 const gl::RangeUI &indexRange)
198{
Geoff Lang3cf12ce2015-08-27 14:40:48 -0400199 const GLvoid *drawIndexPointer = nullptr;
200 gl::Error error = mStateManager->setDrawElementsState(data, count, type, indices, instances,
201 &drawIndexPointer);
202 if (error.isError())
203 {
204 return error;
205 }
206
207 if (!mSkipDrawCalls)
208 {
209 mFunctions->drawElementsInstanced(mode, count, type, drawIndexPointer, instances);
210 }
211
Geoff Langf6db0982015-08-25 13:04:00 -0400212 return gl::Error(GL_NO_ERROR);
213}
214
215gl::Error RendererGL::drawRangeElements(const gl::Data &data,
216 GLenum mode,
217 GLuint start,
218 GLuint end,
219 GLsizei count,
220 GLenum type,
221 const GLvoid *indices,
222 const gl::RangeUI &indexRange)
223{
224 UNIMPLEMENTED();
225 return gl::Error(GL_NO_ERROR);
226}
227
Geoff Langf9a6f082015-01-22 13:32:49 -0500228CompilerImpl *RendererGL::createCompiler(const gl::Data &data)
229{
Geoff Lang8273e002015-06-15 13:40:19 -0700230 return new CompilerGL(data, mFunctions);
Geoff Langf9a6f082015-01-22 13:32:49 -0500231}
232
233ShaderImpl *RendererGL::createShader(GLenum type)
234{
Geoff Lang295ed4c2015-02-20 09:58:25 -0500235 return new ShaderGL(type, mFunctions);
Geoff Langf9a6f082015-01-22 13:32:49 -0500236}
237
Jamie Madill5c6b7bf2015-08-17 12:53:35 -0400238ProgramImpl *RendererGL::createProgram(const gl::Program::Data &data)
Geoff Langf9a6f082015-01-22 13:32:49 -0500239{
Jamie Madill5c6b7bf2015-08-17 12:53:35 -0400240 return new ProgramGL(data, mFunctions, mStateManager);
Geoff Langf9a6f082015-01-22 13:32:49 -0500241}
242
Jamie Madilld1405e52015-03-05 15:41:39 -0500243FramebufferImpl *RendererGL::createFramebuffer(const gl::Framebuffer::Data &data)
Geoff Langf9a6f082015-01-22 13:32:49 -0500244{
Geoff Lang4ad17092015-03-10 16:47:44 -0400245 return new FramebufferGL(data, mFunctions, mStateManager, false);
Geoff Langf9a6f082015-01-22 13:32:49 -0500246}
247
248TextureImpl *RendererGL::createTexture(GLenum target)
249{
Geoff Lang53b8aec2015-08-24 10:33:25 -0400250 return new TextureGL(target, mFunctions, mWorkarounds, mStateManager, mBlitter);
Geoff Langf9a6f082015-01-22 13:32:49 -0500251}
252
253RenderbufferImpl *RendererGL::createRenderbuffer()
254{
Geoff Lang23a2ae02015-07-28 12:42:52 -0400255 return new RenderbufferGL(mFunctions, mWorkarounds, mStateManager, getRendererTextureCaps());
Geoff Langf9a6f082015-01-22 13:32:49 -0500256}
257
258BufferImpl *RendererGL::createBuffer()
259{
Geoff Lang36c79012015-02-24 11:47:20 -0500260 return new BufferGL(mFunctions, mStateManager);
Geoff Langf9a6f082015-01-22 13:32:49 -0500261}
262
Jamie Madill8e344942015-07-09 14:22:07 -0400263VertexArrayImpl *RendererGL::createVertexArray(const gl::VertexArray::Data &data)
Geoff Langf9a6f082015-01-22 13:32:49 -0500264{
Jamie Madill8e344942015-07-09 14:22:07 -0400265 return new VertexArrayGL(data, mFunctions, mStateManager);
Geoff Langf9a6f082015-01-22 13:32:49 -0500266}
267
268QueryImpl *RendererGL::createQuery(GLenum type)
269{
270 return new QueryGL(type);
271}
272
273FenceNVImpl *RendererGL::createFenceNV()
274{
Geoff Langb11ad262015-04-09 14:43:34 -0400275 return new FenceNVGL(mFunctions);
Geoff Langf9a6f082015-01-22 13:32:49 -0500276}
277
278FenceSyncImpl *RendererGL::createFenceSync()
279{
Geoff Lang7d433dd2015-04-02 11:21:20 -0400280 return new FenceSyncGL(mFunctions);
Geoff Langf9a6f082015-01-22 13:32:49 -0500281}
282
283TransformFeedbackImpl *RendererGL::createTransformFeedback()
284{
285 return new TransformFeedbackGL();
286}
287
Austin Kinross6ee1e782015-05-29 17:05:37 -0700288void RendererGL::insertEventMarker(GLsizei, const char *)
289{
290 UNREACHABLE();
291}
292
293void RendererGL::pushGroupMarker(GLsizei, const char *)
294{
295 UNREACHABLE();
296}
297
298void RendererGL::popGroupMarker()
299{
300 UNREACHABLE();
301}
302
Geoff Langf9a6f082015-01-22 13:32:49 -0500303void RendererGL::notifyDeviceLost()
304{
305 UNIMPLEMENTED();
306}
307
308bool RendererGL::isDeviceLost() const
309{
310 UNIMPLEMENTED();
311 return bool();
312}
313
314bool RendererGL::testDeviceLost()
315{
316 UNIMPLEMENTED();
317 return bool();
318}
319
320bool RendererGL::testDeviceResettable()
321{
322 UNIMPLEMENTED();
323 return bool();
324}
325
326VendorID RendererGL::getVendorId() const
327{
328 UNIMPLEMENTED();
329 return VendorID();
330}
331
332std::string RendererGL::getVendorString() const
333{
Geoff Lange42753b2015-04-08 13:46:33 -0400334 return std::string(reinterpret_cast<const char*>(mFunctions->getString(GL_VENDOR)));
Geoff Langf9a6f082015-01-22 13:32:49 -0500335}
336
337std::string RendererGL::getRendererDescription() const
338{
Geoff Lange42753b2015-04-08 13:46:33 -0400339 std::string nativeVendorString(reinterpret_cast<const char*>(mFunctions->getString(GL_VENDOR)));
340 std::string nativeRendererString(reinterpret_cast<const char*>(mFunctions->getString(GL_RENDERER)));
341
Geoff Lange42753b2015-04-08 13:46:33 -0400342 std::ostringstream rendererString;
343 rendererString << nativeVendorString << " " << nativeRendererString << " OpenGL";
Geoff Lang08dcfed2015-05-25 13:38:42 -0400344 if (mFunctions->standard == STANDARD_GL_ES)
Geoff Lange42753b2015-04-08 13:46:33 -0400345 {
346 rendererString << " ES";
347 }
Geoff Lang08dcfed2015-05-25 13:38:42 -0400348 rendererString << " " << mFunctions->version.major << "." << mFunctions->version.minor;
Geoff Lang8b0f0b32015-07-20 15:59:28 -0400349 if (mFunctions->standard == STANDARD_GL_DESKTOP)
350 {
351 // Some drivers (NVIDIA) use a profile mask of 0 when in compatibility profile.
352 if ((mFunctions->profile & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) != 0 ||
353 (mFunctions->isAtLeastGL(gl::Version(3, 2)) && mFunctions->profile == 0))
354 {
355 rendererString << " compatibility";
356 }
357 else if ((mFunctions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0)
358 {
359 rendererString << " core";
360 }
361 }
Geoff Lange42753b2015-04-08 13:46:33 -0400362
363 return rendererString.str();
Geoff Langf9a6f082015-01-22 13:32:49 -0500364}
365
Geoff Lang862c0ba2015-05-25 15:31:16 -0400366const gl::Version &RendererGL::getMaxSupportedESVersion() const
367{
368 // Force generation of caps
369 getRendererCaps();
370
371 return mMaxSupportedESVersion;
372}
373
Austin Kinross02df7962015-07-01 10:03:42 -0700374void RendererGL::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap* outTextureCaps,
375 gl::Extensions *outExtensions,
376 gl::Limitations * /* outLimitations */) const
Geoff Langf9a6f082015-01-22 13:32:49 -0500377{
Geoff Lang862c0ba2015-05-25 15:31:16 -0400378 nativegl_gl::GenerateCaps(mFunctions, outCaps, outTextureCaps, outExtensions, &mMaxSupportedESVersion);
Geoff Langf9a6f082015-01-22 13:32:49 -0500379}
380
Jamie Madill1b94d432015-08-07 13:23:23 -0400381void RendererGL::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits)
382{
383 mStateManager->syncState(state, dirtyBits);
384}
Geoff Langf9a6f082015-01-22 13:32:49 -0500385}