OLD | NEW |
(Empty) | |
| 1 |
| 2 /* |
| 3 * Copyright 2015 Google Inc. |
| 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. |
| 7 */ |
| 8 #include <EGL/egl.h> |
| 9 |
| 10 #include "SkOnce.h" |
| 11 #include "gl/GrGLInterface.h" |
| 12 #include "gl/GrGLAssembleInterface.h" |
| 13 #include "gl/command_buffer/SkCommandBufferGLContext.h" |
| 14 |
| 15 typedef EGLDisplay (*GetDisplayProc)(EGLNativeDisplayType display_id); |
| 16 typedef EGLBoolean (*InitializeProc)(EGLDisplay dpy, EGLint *major, EGLint *mino
r); |
| 17 typedef EGLBoolean (*TerminateProc)(EGLDisplay dpy); |
| 18 typedef EGLBoolean (*ChooseConfigProc)(EGLDisplay dpy, const EGLint* attrib_list
, EGLConfig* configs, EGLint config_size, EGLint* num_config); |
| 19 typedef EGLBoolean (*GetConfigAttrib)(EGLDisplay dpy, EGLConfig config, EGLint a
ttribute, EGLint* value); |
| 20 typedef EGLSurface (*CreateWindowSurfaceProc)(EGLDisplay dpy, EGLConfig config,
EGLNativeWindowType win, const EGLint* attrib_list); |
| 21 typedef EGLSurface (*CreatePbufferSurfaceProc)(EGLDisplay dpy, EGLConfig config,
const EGLint* attrib_list); |
| 22 typedef EGLBoolean (*DestroySurfaceProc)(EGLDisplay dpy, EGLSurface surface); |
| 23 typedef EGLContext (*CreateContextProc)(EGLDisplay dpy, EGLConfig config, EGLCon
text share_context, const EGLint* attrib_list); |
| 24 typedef EGLBoolean (*DestroyContextProc)(EGLDisplay dpy, EGLContext ctx); |
| 25 typedef EGLBoolean (*MakeCurrentProc)(EGLDisplay dpy, EGLSurface draw, EGLSurfac
e read, EGLContext ctx); |
| 26 typedef EGLBoolean (*SwapBuffersProc)(EGLDisplay dpy, EGLSurface surface); |
| 27 typedef __eglMustCastToProperFunctionPointerType (*GetProcAddressProc)(const cha
r* procname); |
| 28 |
| 29 static GetDisplayProc gfGetDisplay = nullptr; |
| 30 static InitializeProc gfInitialize = nullptr; |
| 31 static TerminateProc gfTerminate = nullptr; |
| 32 static ChooseConfigProc gfChooseConfig = nullptr; |
| 33 static GetConfigAttrib gfGetConfigAttrib = nullptr; |
| 34 static CreateWindowSurfaceProc gfCreateWindowSurface = nullptr; |
| 35 static CreatePbufferSurfaceProc gfCreatePbufferSurface = nullptr; |
| 36 static DestroySurfaceProc gfDestroySurface = nullptr; |
| 37 static CreateContextProc gfCreateContext = nullptr; |
| 38 static DestroyContextProc gfDestroyContext = nullptr; |
| 39 static MakeCurrentProc gfMakeCurrent = nullptr; |
| 40 static SwapBuffersProc gfSwapBuffers = nullptr; |
| 41 static GetProcAddressProc gfGetProcAddress = nullptr; |
| 42 |
| 43 static HMODULE ghLibrary = nullptr; |
| 44 static bool gfFunctionsLoadedSuccessfully = false; |
| 45 |
| 46 static void load_command_buffer_functions() { |
| 47 if (!ghLibrary) { |
| 48 ghLibrary = LoadLibrary("command_buffer_gles2.dll"); |
| 49 |
| 50 if (ghLibrary) { |
| 51 gfGetDisplay = (GetDisplayProc)::GetProcAddress(ghLibrary, "CommandB
uffer_GetDisplay"); |
| 52 gfInitialize = (InitializeProc)::GetProcAddress(ghLibrary, "CommandB
uffer_Initialize"); |
| 53 gfTerminate = (TerminateProc)::GetProcAddress(ghLibrary, "CommandBuf
fer_Terminate"); |
| 54 gfChooseConfig = (ChooseConfigProc)::GetProcAddress(ghLibrary, "Comm
andBuffer_ChooseConfig"); |
| 55 gfGetConfigAttrib = (GetConfigAttrib)::GetProcAddress(ghLibrary, "Co
mmandBuffer_GetConfigAttrib"); |
| 56 gfCreateWindowSurface = (CreateWindowSurfaceProc)::GetProcAddress(gh
Library, "CommandBuffer_CreateWindowSurface"); |
| 57 gfCreatePbufferSurface = (CreatePbufferSurfaceProc)::GetProcAddress(
ghLibrary, "CommandBuffer_CreatePbufferSurface"); |
| 58 gfDestroySurface = (DestroySurfaceProc)::GetProcAddress(ghLibrary, "
CommandBuffer_DestroySurface"); |
| 59 gfCreateContext = (CreateContextProc)::GetProcAddress(ghLibrary, "Co
mmandBuffer_CreateContext"); |
| 60 gfDestroyContext = (DestroyContextProc)::GetProcAddress(ghLibrary, "
CommandBuffer_DestroyContext"); |
| 61 gfMakeCurrent = (MakeCurrentProc)::GetProcAddress(ghLibrary, "Comman
dBuffer_MakeCurrent"); |
| 62 gfSwapBuffers = (SwapBuffersProc)::GetProcAddress(ghLibrary, "Comman
dBuffer_SwapBuffers"); |
| 63 gfGetProcAddress = (GetProcAddressProc)::GetProcAddress(ghLibrary, "
CommandBuffer_GetProcAddress"); |
| 64 |
| 65 gfFunctionsLoadedSuccessfully = gfGetDisplay && gfInitialize && gfTe
rminate && |
| 66 gfChooseConfig && gfCreateWindowSurf
ace && |
| 67 gfCreatePbufferSurface && gfDestroyS
urface && |
| 68 gfCreateContext && gfDestroyContext
&& gfMakeCurrent && |
| 69 gfSwapBuffers && gfGetProcAddress; |
| 70 |
| 71 } |
| 72 } |
| 73 } |
| 74 |
| 75 static GrGLFuncPtr command_buffer_get_gl_proc(void* ctx, const char name[]) { |
| 76 GrGLFuncPtr proc = (GrGLFuncPtr) GetProcAddress((HMODULE)ctx, name); |
| 77 if (proc) { |
| 78 return proc; |
| 79 } |
| 80 if (!gfFunctionsLoadedSuccessfully) { |
| 81 return nullptr; |
| 82 } |
| 83 return gfGetProcAddress(name); |
| 84 } |
| 85 |
| 86 SK_DECLARE_STATIC_ONCE(loadCommandBufferOnce); |
| 87 void LoadCommandBufferOnce() { |
| 88 SkOnce(&loadCommandBufferOnce, load_command_buffer_functions); |
| 89 } |
| 90 |
| 91 const GrGLInterface* GrGLCreateCommandBufferInterface() { |
| 92 LoadCommandBufferOnce(); |
| 93 if (!gfFunctionsLoadedSuccessfully) { |
| 94 return nullptr; |
| 95 } |
| 96 return GrGLAssembleGLESInterface(ghLibrary, command_buffer_get_gl_proc); |
| 97 } |
| 98 |
| 99 SkCommandBufferGLContext::SkCommandBufferGLContext() |
| 100 : fContext(EGL_NO_CONTEXT) |
| 101 , fDisplay(EGL_NO_DISPLAY) |
| 102 , fSurface(EGL_NO_SURFACE) { |
| 103 |
| 104 static const EGLint configAttribs[] = { |
| 105 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, |
| 106 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
| 107 EGL_RED_SIZE, 8, |
| 108 EGL_GREEN_SIZE, 8, |
| 109 EGL_BLUE_SIZE, 8, |
| 110 EGL_ALPHA_SIZE, 8, |
| 111 EGL_NONE |
| 112 }; |
| 113 |
| 114 static const EGLint surfaceAttribs[] = { |
| 115 EGL_WIDTH, 1, |
| 116 EGL_HEIGHT, 1, |
| 117 EGL_NONE |
| 118 }; |
| 119 |
| 120 initializeGLContext(nullptr, configAttribs, surfaceAttribs); |
| 121 } |
| 122 |
| 123 SkCommandBufferGLContext::SkCommandBufferGLContext(void* nativeWindow, int msaaS
ampleCount) { |
| 124 static const EGLint surfaceAttribs[] = { EGL_NONE }; |
| 125 |
| 126 EGLint configAttribs[] = { |
| 127 EGL_RED_SIZE, 8, |
| 128 EGL_GREEN_SIZE, 8, |
| 129 EGL_BLUE_SIZE, 8, |
| 130 EGL_ALPHA_SIZE, 8, |
| 131 EGL_DEPTH_SIZE, 8, |
| 132 EGL_STENCIL_SIZE, 8, |
| 133 EGL_SAMPLE_BUFFERS, 1, |
| 134 EGL_SAMPLES, msaaSampleCount, |
| 135 EGL_NONE |
| 136 }; |
| 137 if (msaaSampleCount == 0) { |
| 138 configAttribs[12] = EGL_NONE; |
| 139 } |
| 140 |
| 141 initializeGLContext(nativeWindow, configAttribs, surfaceAttribs); |
| 142 } |
| 143 |
| 144 void SkCommandBufferGLContext::initializeGLContext(void* nativeWindow, const int
* configAttribs, |
| 145 const int* surfaceAttribs) { |
| 146 LoadCommandBufferOnce(); |
| 147 if (!gfFunctionsLoadedSuccessfully) { |
| 148 return; |
| 149 } |
| 150 |
| 151 fDisplay = gfGetDisplay(static_cast<EGLNativeDisplayType>(EGL_DEFAULT_DISPLA
Y)); |
| 152 if (EGL_NO_DISPLAY == fDisplay) { |
| 153 SkDebugf("Could not create EGL display!"); |
| 154 return; |
| 155 } |
| 156 |
| 157 EGLint majorVersion; |
| 158 EGLint minorVersion; |
| 159 gfInitialize(fDisplay, &majorVersion, &minorVersion); |
| 160 |
| 161 EGLConfig surfaceConfig = static_cast<EGLConfig>(fConfig); |
| 162 EGLint numConfigs; |
| 163 gfChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs); |
| 164 |
| 165 if (nativeWindow) { |
| 166 fSurface = gfCreateWindowSurface(fDisplay, surfaceConfig, |
| 167 (EGLNativeWindowType)nativeWindow, surf
aceAttribs); |
| 168 } else { |
| 169 fSurface = gfCreatePbufferSurface(fDisplay, surfaceConfig, surfaceAttrib
s); |
| 170 } |
| 171 |
| 172 static const EGLint contextAttribs[] = { |
| 173 EGL_CONTEXT_CLIENT_VERSION, 2, |
| 174 EGL_NONE |
| 175 }; |
| 176 fContext = gfCreateContext(fDisplay, surfaceConfig, nullptr, contextAttribs)
; |
| 177 |
| 178 gfMakeCurrent(fDisplay, fSurface, fSurface, fContext); |
| 179 |
| 180 SkAutoTUnref<const GrGLInterface> gl(GrGLCreateCommandBufferInterface()); |
| 181 if (nullptr == gl.get()) { |
| 182 SkDebugf("Could not create CommandBuffer GL interface!\n"); |
| 183 this->destroyGLContext(); |
| 184 return; |
| 185 } |
| 186 if (!gl->validate()) { |
| 187 SkDebugf("Could not validate CommandBuffer GL interface!\n"); |
| 188 this->destroyGLContext(); |
| 189 return; |
| 190 } |
| 191 |
| 192 this->init(gl.detach()); |
| 193 } |
| 194 |
| 195 SkCommandBufferGLContext::~SkCommandBufferGLContext() { |
| 196 this->teardown(); |
| 197 this->destroyGLContext(); |
| 198 } |
| 199 |
| 200 void SkCommandBufferGLContext::destroyGLContext() { |
| 201 if (!gfFunctionsLoadedSuccessfully) { |
| 202 return; |
| 203 } |
| 204 if (fDisplay) { |
| 205 gfMakeCurrent(fDisplay, 0, 0, 0); |
| 206 |
| 207 if (fContext) { |
| 208 gfDestroyContext(fDisplay, fContext); |
| 209 fContext = EGL_NO_CONTEXT; |
| 210 } |
| 211 |
| 212 if (fSurface) { |
| 213 gfDestroySurface(fDisplay, fSurface); |
| 214 fSurface = EGL_NO_SURFACE; |
| 215 } |
| 216 |
| 217 gfTerminate(fDisplay); |
| 218 fDisplay = EGL_NO_DISPLAY; |
| 219 } |
| 220 } |
| 221 |
| 222 void SkCommandBufferGLContext::onPlatformMakeCurrent() const { |
| 223 if (!gfFunctionsLoadedSuccessfully) { |
| 224 return; |
| 225 } |
| 226 if (!gfMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { |
| 227 SkDebugf("Could not set the context.\n"); |
| 228 } |
| 229 } |
| 230 |
| 231 void SkCommandBufferGLContext::onPlatformSwapBuffers() const { |
| 232 if (!gfFunctionsLoadedSuccessfully) { |
| 233 return; |
| 234 } |
| 235 if (!gfSwapBuffers(fDisplay, fSurface)) { |
| 236 SkDebugf("Could not complete gfSwapBuffers.\n"); |
| 237 } |
| 238 } |
| 239 |
| 240 GrGLFuncPtr SkCommandBufferGLContext::onPlatformGetProcAddress(const char* name)
const { |
| 241 if (!gfFunctionsLoadedSuccessfully) { |
| 242 return nullptr; |
| 243 } |
| 244 return gfGetProcAddress(name); |
| 245 } |
| 246 |
| 247 void SkCommandBufferGLContext::presentCommandBuffer() { |
| 248 if (this->gl()) { |
| 249 this->gl()->fFunctions.fFlush(); |
| 250 } |
| 251 |
| 252 this->onPlatformSwapBuffers(); |
| 253 } |
| 254 |
| 255 bool SkCommandBufferGLContext::makeCurrent() { |
| 256 return gfMakeCurrent(fDisplay, fSurface, fSurface, fContext) != EGL_FALSE; |
| 257 } |
| 258 |
| 259 int SkCommandBufferGLContext::getStencilBits() { |
| 260 EGLint result = 0; |
| 261 EGLConfig surfaceConfig = static_cast<EGLConfig>(fConfig); |
| 262 gfGetConfigAttrib(fDisplay, surfaceConfig, EGL_STENCIL_SIZE, &result); |
| 263 return result; |
| 264 } |
| 265 |
| 266 int SkCommandBufferGLContext::getSampleCount() { |
| 267 EGLint result = 0; |
| 268 EGLConfig surfaceConfig = static_cast<EGLConfig>(fConfig); |
| 269 gfGetConfigAttrib(fDisplay, surfaceConfig, EGL_SAMPLES, &result); |
| 270 return result; |
| 271 } |
OLD | NEW |