二、修改源码
上篇是cmake改动介绍,本篇讲述源码改动
core模块移植
core模块里面的代码涉及基本功能,包括信号,属性,字符串,路径,应用程序,操作系统抽象,不受平台影响。
graphic模块移植
修改graphics/skia_gl_canvas.c++,添加OpenGL头文件
#include <include/gpu/gl/GrGLAssembleInterface.h>
#include <include/gpu/gl/GrGLInterface.h>
+#ifndef SKUI_USE_IMX8
#ifdef _WIN32
#include <windows.h>
#endif
@@ -41,6 +42,10 @@
#include <GL/gl.h>
#endif
#include <GL/glext.h>
+#else
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#endif
修改graphics/skia_gl_context.c++,添加OpenGL头文件
+#ifndef SKUI_USE_IMX8
#ifdef _WIN32
#include <windows.h>
#endif
@@ -41,6 +42,10 @@
#include <GL/gl.h>
#endif
#include <GL/glext.h>
+#else
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#endif
修改graphics/skia_gradient.c++,解决SkTileMode::kMirror编译报错,skia库的差异导致的
namespace skui::graphics
{
@@ -47,23 +49,40 @@ namespace skui::graphics
auto points = convert_to<std::vector<SkPoint>>(linear.points);
auto colors = convert_to<std::vector<SkColor>>(linear.colors);
+#ifndef SKUI_USE_IMX8
paint.setShader(SkGradientShader::MakeLinear(points.data(),
colors.data(),
nullptr,
static_cast<int>(points.size()),
SkTileMode::kMirror));
+#else
+ paint.setShader(SkGradientShader::MakeLinear(points.data(),
+ colors.data(),
+ nullptr,
+ static_cast<int>(points.size()),
+ SkShader::TileMode::kMirror_TileMode));
+#endif
}
void set_gradient(const radial_gradient& radial,
SkPaint& paint,
const scalar_position& offset)
{
+#ifndef SKUI_USE_IMX8
paint.setShader(SkGradientShader::MakeRadial(convert_to<SkPoint>(radial.center + offset),
radial.radius,
convert_to<std::vector<SkColor>>(radial.colors).data(),
nullptr,
static_cast<int>(radial.positions.size()),
SkTileMode::kMirror));
+#else
+ paint.setShader(SkGradientShader::MakeRadial(convert_to<SkPoint>(radial.center + offset),
+ radial.radius,
+ convert_to<std::vector<SkColor>>(radial.colors).data(),
+ nullptr,
+ static_cast<int>(radial.positions.size()),
+ SkShader::TileMode::kMirror_TileMode));
+#endif
}
void set_gradient(const sweep_gradient& sweep,
@@ -82,6 +101,7 @@ namespace skui::graphics
SkPaint& paint,
const scalar_position& offset)
{
+#ifndef SKUI_USE_IMX8
paint.setShader(SkGradientShader::MakeTwoPointConical(convert_to<SkPoint>(conical.start + offset),
conical.start_radius,
convert_to<SkPoint>(conical.end + offset),
@@ -90,5 +110,15 @@ namespace skui::graphics
nullptr,
static_cast<int>(conical.colors.size()),
SkTileMode::kMirror));
+#else
+ paint.setShader(SkGradientShader::MakeTwoPointConical(convert_to<SkPoint>(conical.start + offset),
+ conical.start_radius,
+ convert_to<SkPoint>(conical.end + offset),
+ conical.end_radius,
+ convert_to<std::vector<SkColor>>(conical.colors).data(),
+ nullptr,
+ static_cast<int>(conical.colors.size()),
+ SkShader::TileMode::kMirror_TileMode));
+#endif
}
}
gui模块移植
添加gui/native_visual/imx.h++、gui/native_visual/imx.c++
支持imx平台EGL初始化
//gui/native_visual/imx.h++
namespace skui::gui::native_visual {
class imx : public base {
public:
imx();
~imx() override;
void create_surface(std::uintptr_t window) override;
void make_current() const override;
void swap_buffers(const graphics::pixel_size &size) const override;
gl_get_function_type get_gl_function() const override;
private:
EGLDisplay egl_display = nullptr;
EGLContext egl_context = nullptr;
EGLConfig egl_config = nullptr;
EGLSurface egl_surface = nullptr;
};
}
//gui/native_visual/imx.c++
namespace skui::gui::native_visual {
namespace {
base::gl_function_type egl_get(void *, const char name[]) {
base::gl_function_type ptr = eglGetProcAddress(name);
if (!ptr) {
if (0 == std::strcmp("eglQueryString", name))
return reinterpret_cast<base::gl_function_type>(eglQueryString);
else if (0 == std::strcmp("eglGetCurrentDisplay", name))
return reinterpret_cast<base::gl_function_type>(eglGetCurrentDisplay);
}
return ptr;
}
}
imx::imx() {
egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (egl_display == EGL_NO_DISPLAY) {
core::debug_print("EGL_NO_DISPLAY\n");
return;
}
if (!eglInitialize(egl_display, nullptr, nullptr)) {
core::debug_print("eglInitialize failed\n");
return;
}
}
imx::~imx() {
if (egl_context) {
eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(egl_display, egl_context);
}
if (egl_surface)
eglDestroySurface(egl_display, egl_surface);
if (egl_display)
eglTerminate(egl_display);
}
void imx::make_current() const {
eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context);
}
void imx::swap_buffers(const graphics::pixel_size &size) const {
eglSwapBuffers(egl_display, egl_surface);
}
void imx::create_surface(std::uintptr_t window) {
EGLint ctxAttribs[] =
{
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
EGLint numConfigs;
const EGLint attribs[] = {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_NONE
};
if (!eglChooseConfig(egl_display, attribs, &egl_config, 1, &numConfigs)) {
core::debug_print("eglChooseConfig failed\n");
return;
}
egl_context = eglCreateContext(egl_display, egl_config, EGL_NO_CONTEXT, ctxAttribs);
egl_surface = eglCreateWindowSurface(egl_display, egl_config, reinterpret_cast<EGLNativeWindowType>(window),
nullptr);
}
base::gl_get_function_type imx::get_gl_function() const {
return &egl_get;
}
}
添加gui/native_window/imx.h++、gui/native_window/imx.c++
继承gui/native_visual/imx类,实现Android Surface创建
//gui/native_window/imx.h++
namespace skui::gui::native_window {
class imx : public base {
public:
imx();
~imx() override;
void create(const graphics::pixel_position &position,
const graphics::pixel_size &size) final;
void show() final;
void hide() final;
void close() final;
core::string get_title() const final;
void set_title(const core::string &title) final;
std::pair<graphics::pixel_position, graphics::pixel_size> get_current_geometry() const final;
private:
ASurface *asurface = nullptr;
};
}
//gui/native_window/imx.c++
namespace skui::gui::native_window {
imx::imx() : base(std::make_unique<native_visual::imx>()) {
}
imx::~imx() {
}
void imx::create(const graphics::pixel_position &position, const graphics::pixel_size &size) {
if (asurface == nullptr) {
asurface = ASurface_create(getprogname(), size.width, size.height, WINDOW_FORMAT_RGBA_8888);
}
if (asurface == nullptr) {
core::debug_print("createSurface failed\n");
return;
}
if (ASurface_setLayer(asurface, 0x7fffffff) < 0) {
core::debug_print("setLayer failed\n");
return;
}
native_visual->create_surface(reinterpret_cast<std::uintptr_t>(ASurface_getNativeWindow(asurface)));
}
void imx::show() {
ASurface_show(asurface);
}
void imx::hide() {
ASurface_hide(asurface);
}
void imx::close() {
ASurface_destory(asurface);
}
core::string imx::get_title() const {
return {};
}
void imx::set_title(const core::string &title) {
}
std::pair<graphics::pixel_position, graphics::pixel_size> imx::get_current_geometry() const {
return {};
}
}
添加gui/events/imx.h++、gui/events/imx.c++,处理鼠标、按键等事件的处理,该部分待完善
//gui/events/imx.h++
namespace skui::gui::events {
class imx : public base {
public:
imx(gui::window &window);
~imx() override;
void exec() override;
};
}
//gui/events/imx.c++
namespace skui::gui::events {
imx::imx(gui::window &window)
: base{window} {
}
imx::~imx() = default;
void imx::exec() {
while (true) {
sleep(1);
window.update();
}
}
}
添加gui/events_imx.c++、gui/native_window_imx.c++,对gui::events::imx和gui::native_window:imx实例化
//gui/events_imx.c++
namespace skui::gui::events {
std::unique_ptr<base> create(window &window) {
return std::make_unique<events::imx>(window);
}
}
//gui/native_window_imx.c++
namespace skui::gui::native_window {
std::unique_ptr<base> create(const graphics::pixel_position &position,
const graphics::pixel_size &size,
const window_flags &flags) {
std::unique_ptr<base> window;
if (flags.test(window_flag::opengl)) {
window = std::make_unique<imx>();
} else
window = std::make_unique<imx>();
window->create(position, size);
return window;
}
}
添加gui/window_imx.c++,添加一些flag
//gui/window_imx.c++
namespace skui::gui {
const window_flags window::default_flags =
window_flag::exit_on_close | window_flag::opengl | window_flag::anti_alias;
}