Skip to content

Commit

Permalink
WIP: Switch support
Browse files Browse the repository at this point in the history
  • Loading branch information
XITRIX committed Dec 21, 2024
1 parent 41a4254 commit d97a69f
Show file tree
Hide file tree
Showing 11 changed files with 324 additions and 6 deletions.
35 changes: 34 additions & 1 deletion Submodules/UIKit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,39 @@ if (APPLE)
lib/platforms/apple/ios/SkiaCtx_ios.mm
)
endif ()
elseif (PLATFORM_SWITCH)
target_sources(UIKit PRIVATE
lib/platforms/SkiaCtx_sdlBase.cpp
lib/platforms/switch/SkiaCtx_switch.cpp
)

find_package(PkgConfig REQUIRED)
pkg_check_modules(SDL2 REQUIRED sdl2)
message(STATUS "SDL2 Path: \"${SDL2_INCLUDE_DIRS}\"")
target_link_libraries(${PROJECT_NAME} PRIVATE ${SDL2_LIBRARIES})
target_include_directories(${PROJECT_NAME} PUBLIC ${SDL2_INCLUDE_DIRS})

# GPU
target_link_libraries(UIKit PUBLIC EGL glapi GLESv2 drm_nouveau nx)


target_link_libraries(UIKit PUBLIC
${EXTERN_PATH}/skia/out/horizon/libskia.a
${EXTERN_PATH}/skia/out/horizon/libskparagraph.a
${EXTERN_PATH}/skia/out/horizon/libskshaper.a
${EXTERN_PATH}/skia/out/horizon/libskunicode_core.a
${EXTERN_PATH}/skia/out/horizon/libskunicode_icu.a
${EXTERN_PATH}/skia/out/horizon/libicu.a
${EXTERN_PATH}/skia/out/horizon/libskcms.a
freetype
expat
jpeg
png
bz2
z


)
endif ()

