Replace SkGLContext with our own GLContext class

This commit is contained in:
David Capello 2015-10-06 16:37:01 -03:00
parent 9e44818cd8
commit 066a8dffcc
7 changed files with 214 additions and 78 deletions

24
src/she/gl/gl_context.h Normal file
View File

@ -0,0 +1,24 @@
// SHE library
// Copyright (C) 2015 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef SHE_GL_CONTEXT_INCLUDED
#define SHE_GL_CONTEXT_INCLUDED
#pragma once
namespace she {
class GLContext {
public:
virtual ~GLContext() { }
virtual bool createGLContext() = 0;
virtual void destroyGLContext() = 0;
virtual int getStencilBits() = 0;
virtual int getSampleCount() = 0;
};
} // namespace she
#endif

View File

@ -0,0 +1,75 @@
// SHE library
// Copyright (C) 2015 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef SHE_GL_CONTEXT_CGL_INCLUDED
#define SHE_GL_CONTEXT_CGL_INCLUDED
#pragma once
#include "she/gl/gl_context.h"
#include <OpenGL/OpenGL.h>
#include <dlfcn.h>
namespace she {
class GLContextCGL : public GLContext {
public:
typedef void* NativeHandle;
GLContextCGL(void*)
: m_glctx(nullptr) {
}
~GLContextCGL() {
destroyGLContext();
}
bool createGLContext() override {
CGLPixelFormatAttribute attributes[] = {
#if MAC_OS_X_VERSION_10_7
kCGLPFAOpenGLProfile,
(CGLPixelFormatAttribute)kCGLOGLPVersion_3_2_Core,
#endif
kCGLPFADoubleBuffer,
(CGLPixelFormatAttribute)0
};
CGLPixelFormatObj pixFormat;
GLint npix;
CGLChoosePixelFormat(attributes, &pixFormat, &npix);
if (!pixFormat)
return false;
CGLCreateContext(pixFormat, nullptr, &m_glctx);
CGLReleasePixelFormat(pixFormat);
if (!m_glctx)
return false;
CGLSetCurrentContext(m_glctx);
return true;
}
void destroyGLContext() override {
if (m_glctx) {
CGLReleaseContext(m_glctx);
m_glctx = nullptr;
}
}
int getStencilBits() override {
return 0;
}
int getSampleCount() override {
return 0;
}
private:
CGLContextObj m_glctx;
};
} // namespace she
#endif

View File

