blob: fdd72a30c28c09e12f1c63add924cb25295a4e0a [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"
Martin Radev8f276e22017-05-30 12:05:52 +030015#include "libANGLE/Context.h"
Jamie Madill9082b982016-04-27 15:21:51 -040016#include "libANGLE/ContextState.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030017#include "libANGLE/Path.h"
Geoff Lang4ad17092015-03-10 16:47:44 -040018#include "libANGLE/Surface.h"
Geoff Lang53b8aec2015-08-24 10:33:25 -040019#include "libANGLE/renderer/gl/BlitGL.h"
Geoff Langf9a6f082015-01-22 13:32:49 -050020#include "libANGLE/renderer/gl/BufferGL.h"
21#include "libANGLE/renderer/gl/CompilerGL.h"
Jamie Madill437fa652016-05-03 15:13:24 -040022#include "libANGLE/renderer/gl/ContextGL.h"
Geoff Langf9a6f082015-01-22 13:32:49 -050023#include "libANGLE/renderer/gl/FenceNVGL.h"
24#include "libANGLE/renderer/gl/FenceSyncGL.h"
25#include "libANGLE/renderer/gl/FramebufferGL.h"
Geoff Lang56cf9af2015-02-17 10:16:49 -050026#include "libANGLE/renderer/gl/FunctionsGL.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030027#include "libANGLE/renderer/gl/PathGL.h"
Geoff Langf9a6f082015-01-22 13:32:49 -050028#include "libANGLE/renderer/gl/ProgramGL.h"
29#include "libANGLE/renderer/gl/QueryGL.h"
30#include "libANGLE/renderer/gl/RenderbufferGL.h"
Geoff Lang0af0b812015-09-23 13:56:25 -040031#include "libANGLE/renderer/gl/SamplerGL.h"
Geoff Langf9a6f082015-01-22 13:32:49 -050032#include "libANGLE/renderer/gl/ShaderGL.h"
Geoff Lang94463d52015-02-18 13:09:37 -050033#include "libANGLE/renderer/gl/StateManagerGL.h"
Geoff Lang4ad17092015-03-10 16:47:44 -040034#include "libANGLE/renderer/gl/SurfaceGL.h"
Geoff Langf9a6f082015-01-22 13:32:49 -050035#include "libANGLE/renderer/gl/TextureGL.h"
36#include "libANGLE/renderer/gl/TransformFeedbackGL.h"
37#include "libANGLE/renderer/gl/VertexArrayGL.h"
Geoff Langddc74462015-02-25 11:48:09 -050038#include "libANGLE/renderer/gl/renderergl_utils.h"
Jamie Madill222c5172017-07-19 16:15:42 -040039#include "libANGLE/renderer/renderer_utils.h"
Geoff Langf9a6f082015-01-22 13:32:49 -050040
Sami Väisänend59ca052016-06-21 16:10:00 +030041namespace
42{
43
44std::vector<GLuint> GatherPaths(const std::vector<gl::Path *> &paths)
45{
46 std::vector<GLuint> ret;
47 ret.reserve(paths.size());
48
49 for (const auto *p : paths)
50 {
51 const auto *pathObj = rx::GetImplAs<rx::PathGL>(p);
52 ret.push_back(pathObj->getPathID());
53 }
54 return ret;
55}
56
57} // namespace
58
Jamie Madill231c7f52017-04-26 13:45:37 -040059static void INTERNAL_GL_APIENTRY LogGLDebugMessage(GLenum source,
60 GLenum type,
61 GLuint id,
62 GLenum severity,
63 GLsizei length,
64 const GLchar *message,
65 const void *userParam)
Geoff Langb80360f2015-05-04 15:01:31 -040066{
67 std::string sourceText;
68 switch (source)
69 {
Jamie Madill231c7f52017-04-26 13:45:37 -040070 case GL_DEBUG_SOURCE_API:
71 sourceText = "OpenGL";
72 break;
73 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
74 sourceText = "Windows";
75 break;
76 case GL_DEBUG_SOURCE_SHADER_COMPILER:
77 sourceText = "Shader Compiler";
78 break;
79 case GL_DEBUG_SOURCE_THIRD_PARTY:
80 sourceText = "Third Party";
81 break;
82 case GL_DEBUG_SOURCE_APPLICATION:
83 sourceText = "Application";
84 break;
85 case GL_DEBUG_SOURCE_OTHER:
86 sourceText = "Other";
87 break;
88 default:
89 sourceText = "UNKNOWN";
90 break;
Geoff Langb80360f2015-05-04 15:01:31 -040091 }
92
93 std::string typeText;
94 switch (type)
95 {
Jamie Madill231c7f52017-04-26 13:45:37 -040096 case GL_DEBUG_TYPE_ERROR:
97 typeText = "Error";
98 break;
99 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
100 typeText = "Deprecated behavior";
101 break;
102 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
103 typeText = "Undefined behavior";
104 break;
105 case GL_DEBUG_TYPE_PORTABILITY:
106 typeText = "Portability";
107 break;
108 case GL_DEBUG_TYPE_PERFORMANCE:
109 typeText = "Performance";
110 break;
111 case GL_DEBUG_TYPE_OTHER:
112 typeText = "Other";
113 break;
114 case GL_DEBUG_TYPE_MARKER:
115 typeText = "Marker";
116 break;
117 default:
118 typeText = "UNKNOWN";
119 break;
Geoff Langb80360f2015-05-04 15:01:31 -0400120 }
121
122 std::string severityText;
123 switch (severity)
124 {
Jamie Madill231c7f52017-04-26 13:45:37 -0400125 case GL_DEBUG_SEVERITY_HIGH:
126 severityText = "High";
127 break;
128 case GL_DEBUG_SEVERITY_MEDIUM:
129 severityText = "Medium";
130 break;
131 case GL_DEBUG_SEVERITY_LOW:
132 severityText = "Low";
133 break;
134 case GL_DEBUG_SEVERITY_NOTIFICATION:
135 severityText = "Notification";
136 break;
137 default:
138 severityText = "UNKNOWN";
139 break;
Geoff Langb80360f2015-05-04 15:01:31 -0400140 }
141
Yuly Novikovbcb3f9b2017-01-27 22:45:18 -0500142 if (type == GL_DEBUG_TYPE_ERROR)
143 {
144 ERR() << std::endl
145 << "\tSource: " << sourceText << std::endl
146 << "\tType: " << typeText << std::endl
147 << "\tID: " << gl::Error(id) << std::endl
148 << "\tSeverity: " << severityText << std::endl
149 << "\tMessage: " << message;
150 }
151 else
152 {
153 // TODO(ynovikov): filter into WARN and INFO if INFO is ever implemented
154 WARN() << std::endl
155 << "\tSource: " << sourceText << std::endl
156 << "\tType: " << typeText << std::endl
157 << "\tID: " << gl::Error(id) << std::endl
158 << "\tSeverity: " << severityText << std::endl
159 << "\tMessage: " << message;
160 }
Geoff Langb80360f2015-05-04 15:01:31 -0400161}
Geoff Langb80360f2015-05-04 15:01:31 -0400162
Geoff Langf9a6f082015-01-22 13:32:49 -0500163namespace rx
164{
165
Jamie Madill39fcf262015-06-08 14:39:07 -0400166RendererGL::RendererGL(const FunctionsGL *functions, const egl::AttributeMap &attribMap)
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400167 : mMaxSupportedESVersion(0, 0),
Geoff Lang94463d52015-02-18 13:09:37 -0500168 mFunctions(functions),
Jamie Madill39fcf262015-06-08 14:39:07 -0400169 mStateManager(nullptr),
Geoff Lang53b8aec2015-08-24 10:33:25 -0400170 mBlitter(nullptr),
Jamie Madill222c5172017-07-19 16:15:42 -0400171 mUseDebugOutput(false),
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400172 mSkipDrawCalls(false),
Martin Radev318f9aa2017-05-17 17:47:28 +0300173 mCapsInitialized(false),
174 mMultiviewImplementationType(MultiviewImplementationTypeGL::UNSPECIFIED)
Geoff Lang56cf9af2015-02-17 10:16:49 -0500175{
176 ASSERT(mFunctions);
Geoff Langcab7e1d2015-07-27 11:20:41 -0400177 nativegl_gl::GenerateWorkarounds(mFunctions, &mWorkarounds);
Martin Radev878c8b12017-07-28 09:51:04 +0300178 mStateManager = new StateManagerGL(mFunctions, getNativeCaps(), getNativeExtensions());
Jamie Madill231c7f52017-04-26 13:45:37 -0400179 mBlitter = new BlitGL(functions, mWorkarounds, mStateManager);
Geoff Langb80360f2015-05-04 15:01:31 -0400180
Jamie Madill222c5172017-07-19 16:15:42 -0400181 bool hasDebugOutput = mFunctions->isAtLeastGL(gl::Version(4, 3)) ||
182 mFunctions->hasGLExtension("GL_KHR_debug") ||
183 mFunctions->isAtLeastGLES(gl::Version(3, 2)) ||
184 mFunctions->hasGLESExtension("GL_KHR_debug");
185
186 mUseDebugOutput = hasDebugOutput && ShouldUseDebugLayers(attribMap);
187
188 if (mUseDebugOutput)
Geoff Langb80360f2015-05-04 15:01:31 -0400189 {
Corentin Wallez930fefc2016-09-14 15:54:18 -0400190 mFunctions->enable(GL_DEBUG_OUTPUT);
Geoff Langb80360f2015-05-04 15:01:31 -0400191 mFunctions->enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
Jamie Madill231c7f52017-04-26 13:45:37 -0400192 mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0,
193 nullptr, GL_TRUE);
194 mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM, 0,
195 nullptr, GL_TRUE);
196 mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0,
197 nullptr, GL_FALSE);
198 mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION,
199 0, nullptr, GL_FALSE);
Geoff Langb80360f2015-05-04 15:01:31 -0400200 mFunctions->debugMessageCallback(&LogGLDebugMessage, nullptr);
201 }
Jamie Madill39fcf262015-06-08 14:39:07 -0400202
Ian Ewellec2c0c52016-04-05 13:46:26 -0400203 EGLint deviceType =
204 static_cast<EGLint>(attribMap.get(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_NONE));
Jamie Madill39fcf262015-06-08 14:39:07 -0400205 if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE)
206 {
207 mSkipDrawCalls = true;
208 }
Corentin Wallez83144652016-08-31 17:03:30 -0400209
210 if (mWorkarounds.initializeCurrentVertexAttributes)
211 {
212 GLint maxVertexAttribs = 0;
213 mFunctions->getIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
214
215 for (GLint i = 0; i < maxVertexAttribs; ++i)
216 {
217 mFunctions->vertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 1.0f);
218 }
219 }
Geoff Lang56cf9af2015-02-17 10:16:49 -0500220}
Geoff Langf9a6f082015-01-22 13:32:49 -0500221
222RendererGL::~RendererGL()
Geoff Lang94463d52015-02-18 13:09:37 -0500223{
Geoff Lang53b8aec2015-08-24 10:33:25 -0400224 SafeDelete(mBlitter);
Geoff Langbf8a72f2015-11-03 16:34:45 -0500225 SafeDelete(mStateManager);
Geoff Lang94463d52015-02-18 13:09:37 -0500226}
Geoff Langf9a6f082015-01-22 13:32:49 -0500227
228gl::Error RendererGL::flush()
229{
Geoff Lang2c919142015-04-01 14:44:13 -0400230 mFunctions->flush();
He Yunchaoacd18982017-01-04 10:46:42 +0800231 return gl::NoError();
Geoff Langf9a6f082015-01-22 13:32:49 -0500232}
233
234gl::Error RendererGL::finish()
235{
Jamie Madill222c5172017-07-19 16:15:42 -0400236 if (mWorkarounds.finishDoesNotCauseQueriesToBeAvailable && mUseDebugOutput)
Geoff Langf0aa8422015-09-29 15:08:34 -0400237 {
238 mFunctions->enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
239 }
Geoff Langf0aa8422015-09-29 15:08:34 -0400240
Geoff Lang2c919142015-04-01 14:44:13 -0400241 mFunctions->finish();
Geoff Langf0aa8422015-09-29 15:08:34 -0400242
Jamie Madill222c5172017-07-19 16:15:42 -0400243 if (mWorkarounds.finishDoesNotCauseQueriesToBeAvailable && mUseDebugOutput)
Geoff Langf0aa8422015-09-29 15:08:34 -0400244 {
245 mFunctions->disable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
246 }
Geoff Langf0aa8422015-09-29 15:08:34 -0400247
He Yunchaoacd18982017-01-04 10:46:42 +0800248 return gl::NoError();
Geoff Langf9a6f082015-01-22 13:32:49 -0500249}
250
Jamie Madill4928b7c2017-06-20 12:57:39 -0400251gl::Error RendererGL::drawArrays(const gl::Context *context,
Jamie Madill9082b982016-04-27 15:21:51 -0400252 GLenum mode,
253 GLint first,
254 GLsizei count)
Geoff Langf9a6f082015-01-22 13:32:49 -0500255{
Martin Radev8f276e22017-05-30 12:05:52 +0300256 const gl::Program *program = context->getGLState().getProgram();
257 const bool usesMultiview = program->usesMultiview();
258 const GLsizei instanceCount = usesMultiview ? program->getNumViews() : 0;
Geoff Lang7c82bc42015-03-09 16:18:08 -0400259
Martin Radev8f276e22017-05-30 12:05:52 +0300260 ANGLE_TRY(mStateManager->setDrawArraysState(context, first, count, instanceCount));
Jamie Madill39fcf262015-06-08 14:39:07 -0400261 if (!mSkipDrawCalls)
262 {
Martin Radev8f276e22017-05-30 12:05:52 +0300263 if (!usesMultiview)
264 {
265 mFunctions->drawArrays(mode, first, count);
266 }
267 else
268 {
269 mFunctions->drawArraysInstanced(mode, first, count, instanceCount);
270 }
Jamie Madill39fcf262015-06-08 14:39:07 -0400271 }
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400272 return gl::NoError();
Geoff Langf9a6f082015-01-22 13:32:49 -0500273}
274
Jamie Madill4928b7c2017-06-20 12:57:39 -0400275gl::Error RendererGL::drawArraysInstanced(const gl::Context *context,
Geoff Langf6db0982015-08-25 13:04:00 -0400276 GLenum mode,
277 GLint first,
278 GLsizei count,
279 GLsizei instanceCount)
280{
Martin Radev8f276e22017-05-30 12:05:52 +0300281 GLsizei adjustedInstanceCount = instanceCount;
282 const gl::Program *program = context->getGLState().getProgram();
283 if (program->usesMultiview())
Geoff Lang3cf12ce2015-08-27 14:40:48 -0400284 {
Martin Radev8f276e22017-05-30 12:05:52 +0300285 adjustedInstanceCount *= program->getNumViews();
Geoff Lang3cf12ce2015-08-27 14:40:48 -0400286 }
287
Martin Radev8f276e22017-05-30 12:05:52 +0300288 ANGLE_TRY(mStateManager->setDrawArraysState(context, first, count, adjustedInstanceCount));
289 if (!mSkipDrawCalls)
290 {
291 mFunctions->drawArraysInstanced(mode, first, count, adjustedInstanceCount);
292 }
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400293 return gl::NoError();
Geoff Langf6db0982015-08-25 13:04:00 -0400294}
295
Jamie Madill4928b7c2017-06-20 12:57:39 -0400296gl::Error RendererGL::drawElements(const gl::Context *context,
Geoff Langf6db0982015-08-25 13:04:00 -0400297 GLenum mode,
298 GLsizei count,
299 GLenum type,
Qin Jiajia1da00652017-06-20 17:16:25 +0800300 const void *indices)
Geoff Langf9a6f082015-01-22 13:32:49 -0500301{
Martin Radev8f276e22017-05-30 12:05:52 +0300302 const gl::Program *program = context->getGLState().getProgram();
303 const bool usesMultiview = program->usesMultiview();
304 const GLsizei instanceCount = usesMultiview ? program->getNumViews() : 0;
Jamie Madill876429b2017-04-20 15:46:24 -0400305 const void *drawIndexPtr = nullptr;
Geoff Lang7c82bc42015-03-09 16:18:08 -0400306
Martin Radev8f276e22017-05-30 12:05:52 +0300307 ANGLE_TRY(mStateManager->setDrawElementsState(context, count, type, indices, instanceCount,
308 &drawIndexPtr));
Jamie Madill39fcf262015-06-08 14:39:07 -0400309 if (!mSkipDrawCalls)
310 {
Martin Radev8f276e22017-05-30 12:05:52 +0300311 if (!usesMultiview)
312 {
313 mFunctions->drawElements(mode, count, type, drawIndexPtr);
314 }
315 else
316 {
317 mFunctions->drawElementsInstanced(mode, count, type, drawIndexPtr, instanceCount);
318 }
Jamie Madill39fcf262015-06-08 14:39:07 -0400319 }
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400320 return gl::NoError();
Geoff Langf9a6f082015-01-22 13:32:49 -0500321}
322
Jamie Madill4928b7c2017-06-20 12:57:39 -0400323gl::Error RendererGL::drawElementsInstanced(const gl::Context *context,
Geoff Langf6db0982015-08-25 13:04:00 -0400324 GLenum mode,
325 GLsizei count,
326 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -0400327 const void *indices,
Qin Jiajia1da00652017-06-20 17:16:25 +0800328 GLsizei instances)
Geoff Langf6db0982015-08-25 13:04:00 -0400329{
Martin Radev8f276e22017-05-30 12:05:52 +0300330 GLsizei adjustedInstanceCount = instances;
331 const gl::Program *program = context->getGLState().getProgram();
332 if (program->usesMultiview())
333 {
334 adjustedInstanceCount *= program->getNumViews();
335 }
Jamie Madill876429b2017-04-20 15:46:24 -0400336 const void *drawIndexPointer = nullptr;
Geoff Lang3cf12ce2015-08-27 14:40:48 -0400337
Martin Radev8f276e22017-05-30 12:05:52 +0300338 ANGLE_TRY(mStateManager->setDrawElementsState(context, count, type, indices,
339 adjustedInstanceCount, &drawIndexPointer));
Geoff Lang3cf12ce2015-08-27 14:40:48 -0400340 if (!mSkipDrawCalls)
341 {
Martin Radev8f276e22017-05-30 12:05:52 +0300342 mFunctions->drawElementsInstanced(mode, count, type, drawIndexPointer,
343 adjustedInstanceCount);
Geoff Lang3cf12ce2015-08-27 14:40:48 -0400344 }
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400345 return gl::NoError();
Geoff Langf6db0982015-08-25 13:04:00 -0400346}
347
Jamie Madill4928b7c2017-06-20 12:57:39 -0400348gl::Error RendererGL::drawRangeElements(const gl::Context *context,
Geoff Langf6db0982015-08-25 13:04:00 -0400349 GLenum mode,
350 GLuint start,
351 GLuint end,
352 GLsizei count,
353 GLenum type,
Qin Jiajia1da00652017-06-20 17:16:25 +0800354 const void *indices)
Geoff Langf6db0982015-08-25 13:04:00 -0400355{
Martin Radev8f276e22017-05-30 12:05:52 +0300356 const gl::Program *program = context->getGLState().getProgram();
357 const bool usesMultiview = program->usesMultiview();
358 const GLsizei instanceCount = usesMultiview ? program->getNumViews() : 0;
Jamie Madill876429b2017-04-20 15:46:24 -0400359 const void *drawIndexPointer = nullptr;
Geoff Lang47502232015-08-25 16:26:10 -0400360
Martin Radev8f276e22017-05-30 12:05:52 +0300361 ANGLE_TRY(mStateManager->setDrawElementsState(context, count, type, indices, instanceCount,
362 &drawIndexPointer));
Geoff Lang47502232015-08-25 16:26:10 -0400363 if (!mSkipDrawCalls)
364 {
Martin Radev8f276e22017-05-30 12:05:52 +0300365 if (!usesMultiview)
366 {
367 mFunctions->drawRangeElements(mode, start, end, count, type, drawIndexPointer);
368 }
369 else
370 {
371 mFunctions->drawElementsInstanced(mode, count, type, drawIndexPointer, instanceCount);
372 }
Geoff Lang47502232015-08-25 16:26:10 -0400373 }
He Yunchaoacd18982017-01-04 10:46:42 +0800374 return gl::NoError();
Geoff Langf6db0982015-08-25 13:04:00 -0400375}
376
Jamie Madill4928b7c2017-06-20 12:57:39 -0400377gl::Error RendererGL::drawArraysIndirect(const gl::Context *context,
Jiajia Qind9671222016-11-29 16:30:31 +0800378 GLenum mode,
Jamie Madill876429b2017-04-20 15:46:24 -0400379 const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +0800380{
Jamie Madill4928b7c2017-06-20 12:57:39 -0400381 ANGLE_TRY(mStateManager->setDrawIndirectState(context, GL_NONE));
Jiajia Qind9671222016-11-29 16:30:31 +0800382
383 if (!mSkipDrawCalls)
384 {
385 mFunctions->drawArraysIndirect(mode, indirect);
386 }
387 return gl::NoError();
388}
389
Jamie Madill4928b7c2017-06-20 12:57:39 -0400390gl::Error RendererGL::drawElementsIndirect(const gl::Context *context,
Jiajia Qind9671222016-11-29 16:30:31 +0800391 GLenum mode,
392 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -0400393 const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +0800394{
Jamie Madill4928b7c2017-06-20 12:57:39 -0400395 ANGLE_TRY(mStateManager->setDrawIndirectState(context, type));
Jiajia Qind9671222016-11-29 16:30:31 +0800396
397 if (!mSkipDrawCalls)
398 {
399 mFunctions->drawElementsIndirect(mode, type, indirect);
400 }
401 return gl::NoError();
402}
403
Sami Väisänene45e53b2016-05-25 10:36:04 +0300404void RendererGL::stencilFillPath(const gl::ContextState &state,
405 const gl::Path *path,
406 GLenum fillMode,
407 GLuint mask)
408{
409 const auto *pathObj = GetImplAs<PathGL>(path);
410
411 mFunctions->stencilFillPathNV(pathObj->getPathID(), fillMode, mask);
412
413 ASSERT(mFunctions->getError() == GL_NO_ERROR);
414}
415
416void RendererGL::stencilStrokePath(const gl::ContextState &state,
417 const gl::Path *path,
418 GLint reference,
419 GLuint mask)
420{
421 const auto *pathObj = GetImplAs<PathGL>(path);
422
423 mFunctions->stencilStrokePathNV(pathObj->getPathID(), reference, mask);
424
425 ASSERT(mFunctions->getError() == GL_NO_ERROR);
426}
427
428void RendererGL::coverFillPath(const gl::ContextState &state,
429 const gl::Path *path,
430 GLenum coverMode)
431{
432
433 const auto *pathObj = GetImplAs<PathGL>(path);
434 mFunctions->coverFillPathNV(pathObj->getPathID(), coverMode);
435
436 ASSERT(mFunctions->getError() == GL_NO_ERROR);
437}
438
439void RendererGL::coverStrokePath(const gl::ContextState &state,
440 const gl::Path *path,
441 GLenum coverMode)
442{
443 const auto *pathObj = GetImplAs<PathGL>(path);
444 mFunctions->coverStrokePathNV(pathObj->getPathID(), coverMode);
445
446 ASSERT(mFunctions->getError() == GL_NO_ERROR);
447}
448
449void RendererGL::stencilThenCoverFillPath(const gl::ContextState &state,
450 const gl::Path *path,
451 GLenum fillMode,
452 GLuint mask,
453 GLenum coverMode)
454{
455
456 const auto *pathObj = GetImplAs<PathGL>(path);
457 mFunctions->stencilThenCoverFillPathNV(pathObj->getPathID(), fillMode, mask, coverMode);
458
459 ASSERT(mFunctions->getError() == GL_NO_ERROR);
460}
461
462void RendererGL::stencilThenCoverStrokePath(const gl::ContextState &state,
463 const gl::Path *path,
464 GLint reference,
465 GLuint mask,
466 GLenum coverMode)
467{
468
469 const auto *pathObj = GetImplAs<PathGL>(path);
470 mFunctions->stencilThenCoverStrokePathNV(pathObj->getPathID(), reference, mask, coverMode);
471
472 ASSERT(mFunctions->getError() == GL_NO_ERROR);
473}
474
Sami Väisänend59ca052016-06-21 16:10:00 +0300475void RendererGL::coverFillPathInstanced(const gl::ContextState &state,
476 const std::vector<gl::Path *> &paths,
477 GLenum coverMode,
478 GLenum transformType,
479 const GLfloat *transformValues)
480{
481 const auto &pathObjs = GatherPaths(paths);
482
483 mFunctions->coverFillPathInstancedNV(static_cast<GLsizei>(pathObjs.size()), GL_UNSIGNED_INT,
484 &pathObjs[0], 0, coverMode, transformType,
485 transformValues);
486
487 ASSERT(mFunctions->getError() == GL_NO_ERROR);
488}
489void RendererGL::coverStrokePathInstanced(const gl::ContextState &state,
490 const std::vector<gl::Path *> &paths,
491 GLenum coverMode,
492 GLenum transformType,
493 const GLfloat *transformValues)
494{
495 const auto &pathObjs = GatherPaths(paths);
496
497 mFunctions->coverStrokePathInstancedNV(static_cast<GLsizei>(pathObjs.size()), GL_UNSIGNED_INT,
498 &pathObjs[0], 0, coverMode, transformType,
499 transformValues);
500
501 ASSERT(mFunctions->getError() == GL_NO_ERROR);
502}
503void RendererGL::stencilFillPathInstanced(const gl::ContextState &state,
504 const std::vector<gl::Path *> &paths,
505 GLenum fillMode,
506 GLuint mask,
507 GLenum transformType,
508 const GLfloat *transformValues)
509{
510 const auto &pathObjs = GatherPaths(paths);
511
512 mFunctions->stencilFillPathInstancedNV(static_cast<GLsizei>(pathObjs.size()), GL_UNSIGNED_INT,
513 &pathObjs[0], 0, fillMode, mask, transformType,
514 transformValues);
515
516 ASSERT(mFunctions->getError() == GL_NO_ERROR);
517}
518void RendererGL::stencilStrokePathInstanced(const gl::ContextState &state,
519 const std::vector<gl::Path *> &paths,
520 GLint reference,
521 GLuint mask,
522 GLenum transformType,
523 const GLfloat *transformValues)
524{
525 const auto &pathObjs = GatherPaths(paths);
526
527 mFunctions->stencilStrokePathInstancedNV(static_cast<GLsizei>(pathObjs.size()), GL_UNSIGNED_INT,
528 &pathObjs[0], 0, reference, mask, transformType,
529 transformValues);
530
531 ASSERT(mFunctions->getError() == GL_NO_ERROR);
532}
533
534void RendererGL::stencilThenCoverFillPathInstanced(const gl::ContextState &state,
535 const std::vector<gl::Path *> &paths,
536 GLenum coverMode,
537 GLenum fillMode,
538 GLuint mask,
539 GLenum transformType,
540 const GLfloat *transformValues)
541{
542 const auto &pathObjs = GatherPaths(paths);
543
544 mFunctions->stencilThenCoverFillPathInstancedNV(
545 static_cast<GLsizei>(pathObjs.size()), GL_UNSIGNED_INT, &pathObjs[0], 0, fillMode, mask,
546 coverMode, transformType, transformValues);
547
548 ASSERT(mFunctions->getError() == GL_NO_ERROR);
549}
550void RendererGL::stencilThenCoverStrokePathInstanced(const gl::ContextState &state,
551 const std::vector<gl::Path *> &paths,
552 GLenum coverMode,
553 GLint reference,
554 GLuint mask,
555 GLenum transformType,
556 const GLfloat *transformValues)
557{
558 const auto &pathObjs = GatherPaths(paths);
559
560 mFunctions->stencilThenCoverStrokePathInstancedNV(
561 static_cast<GLsizei>(pathObjs.size()), GL_UNSIGNED_INT, &pathObjs[0], 0, reference, mask,
562 coverMode, transformType, transformValues);
563
564 ASSERT(mFunctions->getError() == GL_NO_ERROR);
565}
566
Corentin Wallezb920e362016-08-03 18:19:41 -0400567GLenum RendererGL::getResetStatus()
568{
569 return mFunctions->getGraphicsResetStatus();
570}
571
Jamie Madill8415b5f2016-04-26 13:41:39 -0400572ContextImpl *RendererGL::createContext(const gl::ContextState &state)
Jamie Madill437fa652016-05-03 15:13:24 -0400573{
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400574 return new ContextGL(state, this);
Geoff Lang0af0b812015-09-23 13:56:25 -0400575}
576
Geoff Langf6ade2e2015-09-29 11:21:43 -0400577void RendererGL::insertEventMarker(GLsizei length, const char *marker)
Austin Kinross6ee1e782015-05-29 17:05:37 -0700578{
Geoff Langf6ade2e2015-09-29 11:21:43 -0400579 mFunctions->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 0,
580 GL_DEBUG_SEVERITY_NOTIFICATION, length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -0700581}
582
Geoff Langf6ade2e2015-09-29 11:21:43 -0400583void RendererGL::pushGroupMarker(GLsizei length, const char *marker)
Austin Kinross6ee1e782015-05-29 17:05:37 -0700584{
Geoff Langf6ade2e2015-09-29 11:21:43 -0400585 mFunctions->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -0700586}
587
588void RendererGL::popGroupMarker()
589{
Geoff Langf6ade2e2015-09-29 11:21:43 -0400590 mFunctions->popDebugGroup();
Austin Kinross6ee1e782015-05-29 17:05:37 -0700591}
592
Geoff Langf9a6f082015-01-22 13:32:49 -0500593std::string RendererGL::getVendorString() const
594{
Jamie Madill231c7f52017-04-26 13:45:37 -0400595 return std::string(reinterpret_cast<const char *>(mFunctions->getString(GL_VENDOR)));
Geoff Langf9a6f082015-01-22 13:32:49 -0500596}
597
598std::string RendererGL::getRendererDescription() const
599{
Jamie Madill231c7f52017-04-26 13:45:37 -0400600 std::string nativeVendorString(
601 reinterpret_cast<const char *>(mFunctions->getString(GL_VENDOR)));
602 std::string nativeRendererString(
603 reinterpret_cast<const char *>(mFunctions->getString(GL_RENDERER)));
Geoff Lange42753b2015-04-08 13:46:33 -0400604
Geoff Lange42753b2015-04-08 13:46:33 -0400605 std::ostringstream rendererString;
606 rendererString << nativeVendorString << " " << nativeRendererString << " OpenGL";
Geoff Lang08dcfed2015-05-25 13:38:42 -0400607 if (mFunctions->standard == STANDARD_GL_ES)
Geoff Lange42753b2015-04-08 13:46:33 -0400608 {
609 rendererString << " ES";
610 }
Geoff Lang08dcfed2015-05-25 13:38:42 -0400611 rendererString << " " << mFunctions->version.major << "." << mFunctions->version.minor;
Geoff Lang8b0f0b32015-07-20 15:59:28 -0400612 if (mFunctions->standard == STANDARD_GL_DESKTOP)
613 {
614 // Some drivers (NVIDIA) use a profile mask of 0 when in compatibility profile.
615 if ((mFunctions->profile & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) != 0 ||
616 (mFunctions->isAtLeastGL(gl::Version(3, 2)) && mFunctions->profile == 0))
617 {
618 rendererString << " compatibility";
619 }
620 else if ((mFunctions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0)
621 {
622 rendererString << " core";
623 }
624 }
Geoff Lange42753b2015-04-08 13:46:33 -0400625
626 return rendererString.str();
Geoff Langf9a6f082015-01-22 13:32:49 -0500627}
628
Geoff Lang862c0ba2015-05-25 15:31:16 -0400629const gl::Version &RendererGL::getMaxSupportedESVersion() const
630{
631 // Force generation of caps
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400632 getNativeCaps();
Geoff Lang862c0ba2015-05-25 15:31:16 -0400633
634 return mMaxSupportedESVersion;
635}
636
Jamie Madill231c7f52017-04-26 13:45:37 -0400637void RendererGL::generateCaps(gl::Caps *outCaps,
638 gl::TextureCapsMap *outTextureCaps,
Austin Kinross02df7962015-07-01 10:03:42 -0700639 gl::Extensions *outExtensions,
640 gl::Limitations * /* outLimitations */) const
Geoff Langf9a6f082015-01-22 13:32:49 -0500641{
Shao86904b82017-03-21 09:30:59 +0800642 nativegl_gl::GenerateCaps(mFunctions, mWorkarounds, outCaps, outTextureCaps, outExtensions,
Martin Radev318f9aa2017-05-17 17:47:28 +0300643 &mMaxSupportedESVersion, &mMultiviewImplementationType);
Geoff Langf9a6f082015-01-22 13:32:49 -0500644}
645
Ian Ewell53f59f42016-01-28 17:36:55 -0500646GLint RendererGL::getGPUDisjoint()
647{
648 // TODO(ewell): On GLES backends we should find a way to reliably query disjoint events
649 return 0;
650}
651
652GLint64 RendererGL::getTimestamp()
653{
654 GLint64 result = 0;
655 mFunctions->getInteger64v(GL_TIMESTAMP, &result);
656 return result;
657}
Ian Ewell292f0052016-02-04 10:37:32 -0500658
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400659void RendererGL::ensureCapsInitialized() const
Ian Ewell292f0052016-02-04 10:37:32 -0500660{
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400661 if (!mCapsInitialized)
662 {
663 generateCaps(&mNativeCaps, &mNativeTextureCaps, &mNativeExtensions, &mNativeLimitations);
664 mCapsInitialized = true;
665 }
Ian Ewell292f0052016-02-04 10:37:32 -0500666}
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400667
668const gl::Caps &RendererGL::getNativeCaps() const
669{
670 ensureCapsInitialized();
671 return mNativeCaps;
Geoff Langf9a6f082015-01-22 13:32:49 -0500672}
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400673
674const gl::TextureCapsMap &RendererGL::getNativeTextureCaps() const
675{
676 ensureCapsInitialized();
677 return mNativeTextureCaps;
678}
679
680const gl::Extensions &RendererGL::getNativeExtensions() const
681{
682 ensureCapsInitialized();
683 return mNativeExtensions;
684}
685
686const gl::Limitations &RendererGL::getNativeLimitations() const
687{
688 ensureCapsInitialized();
689 return mNativeLimitations;
690}
691
Martin Radev318f9aa2017-05-17 17:47:28 +0300692MultiviewImplementationTypeGL RendererGL::getMultiviewImplementationType() const
693{
694 ensureCapsInitialized();
695 return mMultiviewImplementationType;
696}
697
Jamie Madill761b02c2017-06-23 16:27:06 -0400698void RendererGL::applyNativeWorkarounds(gl::Workarounds *workarounds) const
699{
700 ensureCapsInitialized();
701 nativegl_gl::ApplyWorkarounds(mFunctions, workarounds);
702}
703
Jamie Madill4928b7c2017-06-20 12:57:39 -0400704gl::Error RendererGL::dispatchCompute(const gl::Context *context,
Xinghua Cao2b396592017-03-29 15:36:04 +0800705 GLuint numGroupsX,
706 GLuint numGroupsY,
707 GLuint numGroupsZ)
708{
Jamie Madill4928b7c2017-06-20 12:57:39 -0400709 ANGLE_TRY(mStateManager->setDispatchComputeState(context));
Xinghua Cao2b396592017-03-29 15:36:04 +0800710 mFunctions->dispatchCompute(numGroupsX, numGroupsY, numGroupsZ);
711 return gl::NoError();
712}
713
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400714} // namespace rx