Add an initial "she" implementation using a WGL context on Skia/Win port

This commit is contained in:
David Capello 2015-05-26 17:21:19 -03:00
parent 517e31c34b
commit 9dd8d0d120
7 changed files with 435 additions and 43 deletions

View File

@ -19,9 +19,19 @@ if(USE_ALLEG4_BACKEND)
endif() endif()
if(USE_SKIA_BACKEND) if(USE_SKIA_BACKEND)
set(SKIA_BUILD_DIR "" CACHE PATH "Skia build directory") set(SKIA_DIR "" CACHE PATH "Skia source code directory")
add_definitions(
-DSK_INTERNAL
-DSK_GAMMA_SRGB
-DSK_GAMMA_APPLY_TO_A8
-DSK_SCALAR_TO_FLOAT_EXCLUDED
-DSK_ALLOW_STATIC_GLOBAL_INITIALIZERS=1
-DSK_SUPPORT_GPU=1
-DSK_SUPPORT_OPENCL=0
-DSK_FORCE_DISTANCE_FIELD_TEXT=0
-DGR_GL_FUNCTION_TYPE=__stdcall)
add_definitions(-DSK_INTERNAL -DSK_GAMMA_SRGB -DSK_GAMMA_APPLY_TO_A8 -DSK_SCALAR_TO_FLOAT_EXCLUDED -DSK_ALLOW_STATIC_GLOBAL_INITIALIZERS=1 -DSK_SUPPORT_GPU=1 -DSK_SUPPORT_OPENCL=0 -DSK_FORCE_DISTANCE_FIELD_TEXT=0 -DGR_GL_FUNCTION_TYPE=__stdcall)
if(WIN32) if(WIN32)
add_definitions(-DSK_BUILD_FOR_WIN32) add_definitions(-DSK_BUILD_FOR_WIN32)
elseif(APPLE) elseif(APPLE)
@ -29,10 +39,10 @@ if(USE_SKIA_BACKEND)
endif() endif()
if(CMAKE_BUILD_TYPE STREQUAL Debug) if(CMAKE_BUILD_TYPE STREQUAL Debug)
set(SKIA_BUILD_OUT_DIR "${SKIA_BUILD_DIR}/out/Debug") set(SKIA_BUILD_OUT_DIR "${SKIA_DIR}/out/Debug")
add_definitions(-DSK_DEVELOPER=1) add_definitions(-DSK_DEVELOPER=1)
else() else()
set(SKIA_BUILD_OUT_DIR "${SKIA_BUILD_DIR}/out/Release") set(SKIA_BUILD_OUT_DIR "${SKIA_DIR}/out/Release")
endif() endif()
find_library(SKIA_CORE_LIBRARY skia_core PATH "${SKIA_BUILD_OUT_DIR}") find_library(SKIA_CORE_LIBRARY skia_core PATH "${SKIA_BUILD_OUT_DIR}")
@ -46,34 +56,46 @@ if(USE_SKIA_BACKEND)
find_library(SKIA_GPU_LIBRARY skia_skgpu PATH "${SKIA_BUILD_OUT_DIR}") find_library(SKIA_GPU_LIBRARY skia_skgpu PATH "${SKIA_BUILD_OUT_DIR}")
find_library(SKIA_UTILS_LIBRARY skia_utils PATH "${SKIA_BUILD_OUT_DIR}") find_library(SKIA_UTILS_LIBRARY skia_utils PATH "${SKIA_BUILD_OUT_DIR}")
set(SKIA_LIBEGL_LIBRARY "")
if(WIN32) if(WIN32)
find_library(ETC1_LIBRARY libetc1 PATH "${SKIA_BUILD_OUT_DIR}/obj/gyp") find_library(SKIA_ETC1_LIBRARY libetc1 PATH "${SKIA_BUILD_OUT_DIR}/obj/gyp")
find_library(LIBSKKTX_LIBRARY libSkKTX PATH "${SKIA_BUILD_OUT_DIR}/obj/gyp") find_library(SKIA_LIBSKKTX_LIBRARY libSkKTX PATH "${SKIA_BUILD_OUT_DIR}/obj/gyp")
find_library(OPENGL32_LIBRARY opengl32) find_library(SKIA_OPENGL32_LIBRARY opengl32)
find_library(SKIA_LIBEGL_LIBRARY libEGL.dll.lib PATH "${SKIA_BUILD_OUT_DIR}")
if(SKIA_LIBEGL_LIBRARY)
add_definitions(-DSK_ANGLE=1)
endif()
else() else()
set(ETC1_LIBRARY) set(SKIA_ETC1_LIBRARY)
set(LIBSKKTX_LIBRARY) set(SKIA_LIBSKKTX_LIBRARY)
# find_library(OPENGL32_LIBRARY glapi) # find_library(SKIA_OPENGL32_LIBRARY glapi)
set(OPENGL32_LIBRARY) set(SKIA_OPENGL32_LIBRARY)
endif() endif()
find_path(SKIA_CONFIG_INCLUDE_DIR SkUserConfig.h HINTS "${SKIA_BUILD_DIR}/include/config") find_path(SKIA_CONFIG_INCLUDE_DIR SkUserConfig.h HINTS "${SKIA_DIR}/include/config")
find_path(SKIA_CORE_INCLUDE_DIR SkCanvas.h HINTS "${SKIA_BUILD_DIR}/include/core") find_path(SKIA_CORE_INCLUDE_DIR SkCanvas.h HINTS "${SKIA_DIR}/include/core")
find_path(SKIA_EFFECTS_INCLUDE_DIR SkBitmapSource.h HINTS "${SKIA_BUILD_DIR}/include/effects") find_path(SKIA_EFFECTS_INCLUDE_DIR SkBitmapSource.h HINTS "${SKIA_DIR}/include/effects")
find_path(SKIA_GPU_INCLUDE_DIR SkGr.h HINTS "${SKIA_BUILD_DIR}/include/gpu") find_path(SKIA_GPU_INCLUDE_DIR SkGr.h HINTS "${SKIA_DIR}/include/gpu")
find_path(SKIA_UTILS_INCLUDE_DIR SkRandom.h HINTS "${SKIA_BUILD_DIR}/include/utils") find_path(SKIA_UTILS_INCLUDE_DIR SkRandom.h HINTS "${SKIA_DIR}/include/utils")
set(SKIA_ANGLE_INCLUDE_DIR "")
if(WIN32)
find_path(SKIA_ANGLE_INCLUDE_DIR angle_gl.h HINTS "${SKIA_DIR}/third_party/externals/angle2/include")
endif()
include_directories( include_directories(
${SKIA_CONFIG_INCLUDE_DIR} ${SKIA_CONFIG_INCLUDE_DIR}
${SKIA_CORE_INCLUDE_DIR} ${SKIA_CORE_INCLUDE_DIR}
${SKIA_GPU_INCLUDE_DIR} ${SKIA_GPU_INCLUDE_DIR}
${SKIA_PORTS_INCLUDE_DIR} ${SKIA_PORTS_INCLUDE_DIR}
${SKIA_UTILS_INCLUDE_DIR}) ${SKIA_UTILS_INCLUDE_DIR}
${SKIA_ANGLE_INCLUDE_DIR})
set(SKIA_LIBRARIES set(SKIA_LIBRARIES
${ETC1_LIBRARY} ${SKIA_ETC1_LIBRARY}
${LIBSKKTX_LIBRARY} ${SKIA_LIBSKKTX_LIBRARY}
${OPENGL32_LIBRARY} ${SKIA_OPENGL32_LIBRARY}
${SKIA_LIBEGL_LIBRARY}
${SKIA_CORE_LIBRARY} ${SKIA_CORE_LIBRARY}
${SKIA_EFFECTS_LIBRARY} ${SKIA_EFFECTS_LIBRARY}
${SKIA_GPU_LIBRARY} ${SKIA_GPU_LIBRARY}

View File

@ -0,0 +1,111 @@
// 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.
#include <windows.h>
#include "GL/gl.h"
#include "gl/SkGLContext.h"
namespace she {
class GLContextWGL : public SkGLContext {
public:
GLContextWGL(HWND hwnd, GrGLStandard forcedGpuAPI)
: m_hwnd(hwnd)
, m_glrc(nullptr) {
HDC hdc = GetDC(m_hwnd);
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1, // version number
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL, // support OpenGL
PFD_TYPE_RGBA, // RGBA type
24, // 24-bit color depth
0, 0, 0, 0, 0, 0, // color bits ignored
8, // 8-bit alpha buffer
0, // shift bit ignored
0, // no accumulation buffer
0, 0, 0, 0, // accum bits ignored
0, // no z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
};
int pixelFormat = ChoosePixelFormat(hdc, &pfd);
SetPixelFormat(hdc, pixelFormat, &pfd);
m_glrc = wglCreateContext(hdc);
if (!m_glrc) {
ReleaseDC(m_hwnd, hdc);
return;
}
wglMakeCurrent(hdc, m_glrc);
fGL.reset(GrGLCreateNativeInterface());
if (!fGL) {
ReleaseDC(m_hwnd, hdc);
destroy();
return;
}
if (!fGL->validate()) {
ReleaseDC(m_hwnd, hdc);
destroy();
return;
}
ReleaseDC(m_hwnd, hdc);
}
~GLContextWGL() {
destroy();
}
void makeCurrent() const override {
HDC hdc = GetDC(m_hwnd);
wglMakeCurrent(hdc, m_glrc);
ReleaseDC(m_hwnd, hdc);
}
void swapBuffers() const override {
HDC hdc = GetDC(m_hwnd);
SwapBuffers(hdc);
ReleaseDC(m_hwnd, hdc);
}
int getStencilBits() {
HDC hdc = GetDC(m_hwnd);
int pixelFormat = GetPixelFormat(hdc);
PIXELFORMATDESCRIPTOR pfd;
DescribePixelFormat(hdc, pixelFormat, sizeof(pfd), &pfd);
ReleaseDC(m_hwnd, hdc);
return pfd.cStencilBits;
}
int getSampleCount() {
return 0; // TODO
}
private:
void destroy() {
fGL.reset(nullptr);
if (m_glrc) {
wglMakeCurrent(nullptr, nullptr);
wglDeleteContext(m_glrc);
m_glrc = nullptr;
}
}
HWND m_hwnd;
HGLRC m_glrc;
};
} // namespace she

View File

@ -16,6 +16,7 @@ SkiaDisplay::SkiaDisplay(EventQueue* queue, int width, int height, int scale)
: m_queue(queue) : m_queue(queue)
, m_window(m_queue, this) , m_window(m_queue, this)
, m_surface(new SkiaSurface) , m_surface(new SkiaSurface)
, m_customSurface(false)
{ {
m_surface->create(width, height); m_surface->create(width, height);
m_window.setScale(scale); m_window.setScale(scale);
@ -23,8 +24,18 @@ SkiaDisplay::SkiaDisplay(EventQueue* queue, int width, int height, int scale)
m_recreated = false; m_recreated = false;
} }
void SkiaDisplay::setSkiaSurface(SkiaSurface* surface)
{
m_surface->dispose();
m_surface = surface;
m_customSurface = true;
}
void SkiaDisplay::resize(const gfx::Size& size) void SkiaDisplay::resize(const gfx::Size& size)
{ {
if (m_customSurface)
return;
m_surface->dispose(); m_surface->dispose();
m_surface = new SkiaSurface; m_surface = new SkiaSurface;
m_surface->create(size.w, size.h); m_surface->create(size.w, size.h);

View File

@ -24,6 +24,8 @@ class SkiaDisplay : public Display {
public: public:
SkiaDisplay(EventQueue* queue, int width, int height, int scale); SkiaDisplay(EventQueue* queue, int width, int height, int scale);
void setSkiaSurface(SkiaSurface* surface);
void resize(const gfx::Size& size); void resize(const gfx::Size& size);
void dispose() override; void dispose() override;
@ -63,6 +65,7 @@ private:
SkiaWindow m_window; SkiaWindow m_window;
SkiaSurface* m_surface; SkiaSurface* m_surface;
bool m_recreated; bool m_recreated;
bool m_customSurface;
}; };
} // namespace she } // namespace she

View File

@ -8,7 +8,6 @@
#define SHE_SKIA_SKIA_SURFACE_INCLUDED #define SHE_SKIA_SKIA_SURFACE_INCLUDED
#pragma once #pragma once
#include "base/unique_ptr.h"
#include "gfx/clip.h" #include "gfx/clip.h"
#include "she/common/font.h" #include "she/common/font.h"
#include "she/locked_surface.h" #include "she/locked_surface.h"
@ -20,6 +19,7 @@
#include "SkColorPriv.h" #include "SkColorPriv.h"
#include "SkImageInfo.h" #include "SkImageInfo.h"
#include "SkRegion.h" #include "SkRegion.h"
#include "SkSurface.h"
namespace she { namespace she {
@ -34,10 +34,25 @@ inline SkRect to_skia(const gfx::Rect& rc) {
class SkiaSurface : public NonDisposableSurface class SkiaSurface : public NonDisposableSurface
, public LockedSurface { , public LockedSurface {
public: public:
SkiaSurface() { SkiaSurface() : m_surface(nullptr)
, m_canvas(nullptr) {
}
SkiaSurface(SkSurface* surface)
: m_surface(surface)
, m_canvas(m_surface->getCanvas())
, m_clip(0, 0, width(), height())
{
}
~SkiaSurface() {
if (!m_surface)
delete m_canvas;
} }
void create(int width, int height) { void create(int width, int height) {
ASSERT(!m_surface);
m_bitmap.tryAllocPixels( m_bitmap.tryAllocPixels(
SkImageInfo::MakeN32Premul(width, height)); SkImageInfo::MakeN32Premul(width, height));
m_bitmap.eraseColor(SK_ColorTRANSPARENT); m_bitmap.eraseColor(SK_ColorTRANSPARENT);
@ -46,6 +61,8 @@ public:
} }
void createRgba(int width, int height) { void createRgba(int width, int height) {
ASSERT(!m_surface);
m_bitmap.tryAllocPixels( m_bitmap.tryAllocPixels(
SkImageInfo::MakeN32Premul(width, height)); SkImageInfo::MakeN32Premul(width, height));
m_bitmap.eraseColor(SK_ColorTRANSPARENT); m_bitmap.eraseColor(SK_ColorTRANSPARENT);
@ -53,6 +70,11 @@ public:
rebuild(); rebuild();
} }
void flush() {
if (m_canvas)
m_canvas->flush();
}
// Surface impl // Surface impl
void dispose() override { void dispose() override {
@ -60,11 +82,17 @@ public:
} }
int width() const override { int width() const override {
return m_bitmap.width(); if (m_surface)
return m_surface->width();
else
return m_bitmap.width();
} }
int height() const override { int height() const override {
return m_bitmap.height(); if (m_surface)
return m_surface->height();
else
return m_bitmap.height();
} }
bool isDirectToScreen() const override { bool isDirectToScreen() const override {
@ -96,6 +124,8 @@ public:
} }
void applyScale(int scaleFactor) override { void applyScale(int scaleFactor) override {
ASSERT(!m_surface);
SkBitmap result; SkBitmap result;
result.tryAllocPixels( result.tryAllocPixels(
SkImageInfo::MakeN32Premul(width()*scaleFactor, height()*scaleFactor)); SkImageInfo::MakeN32Premul(width()*scaleFactor, height()*scaleFactor));
@ -104,7 +134,7 @@ public:
paint.setXfermodeMode(SkXfermode::kSrc_Mode); paint.setXfermodeMode(SkXfermode::kSrc_Mode);
SkCanvas canvas(result); SkCanvas canvas(result);
SkRect srcRect = SkRect::Make(SkIRect::MakeXYWH(0, 0, m_bitmap.width(), m_bitmap.height())); SkRect srcRect = SkRect::Make(SkIRect::MakeXYWH(0, 0, width(), height()));
SkRect dstRect = SkRect::Make(SkIRect::MakeXYWH(0, 0, result.width(), result.height())); SkRect dstRect = SkRect::Make(SkIRect::MakeXYWH(0, 0, result.width(), result.height()));
canvas.drawBitmapRectToRect(m_bitmap, &srcRect, dstRect, &paint); canvas.drawBitmapRectToRect(m_bitmap, &srcRect, dstRect, &paint);
@ -118,11 +148,11 @@ public:
// LockedSurface impl // LockedSurface impl
int lockedWidth() const override { int lockedWidth() const override {
return m_bitmap.width(); return width();
} }
int lockedHeight() const override { int lockedHeight() const override {
return m_bitmap.height(); return height();
} }
void unlock() override { void unlock() override {
@ -130,6 +160,7 @@ public:
} }
void clear() override { void clear() override {
// TODO
} }
uint8_t* getData(int x, int y) const override { uint8_t* getData(int x, int y) const override {
@ -196,7 +227,19 @@ public:
} }
gfx::Color getPixel(int x, int y) const override { gfx::Color getPixel(int x, int y) const override {
SkColor c = m_bitmap.getColor(x, y); SkColor c = 0;
if (m_surface) {
// m_canvas->flush();
SkImageInfo dstInfo = SkImageInfo::MakeN32Premul(1, 1);
uint32_t dstPixels;
if (m_canvas->readPixels(dstInfo, &dstPixels, 4, x, y))
c = dstPixels;
}
else
c = m_bitmap.getColor(x, y);
return gfx::rgba( return gfx::rgba(
SkColorGetR(c), SkColorGetR(c),
SkColorGetG(c), SkColorGetG(c),
@ -250,21 +293,36 @@ public:
} }
void blitTo(LockedSurface* dest, int srcx, int srcy, int dstx, int dsty, int width, int height) const override { void blitTo(LockedSurface* dest, int srcx, int srcy, int dstx, int dsty, int width, int height) const override {
SkPaint paint; if (m_surface) {
paint.setXfermodeMode(SkXfermode::kSrc_Mode); // m_canvas->flush();
SkRect srcRect = SkRect::Make(SkIRect::MakeXYWH(srcx, srcy, width, height)); SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
SkRect dstRect = SkRect::Make(SkIRect::MakeXYWH(dstx, dsty, width, height)); std::vector<uint32_t> pixels(width * height * 4);
((SkiaSurface*)dest)->m_canvas->drawBitmapRectToRect(m_bitmap, &srcRect, dstRect, &paint); m_canvas->readPixels(info, (void*)&pixels[0], 4*width, srcx, srcy);
((SkiaSurface*)dest)->m_canvas->writePixels(info, (void*)&pixels[0], 4*width, dstx, dsty);
}
else {
SkPaint paint;
paint.setXfermodeMode(SkXfermode::kSrc_Mode);
SkRect srcRect = SkRect::Make(SkIRect::MakeXYWH(srcx, srcy, width, height));
SkRect dstRect = SkRect::Make(SkIRect::MakeXYWH(dstx, dsty, width, height));
((SkiaSurface*)dest)->m_canvas->drawBitmapRectToRect(m_bitmap, &srcRect, dstRect, &paint);
}
} }
void scrollTo(const gfx::Rect& rc, int dx, int dy) override { void scrollTo(const gfx::Rect& rc, int dx, int dy) override {
int w = m_bitmap.width(); int w = width();
int h = m_bitmap.height(); int h = height();
gfx::Clip clip(rc.x+dx, rc.y+dy, rc); gfx::Clip clip(rc.x+dx, rc.y+dy, rc);
if (!clip.clip(w, h, w, h)) if (!clip.clip(w, h, w, h))
return; return;
if (m_surface) {
blitTo(this, clip.src.x, clip.src.y, clip.dst.x, clip.dst.y, clip.size.w, clip.size.h);
return;
}
int bytesPerPixel = m_bitmap.bytesPerPixel(); int bytesPerPixel = m_bitmap.bytesPerPixel();
int rowBytes = (int)m_bitmap.rowBytes(); int rowBytes = (int)m_bitmap.rowBytes();
int rowDelta; int rowDelta;
@ -293,10 +351,10 @@ public:
void drawSurface(const LockedSurface* src, int dstx, int dsty) override { void drawSurface(const LockedSurface* src, int dstx, int dsty) override {
gfx::Clip clip(dstx, dsty, 0, 0, gfx::Clip clip(dstx, dsty, 0, 0,
((SkiaSurface*)src)->m_bitmap.width(), ((SkiaSurface*)src)->width(),
((SkiaSurface*)src)->m_bitmap.height()); ((SkiaSurface*)src)->height());
if (!clip.clip(m_bitmap.width(), m_bitmap.height(), clip.size.w, clip.size.h)) if (!clip.clip(width(), height(), clip.size.w, clip.size.h))
return; return;
SkRect srcRect = SkRect::Make(SkIRect::MakeXYWH(clip.src.x, clip.src.y, clip.size.w, clip.size.h)); SkRect srcRect = SkRect::Make(SkIRect::MakeXYWH(clip.src.x, clip.src.y, clip.size.w, clip.size.h));
@ -311,10 +369,10 @@ public:
void drawRgbaSurface(const LockedSurface* src, int dstx, int dsty) override { void drawRgbaSurface(const LockedSurface* src, int dstx, int dsty) override {
gfx::Clip clip(dstx, dsty, 0, 0, gfx::Clip clip(dstx, dsty, 0, 0,
((SkiaSurface*)src)->m_bitmap.width(), ((SkiaSurface*)src)->width(),
((SkiaSurface*)src)->m_bitmap.height()); ((SkiaSurface*)src)->height());
if (!clip.clip(m_bitmap.width(), m_bitmap.height(), clip.size.w, clip.size.h)) if (!clip.clip(width(), height(), clip.size.w, clip.size.h))
return; return;
SkRect srcRect = SkRect::Make(SkIRect::MakeXYWH(clip.src.x, clip.src.y, clip.size.w, clip.size.h)); SkRect srcRect = SkRect::Make(SkIRect::MakeXYWH(clip.src.x, clip.src.y, clip.size.w, clip.size.h));
@ -378,18 +436,24 @@ public:
} }
void swapBitmap(SkBitmap& other) { void swapBitmap(SkBitmap& other) {
ASSERT(!m_surface);
m_bitmap.swap(other); m_bitmap.swap(other);
rebuild(); rebuild();
} }
private: private:
void rebuild() { void rebuild() {
m_canvas.reset(new SkCanvas(m_bitmap)); ASSERT(!m_surface);
delete m_canvas;
m_canvas = new SkCanvas(m_bitmap);
m_clip = gfx::Rect(0, 0, width(), height()); m_clip = gfx::Rect(0, 0, width(), height());
} }
SkBitmap m_bitmap; SkBitmap m_bitmap;
base::UniquePtr<SkCanvas> m_canvas; SkSurface* m_surface;
SkCanvas* m_canvas;
gfx::Rect m_clip; gfx::Rect m_clip;
}; };

View File

@ -13,14 +13,45 @@
#include "she/event_queue.h" #include "she/event_queue.h"
#include "she/skia/skia_display.h" #include "she/skia/skia_display.h"
#if SK_SUPPORT_GPU
#include "GrContext.h"
#include "she/skia/gl_context_wgl.h"
#endif
namespace she { namespace she {
SkiaWindow::SkiaWindow(EventQueue* queue, SkiaDisplay* display) SkiaWindow::SkiaWindow(EventQueue* queue, SkiaDisplay* display)
: m_queue(queue) : m_queue(queue)
, m_display(display) , m_display(display)
, m_backend(Backend::NONE)
#if SK_SUPPORT_GPU
, m_sampleCount(0)
, m_stencilBits(0)
#endif
{ {
} }
SkiaWindow::~SkiaWindow()
{
switch (m_backend) {
case Backend::NONE:
// Do nothing
break;
#if SK_SUPPORT_GPU
case Backend::GL:
case Backend::ANGLE:
detachGL();
break;
#endif // SK_SUPPORT_GPU
}
}
void SkiaWindow::queueEventImpl(Event& ev) void SkiaWindow::queueEventImpl(Event& ev)
{ {
ev.setDisplay(m_display); ev.setDisplay(m_display);
@ -28,6 +59,37 @@ void SkiaWindow::queueEventImpl(Event& ev)
} }
void SkiaWindow::paintImpl(HDC hdc) void SkiaWindow::paintImpl(HDC hdc)
{
switch (m_backend) {
case Backend::NONE:
paintHDC(hdc);
break;
#if SK_SUPPORT_GPU
case Backend::GL:
case Backend::ANGLE:
// Flush operations to the SkCanvas
{
SkiaSurface* surface = static_cast<SkiaSurface*>(m_display->getSurface());
surface->flush();
}
// Flush GL context
m_grInterface->fFunctions.fFlush();
// We don't use double-buffer
//ASSERT(m_glCtx);
//if (m_glCtx)
// m_glCtx->swapBuffers();
break;
#endif // SK_SUPPORT_GPU
}
}
void SkiaWindow::paintHDC(HDC hdc)
{ {
SkiaSurface* surface = static_cast<SkiaSurface*>(m_display->getSurface()); SkiaSurface* surface = static_cast<SkiaSurface*>(m_display->getSurface());
const SkBitmap& bitmap = surface->bitmap(); const SkBitmap& bitmap = surface->bitmap();
@ -55,8 +117,96 @@ void SkiaWindow::paintImpl(HDC hdc)
bitmap.unlockPixels(); bitmap.unlockPixels();
} }
#if SK_SUPPORT_GPU
bool SkiaWindow::attachGL()
{
if (!m_glCtx) {
GLContextWGL* wglCtx = SkNEW_ARGS(GLContextWGL, (handle(), kGLES_GrGLStandard));
m_stencilBits = wglCtx->getStencilBits();
m_sampleCount = wglCtx->getSampleCount();
m_glCtx.reset(wglCtx);
ASSERT(m_glCtx->isValid());
if (!m_glCtx->isValid()) {
detachGL();
return false;
}
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();
return true;
}
else
return false;
}
#if SK_ANGLE
bool SkiaWindow::attachANGLE()
{
return false; // TODO
}
#endif // SK_ANGLE
void SkiaWindow::detachGL()
{
m_grCtx.reset(nullptr);
m_grInterface.reset(nullptr);
m_glCtx.reset(nullptr);
}
void SkiaWindow::createRenderTarget(const gfx::Size& size)
{
GrBackendRenderTargetDesc desc;
desc.fWidth = size.w / m_display->scale();
desc.fHeight = size.h / m_display->scale();
desc.fConfig = kSkia8888_GrPixelConfig;
desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
desc.fSampleCnt = m_sampleCount;
desc.fStencilBits = m_stencilBits;
GrGLint buffer;
m_grInterface->fFunctions.fGetIntegerv(0x8CA6, &buffer); // GL_FRAMEBUFFER_BINDING = 0x8CA6
desc.fRenderTargetHandle = buffer;
m_grRenderTarget.reset(m_grCtx->textureProvider()->wrapBackendRenderTarget(desc));
m_skSurface.reset(SkSurface::NewRenderTargetDirect(m_grRenderTarget));
m_display->setSkiaSurface(new SkiaSurface(m_skSurface));
}
#endif // SK_SUPPORT_GPU
void SkiaWindow::resizeImpl(const gfx::Size& size) void SkiaWindow::resizeImpl(const gfx::Size& size)
{ {
#if SK_SUPPORT_GPU
#if SK_ANGLE
if (attachANGLE()) {
m_backend = Backend::ANGLE;
}
else
#endif // SK_ANGLE
if (attachGL()) {
m_backend = Backend::GL;
}
else
#endif // SK_SUPPORT_GPU
{
#if SK_SUPPORT_GPU
detachGL();
#endif
m_backend = Backend::NONE;
}
if (m_glCtx)
createRenderTarget(size);
m_display->resize(size); m_display->resize(size);
} }

View File

@ -8,9 +8,14 @@
#define SHE_SKIA_SKIA_WINDOW_WIN_INCLUDED #define SHE_SKIA_SKIA_WINDOW_WIN_INCLUDED
#pragma once #pragma once
#include "base/disable_copying.h"
#include "she/skia/skia_surface.h" #include "she/skia/skia_surface.h"
#include "she/win/window.h" #include "she/win/window.h"
#if SK_SUPPORT_GPU
#include "gl/SkGLContext.h"
#endif
namespace she { namespace she {
class EventQueue; class EventQueue;
@ -18,15 +23,41 @@ class SkiaDisplay;
class SkiaWindow : public Window<SkiaWindow> { class SkiaWindow : public Window<SkiaWindow> {
public: public:
enum class Backend { NONE, GL, ANGLE };
SkiaWindow(EventQueue* queue, SkiaDisplay* display); SkiaWindow(EventQueue* queue, SkiaDisplay* display);
~SkiaWindow();
void queueEventImpl(Event& ev); void queueEventImpl(Event& ev);
void paintImpl(HDC hdc); void paintImpl(HDC hdc);
void resizeImpl(const gfx::Size& size); void resizeImpl(const gfx::Size& size);
private: private:
void paintHDC(HDC dc);
#if SK_SUPPORT_GPU
bool attachGL();
#if SK_ANGLE
bool attachANGLE();
#endif // SK_ANGLE
void detachGL();
void createRenderTarget(const gfx::Size& size);
#endif // SK_SUPPORT_GPU
EventQueue* m_queue; EventQueue* m_queue;
SkiaDisplay* m_display; SkiaDisplay* m_display;
Backend m_backend;
#if SK_SUPPORT_GPU
SkAutoTUnref<SkGLContext> m_glCtx;
SkAutoTUnref<const GrGLInterface> m_grInterface;
SkAutoTUnref<GrContext> m_grCtx;
SkAutoTUnref<GrRenderTarget> m_grRenderTarget;
SkAutoTDelete<SkSurface> m_skSurface;
int m_sampleCount;
int m_stencilBits;
#endif // SK_SUPPORT_GPU
DISABLE_COPYING(SkiaWindow);
}; };
} // namespace she } // namespace she