Cogs.Core
GraphicsDeviceGLES30.cpp
1#include "GraphicsDeviceGLES30.h"
2
3#include "FormatsGLES30.h"
4
5#include "Foundation/Platform/WindowData.h"
6
7#include "../Base/Utilities.h"
8
9namespace {
10 Cogs::Logging::Log logger = Cogs::Logging::getLogger("GraphicsDeviceGLES30");
11}
12
13Cogs::GraphicsDeviceGLES30::GraphicsDeviceGLES30(RenderingAllocatorInfo*)
14{
15}
16
17Cogs::GraphicsDeviceGLES30::~GraphicsDeviceGLES30()
18{
19 if (glContext.makeCurrent()) {
20 releaseResources();
21 glContext.destroy();
22 }
23}
24
26{
27 // TODO: True headless rendering (no window) is possible with EGL via a surfaceless
28 // context or a pbuffer surface — the EGL backend already handles a null windowHandle
29 // gracefully. Removing this guard and enabling the pbuffer path in EGLContext.cpp
30 // would be the main steps needed to support it.
31 if (reinterpret_cast<void*>(settings.windowData->windowHandle) == nullptr) {
32 LOG_ERROR(logger, "No window handle");
33 return false;
34 }
35 bool enableDiagnostics = isDebug() || ((settings.flags & GraphicsDeviceFlags::EnableDiagnostics) == GraphicsDeviceFlags::EnableDiagnostics);
36
37#ifdef __linux__
38 GLContext::NativeDisplay display = settings.windowData->display;
39#else
40 GLContext::NativeDisplay display = (GLContext::NativeDisplay)nullptr;
41#endif
42 if (!glContext.create(display, settings.windowData, nullptr, &settings, GLContext::Platform::ES3, enableDiagnostics)) {
43 return false;
44 }
45 glContext.makeCurrent();
46
47 bool useClipControl = (settings.flags & GraphicsDeviceFlags::UseOpenGLClipControl) != 0;
48#ifdef __EMSCRIPTEN__
49 if(!has_glClipControl()) useClipControl = false;
50#elif defined(__APPLE__)
51 useClipControl = false;
52#else
53 if(!glClipControl) useClipControl = false;
54#endif
55
56 capabilities.initialize(glContext.platform == GLContext::Platform::GL, useClipControl);
57 buffers.initialize(&capabilities, &context, &effects);
58 textures.initialize(&context, &capabilities);
59 context.initialize(&buffers, &textures, &effects, &renderTargets, &capabilities, &syncObjects);
60 renderTargets.initialize(this, &capabilities, &textures);
61 effects.initialize(&context, settings.fakeAsyncEffectLoadFrames);
62
63 if (settings.ioHandler) effects.setIOHandler(settings.ioHandler);
64
65#ifndef __APPLE__
66 if(useClipControl){
67 LOG_DEBUG(logger, "glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE)");
68 glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
69 }
70#endif
71
72 return true;
73}
74
75void Cogs::GraphicsDeviceGLES30::setSize(int width, int height)
76{
77 if (width == this->width && height == this->height) return;
78
79 this->width = width;
80 this->height = height;
81
82 LOG_TRACE(logger, "Resize(%d, %d)", width, height);
83
84 CHECKED(glViewport(0, 0, width, height));
85}
86
88{
89 glContext.makeCurrent();
90 glEnable(GL_DEPTH_TEST);
91
92 effects.beginFrame();
93 context.frameStatisticsBeginFrame();
94 context.setDefaults();
95}
96
97void Cogs::GraphicsDeviceGLES30::endFrame(uint32_t syncInterval, PresentFlags presentFlags)
98{
99 context.clearCachedState();
100 glContext.swapBuffers(syncInterval, presentFlags);
101
102 if (effects.delayFrames && effects.currentFrame < effects.allEffectsReadyFrame) requestRedraw();
103}
104
106{
107 effects.releaseResources();
108 renderTargets.releaseResources();
109 textures.releaseResources();
110 buffers.releaseResources();
111}
112
113Cogs::ResourceStatistics Cogs::GraphicsDeviceGLES30::getResourceStatistics()
114{
115 ResourceStatistics stats{};
116
117 buffers.updateResourceStatistics(stats);
118 stats.textureBytes = textures.textureMemoryConsumption;
119 stats.vertexArrayObjectCount = static_cast<uint32_t>(buffers.vertexArrayObjects.size());
120 stats.inputLayoutCount = static_cast<uint32_t>(buffers.inputLayouts.size());
121 stats.textureCount = static_cast<uint32_t>(textures.textures.size());
122 stats.samplerStateCount = 0;// static_cast<uint32_t>(textures.samplerStates.size());
123 stats.effectCount = static_cast<uint32_t>(effects.effects.size());
124 stats.blendStateCount = static_cast<uint32_t>(renderTargets.blendStates.size());
125 stats.rasterizerStateCount = static_cast<uint32_t>(renderTargets.rasterizerStates.size());
126 stats.depthStencilStateCount = static_cast<uint32_t>(renderTargets.depthStencilStates.size());
127 stats.rendertargetsCount = static_cast<uint32_t>(renderTargets.renderTargets.size());
128 stats.framebufferCount = 0;// static_cast<uint32_t>(renderTargets.framebuffers.size());
129
130 return stats;
131}
Log implementation class.
Definition: LogManager.h:140
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Definition: LogManager.h:181
PresentFlags
Flags controlling presentation.
Definition: Common.h:166
@ EnableDiagnostics
If available, the device will print diagnostic information to the log.
@ UseOpenGLClipControl
For OpenGL / OpenGLES backends.
bool initialize()
Initializes the graphics device with the settings previous set through calling setSettings.
void setSize(int width, int height) override
Set the size of the main drawing buffer used by the graphics device in pixels.
void endFrame(uint32_t syncInterval=0, PresentFlags presentFlags=PresentFlags::None) override
Signal the end of a frame to the graphics device.
void releaseResources() override
Release all resources allocated.
void beginFrame() override
Signal the beginning of a new frame to the graphics device.