mirror of
https://github.com/aseprite/aseprite.git
synced 2025-04-09 18:44:46 +00:00
Merge branch 'skia'
This commit is contained in:
commit
26b170e67f
@ -55,10 +55,10 @@ std::string show_file_selector(const std::string& title,
|
||||
dlg->addFilter("*." + tok, tok + " files (*." + tok + ")");
|
||||
dlg->addFilter("*.*", "All files (*.*)");
|
||||
|
||||
if (dlg->show(she::instance()->defaultDisplay()->nativeHandle())) {
|
||||
if (dlg->show(she::instance()->defaultDisplay()->nativeHandle()))
|
||||
res = dlg->getFileName();
|
||||
dlg->dispose();
|
||||
}
|
||||
|
||||
dlg->dispose();
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
@ -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}
|
||||
@ -87,11 +109,11 @@ if(USE_SKIA_BACKEND)
|
||||
|
||||
list(APPEND SHE_SOURCES
|
||||
skia/skia_display.cpp
|
||||
skia/skia_window.cpp
|
||||
skia/she.cpp)
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND SHE_SOURCES
|
||||
skia/skia_window_win.cpp
|
||||
win/vk.cpp)
|
||||
endif()
|
||||
endif()
|
||||
|
@ -135,7 +135,7 @@ public:
|
||||
event.setType(Event::None);
|
||||
}
|
||||
|
||||
void queueEvent(const Event& event) {
|
||||
void queueEvent(const Event& event) override {
|
||||
m_events.push(event);
|
||||
}
|
||||
|
||||
|
@ -349,6 +349,13 @@ namespace she {
|
||||
width, height);
|
||||
}
|
||||
|
||||
void scrollTo(const gfx::Rect& rc, int dx, int dy) override {
|
||||
blit(m_bmp, m_bmp,
|
||||
rc.x, rc.y,
|
||||
rc.x+dx, rc.y+dy,
|
||||
rc.w, rc.h);
|
||||
}
|
||||
|
||||
void drawSurface(const LockedSurface* src, int dstx, int dsty) override {
|
||||
draw_sprite(m_bmp, static_cast<const Alleg4Surface*>(src)->m_bmp, dstx, dsty);
|
||||
}
|
||||
|
@ -14,6 +14,8 @@
|
||||
#include "she/scoped_surface_lock.h"
|
||||
#include "she/surface.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace she {
|
||||
|
||||
class CommonFont : public Font {
|
||||
|
@ -16,6 +16,7 @@ namespace she {
|
||||
public:
|
||||
virtual ~EventQueue() { }
|
||||
virtual void getEvent(Event& ev, bool canWait) = 0;
|
||||
virtual void queueEvent(const Event& ev) = 0;
|
||||
};
|
||||
|
||||
} // namespace she
|
||||
|
@ -44,6 +44,7 @@ namespace she {
|
||||
virtual void fillRect(gfx::Color color, const gfx::Rect& rc) = 0;
|
||||
|
||||
virtual void blitTo(LockedSurface* dest, int srcx, int srcy, int dstx, int dsty, int width, int height) const = 0;
|
||||
virtual void scrollTo(const gfx::Rect& rc, int dx, int dy) = 0;
|
||||
virtual void drawSurface(const LockedSurface* src, int dstx, int dsty) = 0;
|
||||
virtual void drawRgbaSurface(const LockedSurface* src, int dstx, int dsty) = 0;
|
||||
virtual void drawColoredRgbaSurface(const LockedSurface* src, gfx::Color fg, gfx::Color bg, const gfx::Clip& clip) = 0;
|
||||
|
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
|
@ -12,9 +12,11 @@
|
||||
|
||||
namespace she {
|
||||
|
||||
SkiaDisplay::SkiaDisplay(int width, int height, int scale)
|
||||
: m_window(&m_queue, this)
|
||||
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);
|
||||
@ -22,8 +24,18 @@ SkiaDisplay::SkiaDisplay(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);
|
||||
@ -80,7 +92,7 @@ bool SkiaDisplay::flip()
|
||||
return false;
|
||||
}
|
||||
|
||||
m_window.invalidate();
|
||||
m_window.updateWindow();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -101,16 +113,18 @@ void SkiaDisplay::setTitleBar(const std::string& title)
|
||||
|
||||
EventQueue* SkiaDisplay::getEventQueue()
|
||||
{
|
||||
return &m_queue;
|
||||
return m_queue;
|
||||
}
|
||||
|
||||
bool SkiaDisplay::setNativeMouseCursor(NativeCursor cursor)
|
||||
{
|
||||
m_window.setNativeMouseCursor(cursor);
|
||||
return true;
|
||||
}
|
||||
|
||||
void SkiaDisplay::setMousePosition(const gfx::Point& position)
|
||||
{
|
||||
m_window.setMousePosition(position);
|
||||
}
|
||||
|
||||
void SkiaDisplay::captureMouse()
|
||||
|
@ -9,8 +9,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "she/display.h"
|
||||
#include "she/skia/skia_event_queue.h"
|
||||
#include "she/skia/skia_window.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "she/skia/skia_window_win.h"
|
||||
#else
|
||||
#error There is no SkiaWindow implementation for your platform
|
||||
#endif
|
||||
|
||||
namespace she {
|
||||
|
||||
@ -18,7 +22,9 @@ class SkiaSurface;
|
||||
|
||||
class SkiaDisplay : public Display {
|
||||
public:
|
||||
SkiaDisplay(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 dispose() override;
|
||||
@ -55,10 +61,11 @@ public:
|
||||
DisplayHandle nativeHandle() override;
|
||||
|
||||
private:
|
||||
SkiaEventQueue m_queue;
|
||||
EventQueue* m_queue;
|
||||
SkiaWindow m_window;
|
||||
SkiaSurface* m_surface;
|
||||
bool m_recreated;
|
||||
bool m_customSurface;
|
||||
};
|
||||
|
||||
} // namespace she
|
||||
|
@ -8,15 +8,18 @@
|
||||
#define SHE_SKIA_SKIA_SURFACE_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "she/common/locked_surface.h"
|
||||
|
||||
#include "base/unique_ptr.h"
|
||||
#include "gfx/clip.h"
|
||||
#include "she/common/font.h"
|
||||
#include "she/locked_surface.h"
|
||||
#include "she/scoped_surface_lock.h"
|
||||
|
||||
#include "SkBitmap.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkColorFilter.h"
|
||||
#include "SkColorPriv.h"
|
||||
#include "SkImageInfo.h"
|
||||
#include "SkRegion.h"
|
||||
#include "SkSurface.h"
|
||||
|
||||
namespace she {
|
||||
|
||||
@ -29,25 +32,49 @@ inline SkRect to_skia(const gfx::Rect& rc) {
|
||||
}
|
||||
|
||||
class SkiaSurface : public NonDisposableSurface
|
||||
, public CommonLockedSurface {
|
||||
, 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);
|
||||
|
||||
rebuild();
|
||||
}
|
||||
|
||||
void createRgba(int width, int height) {
|
||||
ASSERT(!m_surface);
|
||||
|
||||
m_bitmap.tryAllocPixels(
|
||||
SkImageInfo::MakeN32Premul(width, height));
|
||||
m_bitmap.eraseColor(SK_ColorTRANSPARENT);
|
||||
|
||||
rebuild();
|
||||
}
|
||||
|
||||
void flush() {
|
||||
if (m_canvas)
|
||||
m_canvas->flush();
|
||||
}
|
||||
|
||||
// Surface impl
|
||||
|
||||
void dispose() override {
|
||||
@ -55,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 {
|
||||
@ -91,14 +124,19 @@ public:
|
||||
}
|
||||
|
||||
void applyScale(int scaleFactor) override {
|
||||
ASSERT(!m_surface);
|
||||
|
||||
SkBitmap result;
|
||||
result.tryAllocPixels(
|
||||
SkImageInfo::MakeN32Premul(width()*scaleFactor, height()*scaleFactor));
|
||||
|
||||
SkPaint paint;
|
||||
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);
|
||||
canvas.drawBitmapRectToRect(m_bitmap, &srcRect, dstRect, &paint);
|
||||
|
||||
swapBitmap(result);
|
||||
}
|
||||
@ -110,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 {
|
||||
@ -122,6 +160,7 @@ public:
|
||||
}
|
||||
|
||||
void clear() override {
|
||||
// TODO
|
||||
}
|
||||
|
||||
uint8_t* getData(int x, int y) const override {
|
||||
@ -188,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),
|
||||
@ -207,7 +258,7 @@ public:
|
||||
paint.setColor(to_skia(color));
|
||||
m_canvas->drawLine(
|
||||
SkIntToScalar(x), SkIntToScalar(y),
|
||||
SkIntToScalar(x+w-1), SkIntToScalar(y), paint);
|
||||
SkIntToScalar(x+w), SkIntToScalar(y), paint);
|
||||
}
|
||||
|
||||
void drawVLine(gfx::Color color, int x, int y, int h) override {
|
||||
@ -215,7 +266,7 @@ public:
|
||||
paint.setColor(to_skia(color));
|
||||
m_canvas->drawLine(
|
||||
SkIntToScalar(x), SkIntToScalar(y),
|
||||
SkIntToScalar(x), SkIntToScalar(y+h-1), paint);
|
||||
SkIntToScalar(x), SkIntToScalar(y+h), paint);
|
||||
}
|
||||
|
||||
void drawLine(gfx::Color color, const gfx::Point& a, const gfx::Point& b) override {
|
||||
@ -237,24 +288,73 @@ public:
|
||||
SkPaint paint;
|
||||
paint.setColor(to_skia(color));
|
||||
paint.setStyle(SkPaint::kFill_Style);
|
||||
paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
|
||||
m_canvas->drawRect(to_skia(rc), paint);
|
||||
}
|
||||
|
||||
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 = 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;
|
||||
|
||||
if (dy > 0) {
|
||||
clip.src.y += clip.size.h-1;
|
||||
clip.dst.y += clip.size.h-1;
|
||||
rowDelta = -rowBytes;
|
||||
}
|
||||
else
|
||||
rowDelta = rowBytes;
|
||||
|
||||
char* dst = (char*)m_bitmap.getPixels();
|
||||
const char* src = dst;
|
||||
dst += rowBytes*clip.dst.y + bytesPerPixel*clip.dst.x;
|
||||
src += rowBytes*clip.src.y + bytesPerPixel*clip.src.x;
|
||||
w = bytesPerPixel*clip.size.w;
|
||||
h = clip.size.h;
|
||||
|
||||
while (--h >= 0) {
|
||||
memmove(dst, src, w);
|
||||
dst += rowDelta;
|
||||
src += rowDelta;
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
@ -269,39 +369,91 @@ 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));
|
||||
SkRect dstRect = SkRect::Make(SkIRect::MakeXYWH(clip.dst.x, clip.dst.y, clip.size.w, clip.size.h));
|
||||
|
||||
SkPaint paint;
|
||||
paint.setXfermodeMode(SkXfermode::kSrcATop_Mode);
|
||||
paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
|
||||
|
||||
m_canvas->drawBitmapRectToRect(
|
||||
((SkiaSurface*)src)->m_bitmap, &srcRect, dstRect, &paint);
|
||||
}
|
||||
|
||||
void drawColoredRgbaSurface(const LockedSurface* src, gfx::Color fg, gfx::Color bg, const gfx::Clip& clipbase) override {
|
||||
gfx::Clip clip(clipbase);
|
||||
if (!clip.clip(lockedWidth(), lockedHeight(), src->lockedWidth(), src->lockedHeight()))
|
||||
return;
|
||||
|
||||
SkRect srcRect = SkRect::Make(SkIRect::MakeXYWH(clip.src.x, clip.src.y, clip.size.w, clip.size.h));
|
||||
SkRect dstRect = SkRect::Make(SkIRect::MakeXYWH(clip.dst.x, clip.dst.y, clip.size.w, clip.size.h));
|
||||
|
||||
SkPaint paint;
|
||||
paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
|
||||
|
||||
if (gfx::geta(bg) > 0) {
|
||||
SkPaint paint;
|
||||
paint.setColor(to_skia(bg));
|
||||
paint.setStyle(SkPaint::kFill_Style);
|
||||
m_canvas->drawRect(dstRect, paint);
|
||||
}
|
||||
|
||||
SkAutoTUnref<SkColorFilter> colorFilter(
|
||||
SkColorFilter::CreateModeFilter(to_skia(fg), SkXfermode::kSrcIn_Mode));
|
||||
paint.setColorFilter(colorFilter);
|
||||
|
||||
m_canvas->drawBitmapRectToRect(
|
||||
((SkiaSurface*)src)->m_bitmap,
|
||||
&srcRect, dstRect, &paint);
|
||||
}
|
||||
|
||||
void drawChar(Font* font, gfx::Color fg, gfx::Color bg, int x, int y, int chr) override {
|
||||
CommonFont* commonFont = static_cast<CommonFont*>(font);
|
||||
|
||||
gfx::Rect charBounds = commonFont->getCharBounds(chr);
|
||||
if (!charBounds.isEmpty()) {
|
||||
ScopedSurfaceLock lock(commonFont->getSurfaceSheet());
|
||||
drawColoredRgbaSurface(lock, fg, bg, gfx::Clip(x, y, charBounds));
|
||||
}
|
||||
}
|
||||
|
||||
void drawString(Font* font, gfx::Color fg, gfx::Color bg, int x, int y, const std::string& str) override {
|
||||
base::utf8_const_iterator it(str.begin()), end(str.end());
|
||||
while (it != end) {
|
||||
drawChar(font, fg, bg, x, y, *it);
|
||||
x += font->charWidth(*it);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
SkBitmap& bitmap() {
|
||||
return m_bitmap;
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
@ -17,6 +17,12 @@
|
||||
#include "she/skia/skia_display.h"
|
||||
#include "she/skia/skia_surface.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "she/win/event_queue.h"
|
||||
#else
|
||||
#error There is no EventQueue implementation for your platform
|
||||
#endif
|
||||
|
||||
namespace she {
|
||||
|
||||
class SkiaSystem : public CommonSystem {
|
||||
@ -44,7 +50,7 @@ public:
|
||||
}
|
||||
|
||||
Display* createDisplay(int width, int height, int scale) override {
|
||||
SkiaDisplay* display = new SkiaDisplay(width, height, scale);
|
||||
SkiaDisplay* display = new SkiaDisplay(&m_queue, width, height, scale);
|
||||
if (!m_defaultDisplay)
|
||||
m_defaultDisplay = display;
|
||||
return display;
|
||||
@ -67,8 +73,6 @@ public:
|
||||
SkAutoTDelete<SkStreamAsset> stream(SkNEW_ARGS(SkFILEStream, (fp.get(), SkFILEStream::kCallerRetains_Ownership)));
|
||||
|
||||
SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(stream));
|
||||
// decoder->setRequireUnpremultipliedColors(true);
|
||||
|
||||
if (decoder) {
|
||||
stream->rewind();
|
||||
SkBitmap bm;
|
||||
@ -92,6 +96,7 @@ public:
|
||||
|
||||
private:
|
||||
SkiaDisplay* m_defaultDisplay;
|
||||
EventQueueImpl m_queue;
|
||||
};
|
||||
|
||||
} // namespace she
|
||||
|
@ -1,62 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "she/skia/skia_window.h"
|
||||
|
||||
#include "she/skia/skia_display.h"
|
||||
|
||||
namespace she {
|
||||
|
||||
SkiaWindow::SkiaWindow(SkiaEventQueue* queue, SkiaDisplay* display)
|
||||
: m_queue(queue)
|
||||
, m_display(display)
|
||||
{
|
||||
}
|
||||
|
||||
void SkiaWindow::queueEventImpl(Event& ev)
|
||||
{
|
||||
ev.setDisplay(m_display);
|
||||
m_queue->queueEvent(ev);
|
||||
}
|
||||
|
||||
void SkiaWindow::paintImpl(HDC hdc)
|
||||
{
|
||||
SkiaSurface* surface = static_cast<SkiaSurface*>(m_display->getSurface());
|
||||
const SkBitmap& bitmap = surface->bitmap();
|
||||
|
||||
BITMAPINFO bmi;
|
||||
memset(&bmi, 0, sizeof(bmi));
|
||||
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bmi.bmiHeader.biWidth = bitmap.width();
|
||||
bmi.bmiHeader.biHeight = -bitmap.height();
|
||||
bmi.bmiHeader.biPlanes = 1;
|
||||
bmi.bmiHeader.biBitCount = 32;
|
||||
bmi.bmiHeader.biCompression = BI_RGB;
|
||||
bmi.bmiHeader.biSizeImage = 0;
|
||||
|
||||
ASSERT(bitmap.width() * bitmap.bytesPerPixel() == bitmap.rowBytes());
|
||||
bitmap.lockPixels();
|
||||
|
||||
int ret = StretchDIBits(hdc,
|
||||
0, 0, bitmap.width()*scale(), bitmap.height()*scale(),
|
||||
0, 0, bitmap.width(), bitmap.height(),
|
||||
bitmap.getPixels(),
|
||||
&bmi, DIB_RGB_COLORS, SRCCOPY);
|
||||
(void)ret;
|
||||
|
||||
bitmap.unlockPixels();
|
||||
}
|
||||
|
||||
void SkiaWindow::resizeImpl(const gfx::Size& size)
|
||||
{
|
||||
m_display->resize(size);
|
||||
}
|
||||
|
||||
} // namespace she
|
@ -1,38 +0,0 @@
|
||||
// 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_SKIA_WINDOW_INCLUDED
|
||||
#define SHE_SKIA_SKIA_WINDOW_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "she/win/window.h"
|
||||
#else
|
||||
#error There is no Window implementation
|
||||
#endif
|
||||
|
||||
#include "she/skia/skia_event_queue.h"
|
||||
#include "she/skia/skia_surface.h"
|
||||
|
||||
namespace she {
|
||||
|
||||
class SkiaDisplay;
|
||||
|
||||
class SkiaWindow : public Window<SkiaWindow> {
|
||||
public:
|
||||
SkiaWindow(SkiaEventQueue* queue, SkiaDisplay* display);
|
||||
void queueEventImpl(Event& ev);
|
||||
void paintImpl(HDC hdc);
|
||||
void resizeImpl(const gfx::Size& size);
|
||||
|
||||
private:
|
||||
SkiaEventQueue* m_queue;
|
||||
SkiaDisplay* m_display;
|
||||
};
|
||||
|
||||
} // namespace she
|
||||
|
||||
#endif
|
213
src/she/skia/skia_window_win.cpp
Normal file
213
src/she/skia/skia_window_win.cpp
Normal file
@ -0,0 +1,213 @@
|
||||
// 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.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "she/skia/skia_window_win.h"
|
||||
|
||||
#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);
|
||||
m_queue->queueEvent(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();
|
||||
|
||||
BITMAPINFO bmi;
|
||||
memset(&bmi, 0, sizeof(bmi));
|
||||
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bmi.bmiHeader.biWidth = bitmap.width();
|
||||
bmi.bmiHeader.biHeight = -bitmap.height();
|
||||
bmi.bmiHeader.biPlanes = 1;
|
||||
bmi.bmiHeader.biBitCount = 32;
|
||||
bmi.bmiHeader.biCompression = BI_RGB;
|
||||
bmi.bmiHeader.biSizeImage = 0;
|
||||
|
||||
ASSERT(bitmap.width() * bitmap.bytesPerPixel() == bitmap.rowBytes());
|
||||
bitmap.lockPixels();
|
||||
|
||||
int ret = StretchDIBits(hdc,
|
||||
0, 0, bitmap.width()*scale(), bitmap.height()*scale(),
|
||||
0, 0, bitmap.width(), bitmap.height(),
|
||||
bitmap.getPixels(),
|
||||
&bmi, DIB_RGB_COLORS, SRCCOPY);
|
||||
(void)ret;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
} // namespace she
|
65
src/she/skia/skia_window_win.h
Normal file
65
src/she/skia/skia_window_win.h
Normal file
@ -0,0 +1,65 @@
|
||||
// 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_SKIA_WINDOW_WIN_INCLUDED
|
||||
#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;
|
||||
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
|
||||
|
||||
#endif
|
@ -4,8 +4,8 @@
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
|
||||
#ifndef SHE_SKIA_SKIA_EVENT_QUEUE_INCLUDED
|
||||
#define SHE_SKIA_SKIA_EVENT_QUEUE_INCLUDED
|
||||
#ifndef SHE_WIN_EVENT_QUEUE_INCLUDED
|
||||
#define SHE_WIN_EVENT_QUEUE_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include <queue>
|
||||
@ -17,18 +17,16 @@
|
||||
|
||||
namespace she {
|
||||
|
||||
class SkiaEventQueue : public EventQueue {
|
||||
class EventQueueImpl : public EventQueue {
|
||||
public:
|
||||
SkiaEventQueue() : m_stop(false) {
|
||||
}
|
||||
|
||||
void getEvent(Event& ev, bool canWait) override {
|
||||
MSG msg;
|
||||
|
||||
while (!m_stop && m_events.empty()) {
|
||||
while (m_events.empty()) {
|
||||
BOOL res;
|
||||
|
||||
if (canWait) {
|
||||
ASSERT(false); // Not yet supported
|
||||
res = GetMessage(&msg, nullptr, 0, 0);
|
||||
}
|
||||
else {
|
||||
@ -52,16 +50,12 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void queueEvent(Event& ev) {
|
||||
if (ev.type() == Event::CloseDisplay)
|
||||
m_stop = true;
|
||||
|
||||
void queueEvent(const Event& ev) override {
|
||||
m_events.push(ev);
|
||||
}
|
||||
|
||||
private:
|
||||
std::queue<Event> m_events;
|
||||
bool m_stop;
|
||||
};
|
||||
|
||||
} // namespace she
|
@ -11,10 +11,12 @@
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <commctrl.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
#include "gfx/size.h"
|
||||
#include "she/event.h"
|
||||
#include "she/keys.h"
|
||||
#include "she/native_cursor.h"
|
||||
|
||||
#ifndef WM_MOUSEHWHEEL
|
||||
#define WM_MOUSEHWHEEL 0x020E
|
||||
@ -32,6 +34,7 @@ namespace she {
|
||||
Window() {
|
||||
registerClass();
|
||||
m_hwnd = createHwnd(this);
|
||||
m_hcursor = NULL;
|
||||
m_hasMouse = false;
|
||||
m_captureMouse = false;
|
||||
m_scale = 1;
|
||||
@ -87,8 +90,68 @@ namespace she {
|
||||
m_captureMouse = false;
|
||||
}
|
||||
|
||||
void invalidate() {
|
||||
void setMousePosition(const gfx::Point& position) {
|
||||
POINT pos = { position.x * m_scale,
|
||||
position.y * m_scale };
|
||||
ClientToScreen(m_hwnd, &pos);
|
||||
SetCursorPos(pos.x, pos.y);
|
||||
}
|
||||
|
||||
void setNativeMouseCursor(NativeCursor cursor) {
|
||||
HCURSOR hcursor = NULL;
|
||||
|
||||
switch (cursor) {
|
||||
case kNoCursor:
|
||||
// Do nothing, just set to null
|
||||
break;
|
||||
case kArrowCursor:
|
||||
hcursor = LoadCursor(NULL, IDC_ARROW);
|
||||
break;
|
||||
case kIBeamCursor:
|
||||
hcursor = LoadCursor(NULL, IDC_IBEAM);
|
||||
break;
|
||||
case kWaitCursor:
|
||||
hcursor = LoadCursor(NULL, IDC_WAIT);
|
||||
break;
|
||||
case kLinkCursor:
|
||||
hcursor = LoadCursor(NULL, IDC_HAND);
|
||||
break;
|
||||
case kHelpCursor:
|
||||
hcursor = LoadCursor(NULL, IDC_HELP);
|
||||
break;
|
||||
case kForbiddenCursor:
|
||||
hcursor = LoadCursor(NULL, IDC_NO);
|
||||
break;
|
||||
case kMoveCursor:
|
||||
hcursor = LoadCursor(NULL, IDC_SIZEALL);
|
||||
break;
|
||||
case kSizeNCursor:
|
||||
case kSizeNSCursor:
|
||||
case kSizeSCursor:
|
||||
hcursor = LoadCursor(NULL, IDC_SIZENS);
|
||||
break;
|
||||
case kSizeECursor:
|
||||
case kSizeWCursor:
|
||||
case kSizeWECursor:
|
||||
hcursor = LoadCursor(NULL, IDC_SIZEWE);
|
||||
break;
|
||||
case kSizeNWCursor:
|
||||
case kSizeSECursor:
|
||||
hcursor = LoadCursor(NULL, IDC_SIZENWSE);
|
||||
break;
|
||||
case kSizeNECursor:
|
||||
case kSizeSWCursor:
|
||||
hcursor = LoadCursor(NULL, IDC_SIZENESW);
|
||||
break;
|
||||
}
|
||||
|
||||
SetCursor(hcursor);
|
||||
m_hcursor = hcursor;
|
||||
}
|
||||
|
||||
void updateWindow() {
|
||||
InvalidateRect(m_hwnd, NULL, FALSE);
|
||||
UpdateWindow(m_hwnd);
|
||||
}
|
||||
|
||||
HWND handle() {
|
||||
@ -99,6 +162,13 @@ namespace she {
|
||||
LRESULT wndProc(UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
switch (msg) {
|
||||
|
||||
case WM_SETCURSOR:
|
||||
if (LOWORD(lparam) == HTCLIENT) {
|
||||
SetCursor(m_hcursor);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CLOSE: {
|
||||
Event ev;
|
||||
ev.setType(Event::CloseDisplay);
|
||||
@ -236,15 +306,13 @@ namespace she {
|
||||
|
||||
case WM_MOUSEWHEEL:
|
||||
case WM_MOUSEHWHEEL: {
|
||||
RECT rc;
|
||||
::GetWindowRect(m_hwnd, &rc);
|
||||
POINT pos = { GET_X_LPARAM(lparam),
|
||||
GET_Y_LPARAM(lparam) };
|
||||
ScreenToClient(m_hwnd, &pos);
|
||||
|
||||
Event ev;
|
||||
ev.setType(Event::MouseWheel);
|
||||
ev.setPosition((gfx::Point(
|
||||
GET_X_LPARAM(lparam),
|
||||
GET_Y_LPARAM(lparam)) - gfx::Point(rc.left, rc.top))
|
||||
/ m_scale);
|
||||
ev.setPosition(gfx::Point(pos.x, pos.y) / m_scale);
|
||||
|
||||
int z = ((short)HIWORD(wparam)) / WHEEL_DELTA;
|
||||
gfx::Point delta(
|
||||
@ -260,16 +328,13 @@ namespace she {
|
||||
|
||||
case WM_HSCROLL:
|
||||
case WM_VSCROLL: {
|
||||
RECT rc;
|
||||
::GetWindowRect(m_hwnd, &rc);
|
||||
|
||||
POINT pos;
|
||||
::GetCursorPos(&pos);
|
||||
GetCursorPos(&pos);
|
||||
ScreenToClient(m_hwnd, &pos);
|
||||
|
||||
Event ev;
|
||||
ev.setType(Event::MouseWheel);
|
||||
ev.setPosition((gfx::Point(pos.x, pos.y) - gfx::Point(rc.left, rc.top))
|
||||
/ m_scale);
|
||||
ev.setPosition(gfx::Point(pos.x, pos.y) / m_scale);
|
||||
|
||||
int bar = (msg == WM_HSCROLL ? SB_HORZ: SB_VERT);
|
||||
int z = GetScrollPos(m_hwnd, bar);
|
||||
@ -309,6 +374,7 @@ namespace she {
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_KEYDOWN: {
|
||||
int vk = wparam;
|
||||
int scancode = (lparam >> 16) & 0xff;
|
||||
@ -392,13 +458,13 @@ namespace she {
|
||||
return; // Already registered
|
||||
|
||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
wcex.style = 0;
|
||||
wcex.style = CS_DBLCLKS;
|
||||
wcex.lpfnWndProc = &Window::staticWndProc;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
wcex.hInstance = instance;
|
||||
wcex.hIcon = nullptr;
|
||||
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
||||
wcex.hCursor = NULL;
|
||||
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
|
||||
wcex.lpszMenuName = nullptr;
|
||||
wcex.lpszClassName = SHE_WND_CLASS_NAME;
|
||||
@ -442,6 +508,7 @@ namespace she {
|
||||
}
|
||||
|
||||
mutable HWND m_hwnd;
|
||||
HCURSOR m_hcursor;
|
||||
gfx::Size m_clientSize;
|
||||
gfx::Size m_restoredSize;
|
||||
int m_scale;
|
||||
|
@ -22,12 +22,8 @@ namespace ui {
|
||||
|
||||
using namespace gfx;
|
||||
|
||||
void move_region(const Region& region, int dx, int dy)
|
||||
void move_region(Manager* manager, const Region& region, int dx, int dy)
|
||||
{
|
||||
ASSERT(Manager::getDefault());
|
||||
if (!Manager::getDefault())
|
||||
return;
|
||||
|
||||
she::System* system = she::instance();
|
||||
she::Display* display = Manager::getDefault()->getDisplay();
|
||||
ASSERT(display);
|
||||
@ -40,7 +36,7 @@ void move_region(const Region& region, int dx, int dy)
|
||||
// Blit directly screen to screen.
|
||||
if (nrects == 1) {
|
||||
Rect rc = region[0];
|
||||
lock->blitTo(lock, rc.x, rc.y, rc.x+dx, rc.y+dy, rc.w, rc.h);
|
||||
lock->scrollTo(rc, dx, dy);
|
||||
}
|
||||
// Blit saving areas and copy them.
|
||||
else if (nrects > 1) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite UI Library
|
||||
// Copyright (C) 2001-2014 David Capello
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -10,9 +10,11 @@
|
||||
|
||||
#include "gfx/region.h"
|
||||
|
||||
namespace ui { // TODO all these functions are deprecated and must be replaced by Graphics methods.
|
||||
namespace ui {
|
||||
|
||||
void move_region(const gfx::Region& region, int dx, int dy);
|
||||
class Manager;
|
||||
|
||||
void move_region(Manager* manager, const gfx::Region& region, int dx, int dy);
|
||||
|
||||
} // namespace ui
|
||||
|
||||
|
@ -1068,7 +1068,7 @@ void Widget::scrollRegion(const Region& region, const Point& delta)
|
||||
reg2.offset(-delta);
|
||||
|
||||
// Move screen pixels
|
||||
ui::move_region(reg2, delta.x, delta.y);
|
||||
ui::move_region(getManager(), reg2, delta.x, delta.y);
|
||||
|
||||
reg2.offset(delta);
|
||||
|
||||
|
@ -577,7 +577,7 @@ void Window::moveWindow(const gfx::Rect& rect, bool use_blit)
|
||||
{
|
||||
IntersectClip clip(&g, man_pos);
|
||||
if (clip) {
|
||||
ui::move_region(moveableRegion, dx, dy);
|
||||
ui::move_region(manager, moveableRegion, dx, dy);
|
||||
}
|
||||
}
|
||||
show_mouse_cursor();
|
||||
|
Loading…
x
Reference in New Issue
Block a user