1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #ifndef EGL_OS_API_H
17 #define EGL_OS_API_H
18
19 #include "aemu/base/Compiler.h"
20
21 #include <EGL/egl.h>
22 #include <EGL/eglext.h>
23
24 #include <memory>
25
26 #define PBUFFER_MAX_WIDTH 32767
27 #define PBUFFER_MAX_HEIGHT 32767
28 #define PBUFFER_MAX_PIXELS (PBUFFER_MAX_WIDTH * PBUFFER_MAX_HEIGHT)
29
30 class GlLibrary;
31
32 namespace EglOS {
33
34 // This header contains declaration used to abstract the underlying
35 // desktop GL library (or equivalent) that is being used by our EGL
36 // and GLES translation libraries.
37
38 // Use EglOS::Engine::getHostInstance() to retrieve an instance of the
39 // EglOS::Engine interface that matches the host display system.
40 //
41 // Alternate renderers (e.g. software-based Mesa) can also implement
42 // their own engine.
43
44 // Base class used to wrap various GL Surface types.
45 class Surface {
46 public:
47 typedef enum {
48 WINDOW = 0,
49 PBUFFER = 1,
50 } SurfaceType;
51
Surface(SurfaceType type)52 explicit Surface(SurfaceType type) : mType(type) {}
53
type()54 SurfaceType type() const { return mType; }
55
56 protected:
57 SurfaceType mType;
58 };
59
60 // An interface class for engine-specific implementation of a GL context.
61 class Context {
62 public:
mCoreProfile(coreProfile)63 Context(bool coreProfile = false) : mCoreProfile(coreProfile) {}
isCoreProfile()64 bool isCoreProfile() const {
65 return mCoreProfile;
66 }
67
68 // as of now, only osx has this non-nullptr, needed by media decoder
lowLevelContext()69 virtual void* lowLevelContext() { return nullptr; }
getNative()70 virtual void* getNative() { return nullptr; }
71
72 protected:
73 ~Context() = default;
74 private:
75 bool mCoreProfile = false;
76 };
77
78 // Base class used to wrap engine-specific pixel format descriptors.
79 class PixelFormat {
80 public:
PixelFormat()81 PixelFormat() {}
82
~PixelFormat()83 virtual ~PixelFormat() {}
84
85 virtual PixelFormat* clone() = 0;
86 };
87
88 // Small structure used to describe the properties of an engine-specific
89 // config.
90 struct ConfigInfo {
91 EGLint red_size;
92 EGLint green_size;
93 EGLint blue_size;
94 EGLint alpha_size;
95 EGLint alpha_mask_size = 0;
96 EGLenum caveat;
97 EGLint depth_size;
98 EGLint frame_buffer_level;
99 EGLint max_pbuffer_width;
100 EGLint max_pbuffer_height;
101 EGLint max_pbuffer_size;
102 EGLBoolean native_renderable;
103 EGLint renderable_type;
104 EGLint native_visual_id;
105 EGLint native_visual_type;
106 EGLint samples_per_pixel;
107 EGLint stencil_size;
108 EGLint surface_type;
109 EGLenum transparent_type;
110 EGLint trans_red_val;
111 EGLint trans_green_val;
112 EGLint trans_blue_val;
113 EGLBoolean recordable_android;
114 PixelFormat* frmt;
115 };
116
117 // A callback function type used with Display::queryConfig() to report to the
118 // caller a new host EGLConfig.
119 // |opaque| is an opaque value passed to queryConfig().
120 // All other parameters are config attributes.
121 // Note that ownership of |frmt| is transfered to the callback.
122 typedef void (AddConfigCallback)(void* opaque, const ConfigInfo* configInfo);
123
124 // Pbuffer description.
125 // |width| and |height| are its dimensions.
126 // |largest| is set to ask the largest pixek buffer (see GLX_LARGEST_PBUFFER).
127 // |format| is one of EGL_TEXTURE_RGB or EGL_TEXTURE_RGBA
128 // |target| is one of EGL_TEXTURE_2D or EGL_NO_TEXTURE.
129 // |hasMipmap| is true if the Pbuffer has mipmaps.
130 struct PbufferInfo {
131 EGLint width;
132 EGLint height;
133 EGLint largest;
134 EGLint format;
135 EGLint target;
136 EGLint hasMipmap;
137 };
138
139 enum class GlesVersion {
140 ES2 = 0,
141 ES30 = 1,
142 ES31 = 2,
143 ES32 = 3,
144 };
145
calcMaxESVersionFromCoreVersion(int coreMajor,int coreMinor)146 inline GlesVersion calcMaxESVersionFromCoreVersion(int coreMajor, int coreMinor) {
147 switch (coreMajor) {
148 case 3:
149 return coreMinor > 1 ? EglOS::GlesVersion::ES30 : EglOS::GlesVersion::ES2;
150 case 4:
151 // 4.3 core has all the entry points we need, but we want 4.5 core for
152 // ARB_ES31_compatibility to avoid shader translation (for now. TODO:
153 // translate ESSL 310 to 4.3 shaders)
154 return coreMinor > 4 ? EglOS::GlesVersion::ES31 : EglOS::GlesVersion::ES30;
155 default:
156 return EglOS::GlesVersion::ES2;
157 }
158 }
159
160 // A class to model the engine-specific implementation of a GL display
161 // connection.
162 class Display {
163 public:
164 Display() = default;
~Display()165 virtual ~Display() {}
166
167 virtual GlesVersion getMaxGlesVersion() = 0;
getExtensionString()168 virtual const char* getExtensionString() { return ""; }
getVendorString()169 virtual const char* getVendorString() { return "Google"; }
170
171 virtual void queryConfigs(int renderableType,
172 AddConfigCallback* addConfigFunc,
173 void* addConfigOpaque) = 0;
174
175 virtual bool isValidNativeWin(Surface* win) = 0;
176 virtual bool isValidNativeWin(EGLNativeWindowType win) = 0;
177
178 virtual bool checkWindowPixelFormatMatch(EGLNativeWindowType win,
179 const PixelFormat* pixelFormat,
180 unsigned int* width,
181 unsigned int* height) = 0;
182
183 virtual std::shared_ptr<Context> createContext(
184 EGLint profileMask,
185 const PixelFormat* pixelFormat,
186 Context* sharedContext) = 0;
187
188 virtual Surface* createPbufferSurface(
189 const PixelFormat* pixelFormat, const PbufferInfo* info) = 0;
190
createImageKHR(EGLDisplay,EGLContext,EGLenum,EGLClientBuffer,const EGLint * attribs)191 virtual EGLImage createImageKHR(
192 EGLDisplay,
193 EGLContext,
194 EGLenum,
195 EGLClientBuffer,
196 const EGLint* attribs) {
197 return (EGLImage)0;
198 }
199
destroyImageKHR(EGLDisplay,EGLImage)200 virtual EGLBoolean destroyImageKHR(
201 EGLDisplay,
202 EGLImage) { return EGL_FALSE; }
203
getNative()204 virtual EGLDisplay getNative() { return (EGLDisplay)0; }
205
206 virtual bool releasePbuffer(Surface* pb) = 0;
207
208 virtual bool makeCurrent(Surface* read,
209 Surface* draw,
210 Context* context) = 0;
211
212 virtual void swapBuffers(Surface* srfc) = 0;
213
releaseThread()214 virtual EGLBoolean releaseThread() { return EGL_TRUE; }
215
216 DISALLOW_COPY_AND_ASSIGN(Display);
217 };
218
219 // An interface class to model a specific underlying GL graphics subsystem
220 // or engine. Use getHost() to retrieve the implementation for the current
221 // host.
222 class Engine {
223 public:
224 Engine() = default;
~Engine()225 virtual ~Engine() {}
226
227 // Return a Display instance to the default display / window.
228 virtual Display* getDefaultDisplay() = 0;
229
230 // Return to engine-specific implementation of GlLibrary.
231 virtual GlLibrary* getGlLibrary() = 0;
232
233 // Return to engine-specific implementation of eglGetProcAddress.
234 virtual void* eglGetProcAddress(const char*) = 0;
235
236 // Return to engine-specific implementation of eglDebugMessageControlKHR.
eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback,const EGLAttrib * attribs)237 virtual EGLint eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback,
238 const EGLAttrib* attribs) {
239 return EGL_BAD_ATTRIBUTE;
240 }
241
242 // Create a new window surface. |wnd| is a host-specific window handle
243 // (e.g. a Windows HWND). A software renderer would always return NULL
244 // here.
245 virtual Surface* createWindowSurface(PixelFormat* cfg,
246 EGLNativeWindowType wnd) = 0;
247
248
249 // Retrieve the implementation for the current host. This can be called
250 // multiple times, and will initialize the engine on first call.
251 static Engine* getHostInstance();
252 };
253
254 // getEgl2EglHostInstance returns a host instance that is used to mount
255 // EGL/GLES translator on top of another EGL/GLES library
256 Engine* getEgl2EglHostInstance(bool nullEgl);
257
258 } // namespace EglOS
259
260 #endif // EGL_OS_API_H
261