@ -1,21 +1,33 @@
// SHE library
// Copyright (C) 2012-2015 David Capello
// Copyright (C) 2015 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#include <windows.h>
#ifndef SHE_GL_CONTEXT_WGL_INCLUDED
#define SHE_GL_CONTEXT_WGL_INCLUDED
#pragma once
#include "GL/gl.h"
#include "gl/SkGLContext.h"
#include "she/gl/gl_context.h"
#include <windows.h>
namespace she {
class GLContextWGL : public SkGLContext {
class GLContextWGL : public GLContext {
public:
GLContextWGL(HWND hwnd, GrGLStandard forcedGpuAPI)
typedef HWND NativeHandle;
GLContextWGL(HWND hwnd)
: m_hwnd(hwnd)
, m_glrc(nullptr) {
}
~GLContextWGL() {
destroyGLContext();
}
bool createGLContext() override {
HDC hdc = GetDC(m_hwnd);
PIXELFORMATDESCRIPTOR pfd = {
@ -43,49 +55,23 @@ public:
m_glrc = wglCreateContext(hdc);
if (!m_glrc) {
ReleaseDC(m_hwnd, hdc);
return;
return false;
}
wglMakeCurrent(hdc, m_glrc);
ReleaseDC(m_hwnd, hdc);
return true;
}
const GrGLInterface* gl = GrGLCreateNativeInterface();
init(gl);
if (!gl) {
ReleaseDC(m_hwnd, hdc);
destroy();
return;
void destroyGLContext() override {
if (m_glrc) {
wglMakeCurrent(nullptr, nullptr);
wglDeleteContext(m_glrc);
m_glrc = nullptr;
}
if (!gl->validate()) {
ReleaseDC(m_hwnd, hdc);
destroy();
return;
}
ReleaseDC(m_hwnd, hdc);
}
~GLContextWGL() {
destroy();
}
void onPlatformMakeCurrent() const override {
HDC hdc = GetDC(m_hwnd);
wglMakeCurrent(hdc, m_glrc);
ReleaseDC(m_hwnd, hdc);
}
void onPlatformSwapBuffers() const override {
HDC hdc = GetDC(m_hwnd);
SwapBuffers(hdc);
ReleaseDC(m_hwnd, hdc);
}
GrGLFuncPtr onPlatformGetProcAddress(const char* name) const override {
return reinterpret_cast<GrGLFuncPtr>(wglGetProcAddress(name));
}
int getStencilBits() {
int getStencilBits() override {
HDC hdc = GetDC(m_hwnd);
int pixelFormat = GetPixelFormat(hdc);
PIXELFORMATDESCRIPTOR pfd;
@ -94,23 +80,15 @@ public:
return pfd.cStencilBits;
}
int getSampleCount() {
return 0; // TODO
int getSampleCount() override {
return 0;
}
private:
void destroy() {
teardown();
if (m_glrc) {
wglMakeCurrent(nullptr, nullptr);
wglDeleteContext(m_glrc);
m_glrc = nullptr;
}
}
HWND m_hwnd;
HGLRC m_glrc;
};
} // namespace she
#endif

View File

@ -0,0 +1,55 @@
// SHE library
// Copyright (C) 2012-2015 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef SHE_SKIA_GL_CONTEXT_INCLUDED
#define SHE_SKIA_GL_CONTEXT_INCLUDED
#pragma once
#ifndef SK_SUPPORT_GPU
#error Skia was compiled without GPU support
#endif
#include "gl/GrGLInterface.h"
#include <stdexcept>
namespace she {
template<typename Base>
class GLContextSkia : public Base {
public:
GLContextSkia(typename Base::NativeHandle nativeHandle) : Base(nativeHandle) {
Base::createGLContext();
if (!createSkiaInterfaces()) {
Base::destroyGLContext();
throw std::runtime_error("Cannot create OpenGL context");
}
}
~GLContextSkia() {
m_gl.reset(nullptr);
}
const GrGLInterface* gl() const {
return m_gl.get();
}
private:
bool createSkiaInterfaces() {
SkAutoTUnref<const GrGLInterface> gl(GrGLCreateNativeInterface());
if (!gl || !gl->validate())
return false;
m_gl.reset(gl.detach());
return true;
}
SkAutoTUnref<const GrGLInterface> m_gl;
};
} // namespace she
#endif

View File

@ -14,6 +14,14 @@
#include "she/osx/window.h"
#include "gfx/size.h"
#if SK_SUPPORT_GPU
#include "GrContext.h"
#include "she/gl/gl_context_cgl.h"
#include "she/skia/gl_context_skia.h"
#endif
namespace she {
class SkiaWindow::Impl : public CloseDelegate {
@ -21,8 +29,9 @@ public:
bool closing;
int scale;
OSXWindow* window;
GLContextSkia<GLContextCGL> gl;
Impl() {
Impl() : gl(nullptr) {
closing = false;
scale = 1;
window = [OSXWindow new];

View File

@ -17,7 +17,7 @@
#if SK_SUPPORT_GPU
#include "GrContext.h"
#include "she/skia/gl_context_wgl.h"
#include "she/gl/gl_context_wgl.h"
#endif
@ -105,7 +105,7 @@ void SkiaWindow::paintImpl(HDC hdc)
}
// Flush GL context
m_grInterface->fFunctions.fFlush();
m_glCtx->gl()->fFunctions.fFlush();
break;
#endif // SK_SUPPORT_GPU
@ -145,26 +145,23 @@ void SkiaWindow::paintHDC(HDC hdc)
bool SkiaWindow::attachGL()
{
if (!m_glCtx) {
GLContextWGL* wglCtx = new GLContextWGL(handle(), kGLES_GrGLStandard);
m_stencilBits = wglCtx->getStencilBits();
m_sampleCount = wglCtx->getSampleCount();
try {
auto wglCtx = new GLContextSkia<GLContextWGL>(handle());
m_stencilBits = wglCtx->getStencilBits();
m_sampleCount = wglCtx->getSampleCount();
m_glCtx.reset(wglCtx);
ASSERT(m_glCtx->isValid());
if (!m_glCtx->isValid()) {
detachGL();
return false;
m_glCtx.reset(wglCtx);
m_grCtx.reset(GrContext::Create(kOpenGL_GrBackend,
(GrBackendContext)m_glCtx->gl()));
}
catch (const std::exception& ex) {
LOG("Cannot create GL context: %s\n", ex.what());
detachGL();
}
m_grInterface.reset(SkRef(m_glCtx->gl()));
m_grInterface.reset(GrGLInterfaceRemoveNVPR(m_grInterface));
m_grCtx.reset(GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)m_grInterface.get()));
}
if (m_glCtx) {
m_glCtx->makeCurrent();
if (m_glCtx)
return true;
}
else
return false;
}
@ -184,14 +181,11 @@ void SkiaWindow::detachGL()
m_skSurface.reset(nullptr);
m_grRenderTarget.reset(nullptr);
m_grCtx.reset(nullptr);
m_grInterface.reset(nullptr);
m_glCtx.reset(nullptr);
}
void SkiaWindow::createRenderTarget(const gfx::Size& size)
{
auto gl = &m_grInterface->fFunctions;
int scale = m_display->scale();
m_lastSize = size;

View File

@ -9,11 +9,13 @@
#pragma once
#include "base/disable_copying.h"
#include "base/unique_ptr.h"
#include "she/skia/skia_surface.h"
#include "she/win/window.h"
#if SK_SUPPORT_GPU
#include "gl/SkGLContext.h"
#include "she/gl/gl_context_wgl.h"
#include "she/skia/gl_context_skia.h"
#endif
namespace she {
@ -48,8 +50,7 @@ private:
SkiaDisplay* m_display;
Backend m_backend;
#if SK_SUPPORT_GPU
SkAutoTUnref<SkGLContext> m_glCtx;
SkAutoTUnref<const GrGLInterface> m_grInterface;
base::UniquePtr<GLContextSkia<GLContextWGL> > m_glCtx;
SkAutoTUnref<GrContext> m_grCtx;
SkAutoTUnref<GrRenderTarget> m_grRenderTarget;
SkAutoTDelete<SkSurface> m_skSurfaceDirect;