mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-06 03:39:51 +00:00
Add an initial "she" implementation using a WGL context on Skia/Win port
This commit is contained in:
parent
517e31c34b
commit
9dd8d0d120
@ -19,9 +19,19 @@ if(USE_ALLEG4_BACKEND)
|
||||
endif()
|
||||
|
||||
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)
|
||||
add_definitions(-DSK_BUILD_FOR_WIN32)
|
||||
elseif(APPLE)
|
||||
@ -29,10 +39,10 @@ if(USE_SKIA_BACKEND)
|
||||
endif()
|
||||
|
||||
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)
|
||||
else()
|
||||
set(SKIA_BUILD_OUT_DIR "${SKIA_BUILD_DIR}/out/Release")
|
||||
set(SKIA_BUILD_OUT_DIR "${SKIA_DIR}/out/Release")
|
||||
endif()
|
||||
|
||||
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_UTILS_LIBRARY skia_utils PATH "${SKIA_BUILD_OUT_DIR}")
|
||||
|
||||
set(SKIA_LIBEGL_LIBRARY "")
|
||||
if(WIN32)
|
||||
find_library(ETC1_LIBRARY libetc1 PATH "${SKIA_BUILD_OUT_DIR}/obj/gyp")
|
||||
find_library(LIBSKKTX_LIBRARY libSkKTX PATH "${SKIA_BUILD_OUT_DIR}/obj/gyp")
|
||||
find_library(OPENGL32_LIBRARY opengl32)
|
||||
find_library(SKIA_ETC1_LIBRARY libetc1 PATH "${SKIA_BUILD_OUT_DIR}/obj/gyp")
|
||||
find_library(SKIA_LIBSKKTX_LIBRARY libSkKTX PATH "${SKIA_BUILD_OUT_DIR}/obj/gyp")
|
||||
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()
|
||||
set(ETC1_LIBRARY)
|
||||
set(LIBSKKTX_LIBRARY)
|
||||
# find_library(OPENGL32_LIBRARY glapi)
|
||||
set(OPENGL32_LIBRARY)
|
||||
set(SKIA_ETC1_LIBRARY)
|
||||
set(SKIA_LIBSKKTX_LIBRARY)
|
||||
# find_library(SKIA_OPENGL32_LIBRARY glapi)
|
||||
set(SKIA_OPENGL32_LIBRARY)
|
||||
endif()
|
||||
|
||||
find_path(SKIA_CONFIG_INCLUDE_DIR SkUserConfig.h HINTS "${SKIA_BUILD_DIR}/include/config")
|
||||
find_path(SKIA_CORE_INCLUDE_DIR SkCanvas.h HINTS "${SKIA_BUILD_DIR}/include/core")
|
||||
find_path(SKIA_EFFECTS_INCLUDE_DIR SkBitmapSource.h HINTS "${SKIA_BUILD_DIR}/include/effects")
|
||||
find_path(SKIA_GPU_INCLUDE_DIR SkGr.h HINTS "${SKIA_BUILD_DIR}/include/gpu")
|
||||
find_path(SKIA_UTILS_INCLUDE_DIR SkRandom.h HINTS "${SKIA_BUILD_DIR}/include/utils")
|
||||
find_path(SKIA_CONFIG_INCLUDE_DIR SkUserConfig.h HINTS "${SKIA_DIR}/include/config")
|
||||
find_path(SKIA_CORE_INCLUDE_DIR SkCanvas.h HINTS "${SKIA_DIR}/include/core")
|
||||
find_path(SKIA_EFFECTS_INCLUDE_DIR SkBitmapSource.h HINTS "${SKIA_DIR}/include/effects")
|
||||
find_path(SKIA_GPU_INCLUDE_DIR SkGr.h HINTS "${SKIA_DIR}/include/gpu")
|
||||
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(
|
||||
${SKIA_CONFIG_INCLUDE_DIR}
|
||||
${SKIA_CORE_INCLUDE_DIR}
|
||||
${SKIA_GPU_INCLUDE_DIR}
|
||||
${SKIA_PORTS_INCLUDE_DIR}
|
||||
${SKIA_UTILS_INCLUDE_DIR})
|
||||
${SKIA_UTILS_INCLUDE_DIR}
|
||||
${SKIA_ANGLE_INCLUDE_DIR})
|
||||
|
||||
set(SKIA_LIBRARIES
|
||||
${ETC1_LIBRARY}
|
||||
${LIBSKKTX_LIBRARY}
|
||||
${OPENGL32_LIBRARY}
|
||||
${SKIA_ETC1_LIBRARY}
|
||||
${SKIA_LIBSKKTX_LIBRARY}
|
||||
${SKIA_OPENGL32_LIBRARY}
|
||||
${SKIA_LIBEGL_LIBRARY}
|
||||
${SKIA_CORE_LIBRARY}
|
||||
${SKIA_EFFECTS_LIBRARY}
|
||||
${SKIA_GPU_LIBRARY}
|
||||
|
111
src/she/skia/gl_context_wgl.h
Normal file
111
src/she/skia/gl_context_wgl.h
Normal 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
|
@ -16,6 +16,7 @@ SkiaDisplay::SkiaDisplay(EventQueue* queue, int width, int height, int scale)
|
||||
: m_queue(queue)
|
||||
, m_window(m_queue, this)
|
||||
, m_surface(new SkiaSurface)
|
||||
, m_customSurface(false)
|
||||
{
|
||||
m_surface->create(width, height);
|
||||
m_window.setScale(scale);
|
||||
@ -23,8 +24,18 @@ SkiaDisplay::SkiaDisplay(EventQueue* queue, int width, int height, int scale)
|
||||
m_recreated = false;
|
||||
}
|
||||
|
||||
void SkiaDisplay::setSkiaSurface(SkiaSurface* surface)
|
||||
{
|
||||
m_surface->dispose();
|
||||
m_surface = surface;
|
||||
m_customSurface = true;
|
||||
}
|
||||
|
||||
void SkiaDisplay::resize(const gfx::Size& size)
|
||||
{
|
||||
if (m_customSurface)
|
||||
return;
|
||||
|
||||
m_surface->dispose();
|
||||
m_surface = new SkiaSurface;
|
||||
m_surface->create(size.w, size.h);
|
||||
|
@ -24,6 +24,8 @@ class SkiaDisplay : public Display {
|
||||
public:
|
||||
SkiaDisplay(EventQueue* queue, int width, int height, int scale);
|
||||
|
||||
void setSkiaSurface(SkiaSurface* surface);
|
||||
|
||||
void resize(const gfx::Size& size);
|
||||
void dispose() override;
|
||||
|
||||
@ -63,6 +65,7 @@ private:
|
||||
SkiaWindow m_window;
|
||||
SkiaSurface* m_surface;
|
||||
bool m_recreated;
|
||||
bool m_customSurface;
|
||||
};
|
||||
|
||||
} // namespace she
|
||||
|
@ -8,7 +8,6 @@
|
||||
#define SHE_SKIA_SKIA_SURFACE_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "base/unique_ptr.h"
|
||||
#include "gfx/clip.h"
|
||||
#include "she/common/font.h"
|
||||
#include "she/locked_surface.h"
|
||||
@ -20,6 +19,7 @@
|
||||
#include "SkColorPriv.h"
|
||||
#include "SkImageInfo.h"
|
||||
#include "SkRegion.h"
|
||||
#include "SkSurface.h"
|
||||
|
||||
namespace she {
|
||||
|
||||
@ -34,10 +34,25 @@ inline SkRect to_skia(const gfx::Rect& rc) {
|
||||
class SkiaSurface : public NonDisposableSurface
|
||||
, public LockedSurface {
|
||||
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) {
|
||||
ASSERT(!m_surface);
|
||||
|
||||
m_bitmap.tryAllocPixels(
|
||||
SkImageInfo::MakeN32Premul(width, height));
|
||||
m_bitmap.eraseColor(SK_ColorTRANSPARENT);
|
||||
@ -46,6 +61,8 @@ public:
|
||||
}
|
||||
|
||||
void createRgba(int width, int height) {
|
||||
ASSERT(!m_surface);
|
||||
|
||||
m_bitmap.tryAllocPixels(
|
||||
SkImageInfo::MakeN32Premul(width, height));
|
||||
m_bitmap.eraseColor(SK_ColorTRANSPARENT);
|
||||
@ -53,6 +70,11 @@ public:
|
||||
rebuild();
|
||||
}
|
||||
|
||||
void flush() {
|
||||
if (m_canvas)
|
||||
m_canvas->flush();
|
||||
}
|
||||
|
||||
// Surface impl
|
||||
|
||||
void dispose() override {
|
||||
@ -60,11 +82,17 @@ public:
|
||||
}
|
||||
|
||||
int width() const override {
|
||||
return m_bitmap.width();
|
||||
if (m_surface)
|
||||
return m_surface->width();
|
||||
else
|
||||
return m_bitmap.width();
|
||||
}
|
||||
|
||||
int height() const override {
|
||||
return m_bitmap.height();
|
||||
if (m_surface)
|
||||
return m_surface->height();
|
||||
else
|
||||
return m_bitmap.height();
|
||||
}
|
||||
|
||||
bool isDirectToScreen() const override {
|
||||
@ -96,6 +124,8 @@ public:
|
||||
}
|
||||
|
||||
void applyScale(int scaleFactor) override {
|
||||
ASSERT(!m_surface);
|
||||
|
||||
SkBitmap result;
|
||||
result.tryAllocPixels(
|
||||
SkImageInfo::MakeN32Premul(width()*scaleFactor, height()*scaleFactor));
|
||||
@ -104,7 +134,7 @@ public:
|
||||
paint.setXfermodeMode(SkXfermode::kSrc_Mode);
|
||||
|
||||
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()));
|
||||
canvas.drawBitmapRectToRect(m_bitmap, &srcRect, dstRect, &paint);
|
||||
|
||||
@ -118,11 +148,11 @@ public:
|
||||
// LockedSurface impl
|
||||
|
||||
int lockedWidth() const override {
|
||||
return m_bitmap.width();
|
||||
return width();
|
||||
}
|
||||
|
||||
int lockedHeight() const override {
|
||||
return m_bitmap.height();
|
||||
return height();
|
||||
}
|
||||
|
||||
void unlock() override {
|
||||
@ -130,6 +160,7 @@ public:
|
||||
}
|
||||
|
||||
void clear() override {
|
||||
// TODO
|
||||
}
|
||||
|
||||
uint8_t* getData(int x, int y) const override {
|
||||
@ -196,7 +227,19 @@ public:
|
||||
}
|
||||
|
||||
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(
|
||||
SkColorGetR(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 {
|
||||
SkPaint paint;
|
||||
paint.setXfermodeMode(SkXfermode::kSrc_Mode);
|
||||
if (m_surface) {
|
||||
// m_canvas->flush();
|
||||
|
||||
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);
|
||||
SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
|
||||
std::vector<uint32_t> pixels(width * height * 4);
|
||||
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 {
|
||||
int w = m_bitmap.width();
|
||||
int h = m_bitmap.height();
|
||||
int w = width();
|
||||
int h = height();
|
||||
gfx::Clip clip(rc.x+dx, rc.y+dy, rc);
|
||||
if (!clip.clip(w, h, w, h))
|
||||
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 rowBytes = (int)m_bitmap.rowBytes();
|
||||
int rowDelta;
|
||||
@ -293,10 +351,10 @@ public:
|
||||
|
||||
void drawSurface(const LockedSurface* src, int dstx, int dsty) override {
|
||||
gfx::Clip clip(dstx, dsty, 0, 0,
|
||||
((SkiaSurface*)src)->m_bitmap.width(),
|
||||
((SkiaSurface*)src)->m_bitmap.height());
|
||||
((SkiaSurface*)src)->width(),
|
||||
((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;
|
||||
|
||||
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 {
|
||||
gfx::Clip clip(dstx, dsty, 0, 0,
|
||||
((SkiaSurface*)src)->m_bitmap.width(),
|
||||
((SkiaSurface*)src)->m_bitmap.height());
|
||||
((SkiaSurface*)src)->width(),
|
||||
((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;
|
||||
|
||||
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) {
|
||||
ASSERT(!m_surface);
|
||||
|
||||
m_bitmap.swap(other);
|
||||
rebuild();
|
||||
}
|
||||
|
||||
private:
|
||||
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());
|
||||
}
|
||||
|
||||
SkBitmap m_bitmap;
|
||||
base::UniquePtr<SkCanvas> m_canvas;
|
||||
SkSurface* m_surface;
|
||||
SkCanvas* m_canvas;
|
||||
gfx::Rect m_clip;
|
||||
};
|
||||
|
||||
|
@ -13,14 +13,45 @@
|
||||
#include "she/event_queue.h"
|
||||
#include "she/skia/skia_display.h"
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
|
||||
#include "GrContext.h"
|
||||
#include "she/skia/gl_context_wgl.h"
|
||||
|
||||
#endif
|
||||
|
||||
namespace she {
|
||||
|
||||
SkiaWindow::SkiaWindow(EventQueue* queue, SkiaDisplay* display)
|
||||
: m_queue(queue)
|
||||
, 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)
|
||||
{
|
||||
ev.setDisplay(m_display);
|
||||
@ -28,6 +59,37 @@ void SkiaWindow::queueEventImpl(Event& ev)
|
||||
}
|
||||
|
||||
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());
|
||||
const SkBitmap& bitmap = surface->bitmap();
|
||||
@ -55,8 +117,96 @@ void SkiaWindow::paintImpl(HDC hdc)
|
||||
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)
|
||||
{
|
||||
#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);
|
||||
}
|
||||
|
||||
|
@ -8,9 +8,14 @@
|
||||
#define SHE_SKIA_SKIA_WINDOW_WIN_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "base/disable_copying.h"
|
||||
#include "she/skia/skia_surface.h"
|
||||
#include "she/win/window.h"
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "gl/SkGLContext.h"
|
||||
#endif
|
||||
|
||||
namespace she {
|
||||
|
||||
class EventQueue;
|
||||
@ -18,15 +23,41 @@ class SkiaDisplay;
|
||||
|
||||
class SkiaWindow : public Window<SkiaWindow> {
|
||||
public:
|
||||
enum class Backend { NONE, GL, ANGLE };
|
||||
|
||||
SkiaWindow(EventQueue* queue, SkiaDisplay* display);
|
||||
~SkiaWindow();
|
||||
|
||||
void queueEventImpl(Event& ev);
|
||||
void paintImpl(HDC hdc);
|
||||
void resizeImpl(const gfx::Size& size);
|
||||
|
||||
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;
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user