From: robertphillips@google.com Date: Wed, 28 Mar 2012 16:19:11 +0000 (+0000) Subject: Code changes for ANGLE GL interface. .gyp file changes will be delivered later. X-Git-Tag: accepted/tizen/5.0/unified/20181102.025319~16533 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d3b9fbbc48c13a1b2a664cf7e01374a44c201f51;p=platform%2Fupstream%2FlibSkiaSharp.git Code changes for ANGLE GL interface. .gyp file changes will be delivered later. http://codereview.appspot.com/5940046/ git-svn-id: http://skia.googlecode.com/svn/trunk@3519 2bbb7eff-a529-9590-31e7-b0007b416f81 --- diff --git a/bench/benchmain.cpp b/bench/benchmain.cpp index 32aace3..e8ff6e2 100644 --- a/bench/benchmain.cpp +++ b/bench/benchmain.cpp @@ -18,6 +18,9 @@ #include "SkGpuDevice.h" #include "SkGraphics.h" #include "SkImageEncoder.h" +#if SK_ANGLE +#include "gl/SkANGLEGLContext.h" +#endif #include "gl/SkNativeGLContext.h" #include "gl/SkNullGLContext.h" #include "gl/SkDebugGLContext.h" @@ -239,6 +242,9 @@ private: static GLHelper gRealGLHelper; static GLHelper gNullGLHelper; static GLHelper gDebugGLHelper; +#if SK_ANGLE +static GLHelper gANGLEGLHelper; +#endif static SkDevice* make_device(SkBitmap::Config config, const SkIPoint& size, Backend backend, GLHelper* glHelper) { @@ -272,6 +278,10 @@ static const struct { { SkBitmap::kARGB_8888_Config, "8888", kRaster_Backend, NULL }, { SkBitmap::kRGB_565_Config, "565", kRaster_Backend, NULL }, { SkBitmap::kARGB_8888_Config, "GPU", kGPU_Backend, &gRealGLHelper }, +#if SK_ANGLE + { SkBitmap::kARGB_8888_Config, "ANGLE", kGPU_Backend, &gANGLEGLHelper }, +#endif + { SkBitmap::kARGB_8888_Config, "Debug", kGPU_Backend, &gDebugGLHelper }, { SkBitmap::kARGB_8888_Config, "NULLGPU", kGPU_Backend, &gNullGLHelper }, }; @@ -521,9 +531,15 @@ int main (int argc, char * const argv[]) { SkAutoTUnref realGLCtx(new SkNativeGLContext); SkAutoTUnref nullGLCtx(new SkNullGLContext); SkAutoTUnref debugGLCtx(new SkDebugGLContext); +#if SK_ANGLE + SkAutoTUnref angleGLCtx(new SkANGLEGLContext); +#endif gRealGLHelper.init(realGLCtx.get(), contextWidth, contextHeight); gNullGLHelper.init(nullGLCtx.get(), contextWidth, contextHeight); gDebugGLHelper.init(debugGLCtx.get(), contextWidth, contextHeight); +#if SK_ANGLE + gANGLEGLHelper.init(angleGLCtx.get(), contextWidth, contextHeight); +#endif #endif BenchTimer timer = BenchTimer(gRealGLHelper.glContext()); diff --git a/gm/gmmain.cpp b/gm/gmmain.cpp index a8aa49c..76bd491 100644 --- a/gm/gmmain.cpp +++ b/gm/gmmain.cpp @@ -20,7 +20,12 @@ #include "SkImageDecoder.h" #include "SkImageEncoder.h" #include "gl/SkNativeGLContext.h" +#if SK_MESA #include "gl/SkMesaGLContext.h" +#endif +#if SK_ANGLE +#include "gl/SkANGLEGLContext.h" +#endif #include "gl/SkDebugGLContext.h" #include "SkPicture.h" #include "SkStream.h" @@ -612,6 +617,9 @@ static void usage(const char * argv0) { #if SK_MESA "[--mesagl]" #endif +#if SK_ANGLE + " [--angle]" +#endif " [--debuggl]\n\n", argv0); SkDebugf(" writePath: directory to write rendered images in.\n"); SkDebugf( @@ -625,11 +633,14 @@ static void usage(const char * argv0) { SkDebugf(" --forceBWtext: disable text anti-aliasing.\n"); SkDebugf(" --nopdf: skip the pdf rendering test pass.\n"); SkDebugf(" --nodeferred: skip the deferred rendering test pass.\n"); - SkDebugf(" --match foo will only run tests that substring match foo.\n"); + SkDebugf(" --match foo: will only run tests that substring match foo.\n"); #if SK_MESA - SkDebugf(" --mesagl will run using the osmesa sw gl rasterizer.\n"); + SkDebugf(" --mesagl: will run using the osmesa sw gl rasterizer.\n"); +#endif +#if SK_ANGLE + SkDebugf(" --angle: use ANGLE backend on Windows.\n"); #endif - SkDebugf(" --debuggl will run using the debugging gl utility.\n"); + SkDebugf(" --debuggl: will run using the debugging gl utility.\n"); SkDebugf(" --notexturecache: disable the gpu texture cache.\n"); } @@ -686,7 +697,12 @@ int main(int argc, char * const argv[]) { bool doPDF = true; bool doReplay = true; bool doSerialize = false; +#if SK_MESA bool useMesa = false; +#endif +#if SK_ANGLE + bool useAngle = false; +#endif bool useDebugGL = false; bool doDeferred = true; bool disableTextureCache = false; @@ -734,6 +750,10 @@ int main(int argc, char * const argv[]) { } else if (strcmp(*argv, "--mesagl") == 0) { useMesa = true; #endif +#if SK_ANGLE + } else if (strcmp(*argv, "--angle") == 0) { + useAngle = true; +#endif } else if (strcmp(*argv, "--debuggl") == 0) { useDebugGL = true; } else if (strcmp(*argv, "--notexturecache") == 0) { @@ -769,6 +789,11 @@ int main(int argc, char * const argv[]) { glContext.reset(new SkMesaGLContext()); } else #endif +#if SK_ANGLE + if (useAngle) { + glContext.reset(new SkANGLEGLContext()); + } else +#endif if (useDebugGL) { glContext.reset(new SkDebugGLContext()); } else { diff --git a/include/gpu/gl/GrGLInterface.h b/include/gpu/gl/GrGLInterface.h index 0ff3034..a9e722b 100644 --- a/include/gpu/gl/GrGLInterface.h +++ b/include/gpu/gl/GrGLInterface.h @@ -96,10 +96,19 @@ const GrGLInterface* GrGLDefaultInterface(); */ const GrGLInterface* GrGLCreateNativeInterface(); +#if SK_MESA /** * Creates a GrGLInterface for an OSMesa context. */ const GrGLInterface* GrGLCreateMesaInterface(); +#endif + +#if SK_ANGLE +/** + * Creates a GrGLInterface for an ANGLE context. + */ +const GrGLInterface* GrGLCreateANGLEInterface(); +#endif /** * Creates a null GrGLInterface that doesn't draw anything. Used for measuring diff --git a/include/gpu/gl/SkANGLEGLContext.h b/include/gpu/gl/SkANGLEGLContext.h new file mode 100644 index 0000000..10954c1 --- /dev/null +++ b/include/gpu/gl/SkANGLEGLContext.h @@ -0,0 +1,49 @@ + +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#ifndef SkANGLEGLContext_DEFINED +#define SkANGLEGLContext_DEFINED + +#if SK_ANGLE + +#include "SkGLContext.h" + +#include +#include + +class SkANGLEGLContext : public SkGLContext { +public: + SkANGLEGLContext(); + + virtual ~SkANGLEGLContext(); + + virtual void makeCurrent() const SK_OVERRIDE; + + class AutoContextRestore { + public: + AutoContextRestore(); + ~AutoContextRestore(); + + private: + angle::EGLContext fOldEGLContext; + angle::EGLDisplay fOldDisplay; + angle::EGLSurface fOldSurface; + }; + +protected: + virtual const GrGLInterface* createGLContext() SK_OVERRIDE; + virtual void destroyGLContext() SK_OVERRIDE; + +private: + angle::EGLContext fContext; + angle::EGLDisplay fDisplay; + angle::EGLSurface fSurface; +}; + +#endif + +#endif diff --git a/include/views/SkOSWindow_Win.h b/include/views/SkOSWindow_Win.h index bd6b4bd..c17807a 100644 --- a/include/views/SkOSWindow_Win.h +++ b/include/views/SkOSWindow_Win.h @@ -12,6 +12,10 @@ #include "SkWindow.h" +#if SK_ANGLE +#include "EGL/egl.h" +#endif + class SkOSWindow : public SkWindow { public: SkOSWindow(void* hwnd); @@ -27,6 +31,12 @@ public: void detachGL(); void presentGL(); +#if SK_ANGLE + bool attachANGLE(); + void detachANGLE(); + void presentANGLE(); +#endif + bool attachD3D9(); void detachD3D9(); void presentD3D9(); @@ -57,6 +67,11 @@ private: void doPaint(void* ctx); void* fHGLRC; +#if SK_ANGLE + angle::EGLDisplay fDisplay; + angle::EGLContext fContext; + angle::EGLSurface fSurface; +#endif bool fGLAttached; @@ -69,4 +84,3 @@ private: }; #endif - diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp index ddd33ed..dc522b6 100644 --- a/samplecode/SampleApp.cpp +++ b/samplecode/SampleApp.cpp @@ -130,7 +130,11 @@ static void writeTitleToPrefs(const char* title) { class SampleWindow::DefaultDeviceManager : public SampleWindow::DeviceManager { public: - DefaultDeviceManager() { + DefaultDeviceManager() +#if SK_ANGLE + : fUseAltContext(false) +#endif + { fGrRenderTarget = NULL; fGrContext = NULL; fGL = NULL; @@ -146,12 +150,32 @@ public: SkSafeUnref(fNullGrRenderTarget); } - virtual void init(SampleWindow* win) { - if (!win->attachGL()) { + virtual void init(SampleWindow* win, bool useAltContext) { +#if SK_ANGLE + fUseAltContext = useAltContext; +#endif + bool result; + +#if SK_ANGLE + if (useAltContext) { + result = win->attachANGLE(); + } else +#endif + { + result = win->attachGL(); + } + if (!result) { SkDebugf("Failed to initialize GL"); } if (NULL == fGL) { - fGL = GrGLCreateNativeInterface(); +#if SK_ANGLE + if (useAltContext) { + fGL = GrGLCreateANGLEInterface(); + } else +#endif + { + fGL = GrGLCreateNativeInterface(); + } GrAssert(NULL == fGrContext); fGrContext = GrContext::Create(kOpenGL_Shaders_GrEngine, (GrPlatform3DContext) fGL); @@ -160,7 +184,14 @@ public: SkSafeUnref(fGrContext); SkSafeUnref(fGL); SkDebugf("Failed to setup 3D"); - win->detachGL(); +#if SK_ANGLE + if (useAltContext) { + win->detachANGLE(); + } else +#endif + { + win->detachGL(); + } } if (NULL == fNullGrContext) { const GrGLInterface* nullGL = GrGLCreateNullInterface(); @@ -231,12 +262,26 @@ public: bm.rowBytes()); } } - win->presentGL(); +#if SK_ANGLE + if (fUseAltContext) { + win->presentANGLE(); + } else +#endif + { + win->presentGL(); + } } virtual void windowSizeChanged(SampleWindow* win) { if (fGrContext) { - win->attachGL(); +#if SK_ANGLE + if (fUseAltContext) { + win->attachANGLE(); + } else +#endif + { + win->attachGL(); + } GrPlatformRenderTargetDesc desc; desc.fWidth = SkScalarRound(win->width()); @@ -271,6 +316,9 @@ public: } } private: +#if SK_ANGLE + bool fUseAltContext; +#endif GrContext* fGrContext; const GrGLInterface* fGL; GrRenderTarget* fGrRenderTarget; @@ -621,6 +669,7 @@ SampleWindow::SampleWindow(void* hwnd, int argc, char** argv, DeviceManager* dev const char* resourcePath = NULL; fCurrIndex = -1; + bool useAltContext = false; const char* const commandName = argv[0]; char* const* stop = argv + argc; @@ -638,7 +687,14 @@ SampleWindow::SampleWindow(void* hwnd, int argc, char** argv, DeviceManager* dev fprintf(stderr, "Unknown sample \"%s\"\n", *argv); } } - } else { + } +#if SK_ANGLE + else if (strcmp(*argv, "--angle") == 0) { + argv++; + useAltContext = true; + } +#endif + else { usage(commandName); } } @@ -769,7 +825,7 @@ SampleWindow::SampleWindow(void* hwnd, int argc, char** argv, DeviceManager* dev devManager->ref(); fDevManager = devManager; } - fDevManager->init(this); + fDevManager->init(this, useAltContext); // If another constructor set our dimensions, ensure that our // onSizeChange gets called. diff --git a/samplecode/SampleApp.h b/samplecode/SampleApp.h index 871d47e..94f663f 100644 --- a/samplecode/SampleApp.h +++ b/samplecode/SampleApp.h @@ -48,7 +48,7 @@ public: class DeviceManager : public SkRefCnt { public: // called at end of SampleWindow cons - virtual void init(SampleWindow* win) = 0; + virtual void init(SampleWindow* win, bool useAltContext) = 0; // called when selecting a new device type // can disallow a device type by returning false. diff --git a/samplecode/SampleDegenerateTwoPtRadials.cpp b/samplecode/SampleDegenerateTwoPtRadials.cpp index 5b8f46d..2c08a81 100644 --- a/samplecode/SampleDegenerateTwoPtRadials.cpp +++ b/samplecode/SampleDegenerateTwoPtRadials.cpp @@ -66,7 +66,6 @@ protected: static const int DELTA_SCALE = 500; delta /= DELTA_SCALE; - SkRect rect; SkScalar w = SK_Scalar1 * 500; SkScalar h = SK_Scalar1 * 500; SkScalar l = SK_Scalar1 * 100; diff --git a/src/gpu/gl/angle/GrGLCreateANGLEInterface.cpp b/src/gpu/gl/angle/GrGLCreateANGLEInterface.cpp new file mode 100644 index 0000000..f2d31b8 --- /dev/null +++ b/src/gpu/gl/angle/GrGLCreateANGLEInterface.cpp @@ -0,0 +1,130 @@ + +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + + +#include "gl/GrGLInterface.h" + +#ifndef GL_GLEXT_PROTOTYPES +#define GL_GLEXT_PROTOTYPES +#endif + +#include "GLES2/gl2.h" +#include "GLES2/gl2ext.h" +#include "EGL/egl.h" + +const GrGLInterface* GrGLCreateANGLEInterface() { + static SkAutoTUnref glInterface; + if (!glInterface.get()) { + GrGLInterface* interface = new GrGLInterface; + glInterface.reset(interface); + interface->fBindingsExported = kES2_GrGLBinding; + interface->fActiveTexture = angle::glActiveTexture; + interface->fAttachShader = angle::glAttachShader; + interface->fBindAttribLocation = angle::glBindAttribLocation; + interface->fBindBuffer = angle::glBindBuffer; + interface->fBindTexture = angle::glBindTexture; + interface->fBlendColor = angle::glBlendColor; + interface->fBlendFunc = angle::glBlendFunc; + interface->fBufferData = angle::glBufferData; + interface->fBufferSubData = angle::glBufferSubData; + interface->fClear = angle::glClear; + interface->fClearColor = angle::glClearColor; + interface->fClearStencil = angle::glClearStencil; + interface->fColorMask = angle::glColorMask; + interface->fCompileShader = angle::glCompileShader; + interface->fCompressedTexImage2D = angle::glCompressedTexImage2D; + interface->fCreateProgram = angle::glCreateProgram; + interface->fCreateShader = angle::glCreateShader; + interface->fCullFace = angle::glCullFace; + interface->fDeleteBuffers = angle::glDeleteBuffers; + interface->fDeleteProgram = angle::glDeleteProgram; + interface->fDeleteShader = angle::glDeleteShader; + interface->fDeleteTextures = angle::glDeleteTextures; + interface->fDepthMask = angle::glDepthMask; + interface->fDisable = angle::glDisable; + interface->fDisableVertexAttribArray = angle::glDisableVertexAttribArray; + interface->fDrawArrays = angle::glDrawArrays; + interface->fDrawElements = angle::glDrawElements; + interface->fEnable = angle::glEnable; + interface->fEnableVertexAttribArray = angle::glEnableVertexAttribArray; + interface->fFinish = angle::glFinish; + interface->fFlush = angle::glFlush; + interface->fFrontFace = angle::glFrontFace; + interface->fGenBuffers = angle::glGenBuffers; + interface->fGenTextures = angle::glGenTextures; + interface->fGetBufferParameteriv = angle::glGetBufferParameteriv; + interface->fGetError = angle::glGetError; + interface->fGetIntegerv = angle::glGetIntegerv; + interface->fGetProgramInfoLog = angle::glGetProgramInfoLog; + interface->fGetProgramiv = angle::glGetProgramiv; + interface->fGetShaderInfoLog = angle::glGetShaderInfoLog; + interface->fGetShaderiv = angle::glGetShaderiv; + interface->fGetString = angle::glGetString; + interface->fGetUniformLocation = angle::glGetUniformLocation; + interface->fLineWidth = angle::glLineWidth; + interface->fLinkProgram = angle::glLinkProgram; + interface->fPixelStorei = angle::glPixelStorei; + interface->fReadPixels = angle::glReadPixels; + interface->fScissor = angle::glScissor; + interface->fShaderSource = angle::glShaderSource; + interface->fStencilFunc = angle::glStencilFunc; + interface->fStencilFuncSeparate = angle::glStencilFuncSeparate; + interface->fStencilMask = angle::glStencilMask; + interface->fStencilMaskSeparate = angle::glStencilMaskSeparate; + interface->fStencilOp = angle::glStencilOp; + interface->fStencilOpSeparate = angle::glStencilOpSeparate; + interface->fTexImage2D = angle::glTexImage2D; + interface->fTexParameteri = angle::glTexParameteri; + interface->fTexSubImage2D = angle::glTexSubImage2D; +#if GL_ARB_texture_storage + interface->fTexStorage2D = angle::glTexStorage2D; +#elif GL_EXT_texture_storage + interface->fTexStorage2D = angle::glTexStorage2DEXT; +#endif + interface->fUniform1f = angle::glUniform1f; + interface->fUniform1i = angle::glUniform1i; + interface->fUniform1fv = angle::glUniform1fv; + interface->fUniform1iv = angle::glUniform1iv; + interface->fUniform2f = angle::glUniform2f; + interface->fUniform2i = angle::glUniform2i; + interface->fUniform2fv = angle::glUniform2fv; + interface->fUniform2iv = angle::glUniform2iv; + interface->fUniform3f = angle::glUniform3f; + interface->fUniform3i = angle::glUniform3i; + interface->fUniform3fv = angle::glUniform3fv; + interface->fUniform3iv = angle::glUniform3iv; + interface->fUniform4f = angle::glUniform4f; + interface->fUniform4i = angle::glUniform4i; + interface->fUniform4fv = angle::glUniform4fv; + interface->fUniform4iv = angle::glUniform4iv; + interface->fUniformMatrix2fv = angle::glUniformMatrix2fv; + interface->fUniformMatrix3fv = angle::glUniformMatrix3fv; + interface->fUniformMatrix4fv = angle::glUniformMatrix4fv; + interface->fUseProgram = angle::glUseProgram; + interface->fVertexAttrib4fv = angle::glVertexAttrib4fv; + interface->fVertexAttribPointer = angle::glVertexAttribPointer; + interface->fViewport = angle::glViewport; + interface->fBindFramebuffer = angle::glBindFramebuffer; + interface->fBindRenderbuffer = angle::glBindRenderbuffer; + interface->fCheckFramebufferStatus = angle::glCheckFramebufferStatus; + interface->fDeleteFramebuffers = angle::glDeleteFramebuffers; + interface->fDeleteRenderbuffers = angle::glDeleteRenderbuffers; + interface->fFramebufferRenderbuffer = angle::glFramebufferRenderbuffer; + interface->fFramebufferTexture2D = angle::glFramebufferTexture2D; + interface->fGenFramebuffers = angle::glGenFramebuffers; + interface->fGenRenderbuffers = angle::glGenRenderbuffers; + interface->fGetFramebufferAttachmentParameteriv = angle::glGetFramebufferAttachmentParameteriv; + interface->fGetRenderbufferParameteriv = angle::glGetRenderbufferParameteriv; + interface->fRenderbufferStorage = angle::glRenderbufferStorage; + + interface->fMapBuffer = (angle::PFNGLMAPBUFFEROESPROC) angle::eglGetProcAddress("glMapBufferOES"); + interface->fUnmapBuffer = (angle::PFNGLUNMAPBUFFEROESPROC) angle::eglGetProcAddress("glUnmapBufferOES"); + } + glInterface.get()->ref(); + return glInterface.get(); +} \ No newline at end of file diff --git a/src/gpu/gl/angle/SkANGLEGLContext.cpp b/src/gpu/gl/angle/SkANGLEGLContext.cpp new file mode 100644 index 0000000..b2cfc1e --- /dev/null +++ b/src/gpu/gl/angle/SkANGLEGLContext.cpp @@ -0,0 +1,107 @@ + +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "gl/SkANGLEGLContext.h" + +SkANGLEGLContext::AutoContextRestore::AutoContextRestore() { + fOldEGLContext = angle::eglGetCurrentContext(); + fOldDisplay = angle::eglGetCurrentDisplay(); + fOldSurface = angle::eglGetCurrentSurface(EGL_DRAW); + +} + +SkANGLEGLContext::AutoContextRestore::~AutoContextRestore() { + if (NULL != fOldDisplay) { + angle::eglMakeCurrent(fOldDisplay, fOldSurface, fOldSurface, fOldEGLContext); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +SkANGLEGLContext::SkANGLEGLContext() + : fContext(EGL_NO_CONTEXT) + , fDisplay(EGL_NO_DISPLAY) + , fSurface(EGL_NO_SURFACE) { +} + +SkANGLEGLContext::~SkANGLEGLContext() { + this->destroyGLContext(); +} + +void SkANGLEGLContext::destroyGLContext() { + if (fDisplay) { + angle::eglMakeCurrent(fDisplay, 0, 0, 0); + + if (fContext) { + angle::eglDestroyContext(fDisplay, fContext); + fContext = EGL_NO_CONTEXT; + } + + if (fSurface) { + angle::eglDestroySurface(fDisplay, fSurface); + fSurface = EGL_NO_SURFACE; + } + + //TODO should we close the display? + fDisplay = EGL_NO_DISPLAY; + } +} + +const GrGLInterface* SkANGLEGLContext::createGLContext() { + + fDisplay = angle::eglGetDisplay(EGL_DEFAULT_DISPLAY); + + EGLint majorVersion; + EGLint minorVersion; + angle::eglInitialize(fDisplay, &majorVersion, &minorVersion); + + EGLint numConfigs; + static const EGLint configAttribs[] = { + EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_NONE + }; + + angle::EGLConfig surfaceConfig; + angle::eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs); + + static const EGLint contextAttribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE + }; + fContext = angle::eglCreateContext(fDisplay, surfaceConfig, NULL, contextAttribs); + + + static const EGLint surfaceAttribs[] = { + EGL_WIDTH, 1, + EGL_HEIGHT, 1, + EGL_NONE + }; + fSurface = angle::eglCreatePbufferSurface(fDisplay, surfaceConfig, surfaceAttribs); + + angle::eglMakeCurrent(fDisplay, fSurface, fSurface, fContext); + + const GrGLInterface* interface = GrGLCreateANGLEInterface(); + if (NULL == interface) { + SkDebugf("Could not create ANGLE GL interface!\n"); + this->destroyGLContext(); + return NULL; + } + + return interface; +} + +void SkANGLEGLContext::makeCurrent() const { + if (!angle::eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { + SkDebugf("Could not set the context.\n"); + } +} diff --git a/src/views/win/SkOSWindow_win.cpp b/src/views/win/SkOSWindow_win.cpp index c59821a..bf59e76 100644 --- a/src/views/win/SkOSWindow_win.cpp +++ b/src/views/win/SkOSWindow_win.cpp @@ -21,6 +21,10 @@ #include "SkGraphics.h" +#if SK_ANGLE +#include "GLES2/gl2.h" +#endif + #define INVALIDATE_DELAY_MS 200 static SkOSWindow* gCurrOSWin; @@ -33,8 +37,13 @@ void post_skwinevent() PostMessage(gEventTarget, WM_EVENT_CALLBACK, 0, 0); } -SkOSWindow::SkOSWindow(void* hWnd) : fHWND(hWnd), - fHGLRC(NULL), +SkOSWindow::SkOSWindow(void* hWnd) : fHWND(hWnd) +#if SK_ANGLE + , fDisplay(EGL_NO_DISPLAY) + , fContext(EGL_NO_CONTEXT) + , fSurface(EGL_NO_SURFACE) +#endif + , fHGLRC(NULL), fGLAttached(false), fD3D9Device(NULL), fD3D9Attached(FALSE) { @@ -48,6 +57,11 @@ SkOSWindow::~SkOSWindow() { if (NULL != fHGLRC) { wglDeleteContext((HGLRC)fHGLRC); } +#if SK_ANGLE + if (EGL_NO_DISPLAY != fDisplay) { + angle::eglDestroyContext(fDisplay, fContext); + } +#endif } static SkKey winToskKey(WPARAM vk) { @@ -381,6 +395,107 @@ void SkOSWindow::presentGL() { SwapBuffers(GetDC((HWND)fHWND)); } +#if SK_ANGLE +bool create_ANGLE(EGLNativeWindowType hWnd, angle::EGLDisplay* eglDisplay, + angle::EGLContext* eglContext, angle::EGLSurface* eglSurface) { + EGLint contextAttribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE, EGL_NONE + }; + EGLint configAttribList[] = { + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_DEPTH_SIZE, 8, + EGL_STENCIL_SIZE, 8, + EGL_NONE + }; + EGLint surfaceAttribList[] = { + EGL_NONE, EGL_NONE + }; + + angle::EGLDisplay display = angle::eglGetDisplay(GetDC(hWnd)); + if (display == EGL_NO_DISPLAY ) { + return false; + } + + // Initialize EGL + EGLint majorVersion, minorVersion; + if (!angle::eglInitialize(display, &majorVersion, &minorVersion)) { + return false; + } + + EGLint numConfigs; + if (!angle::eglGetConfigs(display, NULL, 0, &numConfigs)) { + return false; + } + + // Choose config + angle::EGLConfig config; + if (!angle::eglChooseConfig(display, configAttribList, + &config, 1, &numConfigs)) { + return false; + } + + // Create a surface + angle::EGLSurface surface = angle::eglCreateWindowSurface(display, config, + (EGLNativeWindowType)hWnd, + surfaceAttribList); + if (surface == EGL_NO_SURFACE) { + return false; + } + + // Create a GL context + angle::EGLContext context = angle::eglCreateContext(display, config, + EGL_NO_CONTEXT, + contextAttribs ); + if (context == EGL_NO_CONTEXT ) { + return false; + } + + // Make the context current + if (!angle::eglMakeCurrent(display, surface, surface, context)) { + return false; + } + + *eglDisplay = display; + *eglContext = context; + *eglSurface = surface; + return true; +} + +bool SkOSWindow::attachANGLE() { + if (EGL_NO_DISPLAY == fDisplay) { + bool bResult = create_ANGLE((HWND)fHWND, &fDisplay, &fContext, &fSurface); + if (false == bResult) { + return false; + } + angle::glClearStencil(0); + angle::glClearColor(0, 0, 0, 0); + angle::glStencilMask(0xffffffff); + angle::glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + } + if (angle::eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { + angle::glViewport(0, 0, SkScalarRound(this->width()), + SkScalarRound(this->height())); + fGLAttached = true; + return true; + } + return false; +} + +void SkOSWindow::detachANGLE() { + angle::eglMakeCurrent(fDisplay, EGL_NO_SURFACE , EGL_NO_SURFACE , EGL_NO_CONTEXT); + fGLAttached = false; +} + +void SkOSWindow::presentANGLE() { + angle::glFlush(); + angle::eglSwapBuffers(fDisplay, fSurface); +} +#endif + IDirect3DDevice9* create_d3d9_device(HWND hwnd) { HRESULT hr; @@ -490,3 +605,4 @@ void SkOSWindow::presentD3D9() { #endif + diff --git a/tests/GLInterfaceValidation.cpp b/tests/GLInterfaceValidation.cpp index 5cee0e4..9ca2cc2 100755 --- a/tests/GLInterfaceValidation.cpp +++ b/tests/GLInterfaceValidation.cpp @@ -7,8 +7,13 @@ */ #include "Test.h" +#if SK_ANGLE +#include "gl/SkANGLEGLContext.h" +#endif #include "gl/SkNativeGLContext.h" +#if SK_MESA #include "gl/SkMesaGLContext.h" +#endif static void GLInterfaceValidationTest(skiatest::Reporter* reporter) { typedef const GrGLInterface* (*interfaceFactory)(); @@ -16,10 +21,14 @@ static void GLInterfaceValidationTest(skiatest::Reporter* reporter) { interfaceFactory fFactory; const char* fName; } interfaceFactories[] = { +#if SK_ANGLE + {GrGLCreateANGLEInterface, "ANGLE"}, +#endif {GrGLCreateNativeInterface, "Native"}, #if SK_MESA {GrGLCreateMesaInterface, "Mesa"}, #endif + {GrGLCreateDebugInterface, "Debug"}, {GrGLCreateNullInterface, "Null"}, }; diff --git a/third_party/glu/README.skia b/third_party/glu/README.skia index 0b6b624..a6b10d9 100644 --- a/third_party/glu/README.skia +++ b/third_party/glu/README.skia @@ -39,3 +39,6 @@ The following changes were made in order to incorporate this code: - rename all __gl_ functions to Sk__gl_ to avoid conflicting with other static linkers of this library. + + - In sweep.c, added explicit cast to GLfloat in VertexWeights() to silence + compiler complaint diff --git a/third_party/glu/libtess/sweep.c b/third_party/glu/libtess/sweep.c index 6fe8a47..635a08c 100644 --- a/third_party/glu/libtess/sweep.c +++ b/third_party/glu/libtess/sweep.c @@ -465,8 +465,8 @@ static void VertexWeights( GLUvertex *isect, GLUvertex *org, GLUvertex *dst, GLdouble t1 = VertL1dist( org, isect ); GLdouble t2 = VertL1dist( dst, isect ); - weights[0] = 0.5 * t2 / (t1 + t2); - weights[1] = 0.5 * t1 / (t1 + t2); + weights[0] = (GLfloat)(0.5 * t2 / (t1 + t2)); + weights[1] = (GLfloat)(0.5 * t1 / (t1 + t2)); isect->coords[0] += weights[0]*org->coords[0] + weights[1]*dst->coords[0]; isect->coords[1] += weights[0]*org->coords[1] + weights[1]*dst->coords[1]; isect->coords[2] += weights[0]*org->coords[2] + weights[1]*dst->coords[2];