target_include_directories(UIKit PUBLIC
Expand All @@ -118,4 +151,4 @@ if (APPLE)
list(APPEND platform_libs "-framework Foundation" "-framework VideoToolbox" "-framework AVKit" "-framework MetalKit" "-framework CoreText")
endif ()

target_link_libraries(UIKit PRIVATE ${platform_libs})
target_link_libraries(UIKit PUBLIC ${platform_libs})
2 changes: 2 additions & 0 deletions Submodules/UIKit/include/UIEvent.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#include <Timer.h>
#include <set>
#include <memory>
#include <vector>

namespace NXKit {

Expand Down
34 changes: 34 additions & 0 deletions Submodules/UIKit/include/platforms/switch/SkiaCtx_switch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#pragma once

#include <SDL.h>
#include <SkiaCtx.h>
#include <platforms/SkiaCtx_sdlBase.h>
#include <include/gpu/ganesh/GrDirectContext.h>

namespace NXKit {

class SkiaCtx_switch: public SkiaCtx_sdlBase {
public:
SkiaCtx_switch();

sk_sp<SkSurface> getBackbufferSurface() override;
// float getScaleFactor() override;
sk_sp<GrDirectContext> directContext() override { return context; }


virtual void swapBuffers() override;

virtual NXSize getSize() override;

virtual float getScaleFactor() override;

private:
SDL_Window *window = nullptr;

sk_sp<GrDirectContext> context;
sk_sp<SkSurface> surface;

void initContext();
};

}
1 change: 1 addition & 0 deletions Submodules/UIKit/lib/CABasicAnimation.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <CABasicAnimation.h>
#include <cmath>

using namespace NXKit;

Expand Down
3 changes: 2 additions & 1 deletion Submodules/UIKit/lib/CADisplayLink.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <CADisplayLink.h>
#include <utility>
#include <algorithm>

namespace NXKit {
std::vector<CADisplayLink*> CADisplayLink::activeLinks;
Expand All @@ -18,4 +19,4 @@ namespace NXKit {
isRunning = false;
activeLinks.erase(std::remove(activeLinks.begin(), activeLinks.end(), this), activeLinks.end());
}
}
}
1 change: 1 addition & 0 deletions Submodules/UIKit/lib/Geometry.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <Geometry.h>
#include <algorithm>
#include <math.h>

#include "NXAffineTransform.h"
#include "NXTransform3D.h"
Expand Down
4 changes: 2 additions & 2 deletions Submodules/UIKit/lib/NXData.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include <NXData.h>
//#include <Tools/Tools.hpp>
#include <tools/Tools.hpp>
#include <SDL2/SDL.h>

//#ifdef USE_LIBROMFS
Expand Down Expand Up @@ -45,7 +45,7 @@ std::shared_ptr<NXData> NXData::fromPath(const std::string& path) {
fileReader->close(fileReader);

if (bytesRead == fileSize) {
return make_shared<NXData>(buffer, fileSize, true);
return new_shared<NXData>(buffer, fileSize, true);
} else {
delete[] buffer;
return nullptr;
Expand Down
2 changes: 2 additions & 0 deletions Submodules/UIKit/lib/UIGestureRecognizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include <UITouch.h>
#include <UIPress.h>

#include <algorithm>

namespace NXKit {

UIGestureRecognizer::UIGestureRecognizer(std::function<void(std::shared_ptr<UIGestureRecognizer>)> onStateChanged):
Expand Down
12 changes: 11 additions & 1 deletion Submodules/UIKit/lib/platforms/SkiaCtx_sdlBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,17 @@ SkiaCtx_sdlBase::SkiaCtx_sdlBase()
SDL_Init(SDL_INIT_EVERYTHING);
Uint32 flags = SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_RESIZABLE;

#ifdef USE_GLES
#ifdef __SWITCH__
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);

flags |= SDL_WINDOW_OPENGL;
#elif defined(USE_GLES)
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
Expand Down
213 changes: 213 additions & 0 deletions Submodules/UIKit/lib/platforms/switch/SkiaCtx_switch.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
#include <platforms/switch/SkiaCtx_switch.h>

#include "include/core/SkColorSpace.h"
#include <include/core/SkGraphics.h>
#include "include/gpu/ganesh/gl/GrGLDirectContext.h"
#include "include/gpu/ganesh/gl/GrGLInterface.h"
#include "include/gpu/ganesh/gl/GrGLBackendSurface.h"
#include "include/gpu/ganesh/gl/ios/GrGLMakeIOSInterface.h"
#include "include/gpu/ganesh/SkSurfaceGanesh.h"
#include "include/gpu/ganesh/GrDirectContext.h"
#include "include/gpu/ganesh/GrBackendSurface.h"
#include "include/gpu/ganesh/gl/GrGLAssembleInterface.h"
#include "include/gpu/ganesh/gl/GrGLInterface.h"
#include "include/private/base/SkTemplates.h"

#include "include/gpu/ganesh/gl/egl/GrGLMakeEGLInterface.h"
#include "include/ports/SkFontMgr_empty.h"

#include <GLES3/gl3.h>


// Include the main libnx system header, for Switch development
#include <switch.h>

#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GL/gl.h>

using namespace NXKit;

static EGLDisplay s_display;
static EGLContext s_context;
static EGLSurface s_surface;

static bool initEgl(NWindow* win)
{
// Connect to the EGL default display
s_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (!s_display)
{
// LTRACEF("Could not connect to display! error: %d", eglGetError());
goto _fail0;
}

// Initialize the EGL display connection
eglInitialize(s_display, nullptr, nullptr);

// Select OpenGL (Core) as the desired graphics API
if (eglBindAPI(EGL_OPENGL_API) == EGL_FALSE)
{
// LTRACEF("Could not set API! error: %d", eglGetError());
goto _fail1;
}

// Get an appropriate EGL framebuffer configuration
EGLConfig config;
EGLint numConfigs;
static const EGLint framebufferAttributeList[] =
{
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_DEPTH_SIZE, 24,
EGL_STENCIL_SIZE, 8,
EGL_NONE
};
eglChooseConfig(s_display, framebufferAttributeList, &config, 1, &numConfigs);
if (numConfigs == 0)
{
// LTRACEF("No config found! error: %d", eglGetError());
goto _fail1;
}

// Create an EGL window surface
s_surface = eglCreateWindowSurface(s_display, config, win, nullptr);
if (!s_surface)
{
// LTRACEF("Surface creation failed! error: %d", eglGetError());
goto _fail1;
}

// Create an EGL rendering context
static const EGLint contextAttributeList[] =
{
EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR,
EGL_CONTEXT_MAJOR_VERSION_KHR, 4,
EGL_CONTEXT_MINOR_VERSION_KHR, 3,
EGL_NONE
};
s_context = eglCreateContext(s_display, config, EGL_NO_CONTEXT, contextAttributeList);
if (!s_context)
{
// LTRACEF("Context creation failed! error: %d", eglGetError());
goto _fail2;
}

// Connect the context to the surface
eglMakeCurrent(s_display, s_surface, s_surface, s_context);
return true;

_fail2:
eglDestroySurface(s_display, s_surface);
s_surface = nullptr;
_fail1:
eglTerminate(s_display);
s_display = nullptr;
_fail0:
return false;
}

static void deinitEgl()
{
if (s_display)
{
eglMakeCurrent(s_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (s_context)
{
eglDestroyContext(s_display, s_context);
s_context = nullptr;
}
if (s_surface)
{
eglDestroySurface(s_display, s_surface);
s_surface = nullptr;
}
eglTerminate(s_display);
s_display = nullptr;
}
}

SkiaCtx_switch::SkiaCtx_switch() {
if (!initEgl(nwindowGetDefault()))
exit(1);


SDL_Init(SDL_INIT_EVERYTHING);
// Uint32 flags = SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_RESIZABLE;

// SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
// SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
// SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
// SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
// SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
// SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 0);
// SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);

// flags |= SDL_WINDOW_OPENGL;
// window = SDL_CreateWindow("Window", 12, 12, 1280, 720, flags);
// auto context = SDL_GL_CreateContext(window);
// SDL_GL_MakeCurrent(window, context);

SkGraphics::Init();
initContext();

// fontMgr = SkFontMgr_New_Custom_Empty();
}

void SkiaCtx_switch::initContext() {
auto interface = GrGLInterfaces::MakeEGL();
auto ctx = GrDirectContexts::MakeGL(interface);
}

//float SkiaCtx_switch::getScaleFactor() {
// return NSApplication.sharedApplication.keyWindow.backingScaleFactor;
//}

sk_sp<SkSurface> SkiaCtx_switch::getBackbufferSurface() {
auto size = getSize();
if (_size.width == size.width && _size.height == size.height && surface != nullptr) { return surface; }

_size = size;

GrGLFramebufferInfo framebuffer_info;
framebuffer_info.fFormat = GL_RGBA8;
framebuffer_info.fFBOID = 0;
auto scaleFactor = getScaleFactor();
GrBackendRenderTarget target = GrBackendRenderTargets::MakeGL(size.width * scaleFactor,
size.height * scaleFactor,
0, 8,
framebuffer_info);

SkSurfaceProps props;

glViewport(0, 0, _size.width * scaleFactor, _size.height * scaleFactor);
surface = SkSurfaces::WrapBackendRenderTarget(context.get(), target,
kBottomLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
nullptr, &props);

return surface;
}

std::unique_ptr<SkiaCtx> NXKit::MakeSkiaCtx() {
return std::make_unique<SkiaCtx_switch>();
}

bool NXKit::platformRunLoop(std::function<bool()> loop) {
return loop();
}

void SkiaCtx_switch::swapBuffers() {
eglSwapBuffers(s_display, s_surface);
}

NXSize SkiaCtx_switch::getSize() {
return { 1280, 720 };
}

float SkiaCtx_switch::getScaleFactor() {
return 1;
}

Loading

0 comments on commit d97a69f

Please sign in to comment.