skui学习笔记(四)IMX8平台移植 中篇

二、修改源码

上篇是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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值