mirror of
https://github.com/zetaPRIME/libstarlight.git
synced 2025-06-26 05:32:46 +00:00
thread testing and fixes, exposed blend mode in drawables, made frame timing a bit more accurate
This commit is contained in:
parent
c4a75355eb
commit
88d640f3e7
@ -98,6 +98,7 @@ void Application::_end() {
|
||||
}
|
||||
|
||||
void Application::_mainLoop() {
|
||||
RenderCore::SyncFrame(); // sync to vblank here for more accurate timing
|
||||
frameTimer.FrameStart();
|
||||
|
||||
if (!forms.empty()) {
|
||||
@ -159,7 +160,7 @@ void Application::_mainLoop() {
|
||||
|
||||
while (!threads.empty() && frameTimer.GetSubframe() < 0.9) {
|
||||
threads.front()->Resume();
|
||||
threads.splice(threads.end(), threads, threads.begin()); // move to back of queue
|
||||
if (threads.size() > 1) threads.splice(threads.end(), threads, threads.begin()); // move to back of queue
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ void DrawContextCanvas::Clear(Color color) {
|
||||
void DrawContextCanvas::Clear() { Clear(Color(0,0,0,0)); }
|
||||
|
||||
// drawable stuff
|
||||
void DrawContextCanvas::Draw(const Vector2& position, const Vector2& origin, OptRef<VRect> sampleRect, OptRef<Color> color, float rotation, const Vector2& scale) {
|
||||
void DrawContextCanvas::Draw(const Vector2& position, const Vector2& origin, OptRef<VRect> sampleRect, OptRef<Color> color, float rotation, const Vector2& scale, BlendMode mode) {
|
||||
if (GFXManager::PrepareForDrawing()) {
|
||||
target->Bind(color ? color.get() : Color(1,1,1,1));
|
||||
const VRect& sr = sampleRect ? sampleRect.get() : this->rect;
|
||||
@ -54,7 +54,7 @@ void DrawContextCanvas::Draw(const Vector2& position, const Vector2& origin, Opt
|
||||
}
|
||||
}
|
||||
|
||||
void DrawContextCanvas::Draw(const VRect& rect, OptRef<VRect> sampleRect, OptRef<Color> color) {
|
||||
void DrawContextCanvas::Draw(const VRect& rect, OptRef<VRect> sampleRect, OptRef<Color> color, BlendMode mode) {
|
||||
if (GFXManager::PrepareForDrawing()) {
|
||||
target->Bind(color ? color.get() : Color(1,1,1,1));
|
||||
const VRect& sr = sampleRect ? sampleRect.get() : this->rect;
|
||||
|
@ -23,8 +23,8 @@ namespace starlight {
|
||||
DrawContextCanvas(Vector2 size);
|
||||
~DrawContextCanvas();
|
||||
|
||||
void Draw(const Vector2& position, const Vector2& origin = Vector2::zero, OptRef<VRect> sampleRect = nullptr, OptRef<Color> color = nullptr, float rotation = 0, const Vector2& scale = Vector2::one) override;
|
||||
void Draw(const VRect& rect, OptRef<VRect> sampleRect = nullptr, OptRef<Color> color = nullptr) override;
|
||||
void Draw(const Vector2& position, const Vector2& origin = Vector2::zero, OptRef<VRect> sampleRect = nullptr, OptRef<Color> color = nullptr, float rotation = 0, const Vector2& scale = Vector2::one, BlendMode mode = BlendMode::Normal) override;
|
||||
void Draw(const VRect& rect, OptRef<VRect> sampleRect = nullptr, OptRef<Color> color = nullptr, BlendMode mode = BlendMode::Normal) override;
|
||||
|
||||
Vector2 Size() override;
|
||||
|
||||
@ -32,4 +32,4 @@ namespace starlight {
|
||||
void Clear() override;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,8 @@
|
||||
|
||||
#include "starlight/datatypes/OptRef.h"
|
||||
|
||||
#include "starlight/gfx/Enums.h"
|
||||
|
||||
namespace starlight {
|
||||
namespace gfx {
|
||||
class Drawable {
|
||||
@ -17,16 +19,14 @@ namespace starlight {
|
||||
// pattern after:
|
||||
// public abstract void Draw(DrawContext context, PxRect rect, PxRect? sampleRect = null, DrawColor? color = null);
|
||||
// public abstract void Draw(DrawContext context, FxVector position, FxVector? align = null, PxRect? sampleRect = null, DrawColor? color = null, float rotation = 0, FxVector? scale = null);
|
||||
virtual void Draw(const Vector2& position, const Vector2& origin = Vector2::zero, OptRef<VRect> sampleRect = nullptr, OptRef<Color> color = nullptr, float rotation = 0, const Vector2& scale = Vector2::one) = 0;
|
||||
void Draw(const Vector2& position, OptRef<Vector2> hotspot, OptRef<VRect> sampleRect, OptRef<Color> color, float rotation, float scale) {
|
||||
Draw(position, hotspot, sampleRect, color, rotation, Vector2(scale, scale));
|
||||
virtual void Draw(const Vector2& position, const Vector2& origin = Vector2::zero, OptRef<VRect> sampleRect = nullptr, OptRef<Color> color = nullptr, float rotation = 0, const Vector2& scale = Vector2::one, BlendMode mode = BlendMode::Normal) = 0;
|
||||
void Draw(const Vector2& position, OptRef<Vector2> hotspot, OptRef<VRect> sampleRect, OptRef<Color> color, float rotation, float scale, BlendMode mode = BlendMode::Normal) {
|
||||
Draw(position, hotspot, sampleRect, color, rotation, Vector2(scale, scale), mode);
|
||||
}
|
||||
|
||||
virtual void Draw(const VRect& rect, OptRef<VRect> sampleRect = nullptr, OptRef<Color> color = nullptr) = 0;
|
||||
virtual void Draw(const VRect& rect, OptRef<VRect> sampleRect = nullptr, OptRef<Color> color = nullptr, BlendMode mode = BlendMode::Normal) = 0;
|
||||
|
||||
virtual Vector2 Size() = 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -15,18 +15,18 @@ using starlight::gfx::DrawableImage;
|
||||
using starlight::gfx::RenderCore;
|
||||
using starlight::gfx::CRenderTarget;
|
||||
|
||||
void DrawableImage::Draw(const Vector2& position, const Vector2& origin, OptRef<VRect> sampleRect, OptRef<Color> color, float rotation, const Vector2& scale) {
|
||||
void DrawableImage::Draw(const Vector2& position, const Vector2& origin, OptRef<VRect> sampleRect, OptRef<Color> color, float rotation, const Vector2& scale, BlendMode mode) {
|
||||
if (GFXManager::PrepareForDrawing()) {
|
||||
texture->Bind(color ? color.get() : Color(1,1,1,1));
|
||||
texture->Bind(color ? color.get() : Color(1,1,1,1), mode);
|
||||
const VRect& sr = sampleRect ? sampleRect.get() : VRect(Vector2::zero, texture->size);
|
||||
VRect rect(position - (texture->size * origin) * scale, sr.size * scale);
|
||||
RenderCore::DrawQuad(rect, position, rotation, sr / texture->txSize);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawableImage::Draw(const VRect& rect, OptRef<VRect> sampleRect, OptRef<Color> color) {
|
||||
void DrawableImage::Draw(const VRect& rect, OptRef<VRect> sampleRect, OptRef<Color> color, BlendMode mode) {
|
||||
if (GFXManager::PrepareForDrawing()) {
|
||||
texture->Bind(color ? color.get() : Color(1,1,1,1));
|
||||
texture->Bind(color ? color.get() : Color(1,1,1,1), mode);
|
||||
const VRect& sr = sampleRect ? sampleRect.get() : VRect(Vector2::zero, texture->size);
|
||||
RenderCore::DrawQuad(rect, sr / texture->txSize);
|
||||
}
|
||||
|
@ -15,11 +15,10 @@ namespace starlight {
|
||||
DrawableImage(CTexture* texture) : texture(texture) { }
|
||||
~DrawableImage() override { }
|
||||
|
||||
void Draw(const Vector2& position, const Vector2& origin = Vector2::zero, OptRef<VRect> sampleRect = nullptr, OptRef<Color> color = nullptr, float rotation = 0, const Vector2& scale = Vector2::one) override;
|
||||
void Draw(const VRect& rect, OptRef<VRect> sampleRect = nullptr, OptRef<Color> color = nullptr) override;
|
||||
void Draw(const Vector2& position, const Vector2& origin = Vector2::zero, OptRef<VRect> sampleRect = nullptr, OptRef<Color> color = nullptr, float rotation = 0, const Vector2& scale = Vector2::one, BlendMode mode = BlendMode::Normal) override;
|
||||
void Draw(const VRect& rect, OptRef<VRect> sampleRect = nullptr, OptRef<Color> color = nullptr, BlendMode mode = BlendMode::Normal) override;
|
||||
|
||||
Vector2 Size() override;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,9 +15,9 @@ using starlight::gfx::DrawableNinePatch;
|
||||
using starlight::gfx::RenderCore;
|
||||
using starlight::gfx::CRenderTarget;
|
||||
|
||||
void DrawableNinePatch::Draw(const VRect& rect, OptRef<VRect> sampleRect, OptRef<Color> color) {
|
||||
void DrawableNinePatch::Draw(const VRect& rect, OptRef<VRect> sampleRect, OptRef<Color> color, BlendMode mode) {
|
||||
if (GFXManager::PrepareForDrawing()) {
|
||||
texture->Bind(color ? color.get() : Color(1,1,1,1));
|
||||
texture->Bind(color ? color.get() : Color(1,1,1,1), mode);
|
||||
VRect rr = rect.IntSnap();
|
||||
const VRect& sr = (sampleRect ? sampleRect.get() : VRect(Vector2::zero, texture->size)).IntSnap();
|
||||
|
||||
|
@ -16,7 +16,7 @@ namespace starlight {
|
||||
~DrawableNinePatch() override { }
|
||||
|
||||
//void Draw(const Vector2& position, const Vector2& origin = Vector2::zero, OptRef<VRect> sampleRect = nullptr, OptRef<Color> color = nullptr, float rotation = 0, const Vector2& scale = Vector2::one) override;
|
||||
void Draw(const VRect& rect, OptRef<VRect> sampleRect = nullptr, OptRef<Color> color = nullptr) override;
|
||||
void Draw(const VRect& rect, OptRef<VRect> sampleRect = nullptr, OptRef<Color> color = nullptr, BlendMode mode = BlendMode::Normal) override;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,17 +11,16 @@ using starlight::gfx::DrawableTest;
|
||||
|
||||
using starlight::gfx::RenderCore;
|
||||
|
||||
void DrawableTest::Draw(const Vector2& position, const Vector2& origin, OptRef<VRect> sampleRect, OptRef<Color> color, float rotation, const Vector2& scale) {
|
||||
void DrawableTest::Draw(const Vector2& position, const Vector2& origin, OptRef<VRect> sampleRect, OptRef<Color> color, float rotation, const Vector2& scale, BlendMode mode) {
|
||||
if (GFXManager::PrepareForDrawing()) {
|
||||
//static u32 col = Color(0, 0.5f, 1);
|
||||
//sf2d_draw_rectangle_rotate(position.x, position.y, 16, 16, col, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawableTest::Draw(const VRect& rect, OptRef<VRect> sampleRect, OptRef<Color> color) {
|
||||
void DrawableTest::Draw(const VRect& rect, OptRef<VRect> sampleRect, OptRef<Color> color, BlendMode mode) {
|
||||
if (GFXManager::PrepareForDrawing()) {
|
||||
RenderCore::BindColor(color ? color.get() : Color(1,1,1,1));
|
||||
RenderCore::BindColor(color ? color.get() : Color(1,1,1,1), mode);
|
||||
RenderCore::DrawQuad(rect, VRect());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,11 +10,10 @@ namespace starlight {
|
||||
DrawableTest() { }
|
||||
~DrawableTest() override { }
|
||||
|
||||
void Draw(const Vector2& position, const Vector2& origin = Vector2::zero, OptRef<VRect> sampleRect = nullptr, OptRef<Color> color = nullptr, float rotation = 0, const Vector2& scale = Vector2::one) override;
|
||||
void Draw(const VRect& rect, OptRef<VRect> sampleRect = nullptr, OptRef<Color> color = nullptr) override;
|
||||
void Draw(const Vector2& position, const Vector2& origin = Vector2::zero, OptRef<VRect> sampleRect = nullptr, OptRef<Color> color = nullptr, float rotation = 0, const Vector2& scale = Vector2::one, BlendMode mode = BlendMode::Normal) override;
|
||||
void Draw(const VRect& rect, OptRef<VRect> sampleRect = nullptr, OptRef<Color> color = nullptr, BlendMode mode = BlendMode::Normal) override;
|
||||
|
||||
Vector2 Size() override { return Vector2::zero; }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
14
libstarlight/source/starlight/gfx/Enums.h
Normal file
14
libstarlight/source/starlight/gfx/Enums.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include "starlight/_global.h"
|
||||
|
||||
namespace starlight {
|
||||
namespace gfx {
|
||||
enum class BlendMode {
|
||||
Blend,
|
||||
Mask,
|
||||
Replace,
|
||||
|
||||
Normal = Blend
|
||||
};
|
||||
}
|
||||
}
|
@ -78,8 +78,8 @@ namespace { // internals
|
||||
C3D_TexDelete(texture);
|
||||
delete texture;
|
||||
}
|
||||
void Bind(Color color = Color::white) override {
|
||||
RenderCore::BindTexture(texture, color);
|
||||
void Bind(Color color = Color::white, BlendMode mode = BlendMode::Normal) override {
|
||||
RenderCore::BindTexture(texture, color, mode);
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -136,9 +136,13 @@ void RenderCore::Close() {
|
||||
gfxExit();
|
||||
}
|
||||
|
||||
void RenderCore::SyncFrame() {
|
||||
C3D_FrameSync();
|
||||
}
|
||||
|
||||
void RenderCore::BeginFrame() {
|
||||
ResetBuffer();
|
||||
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
|
||||
C3D_FrameBegin(0/*C3D_FRAME_SYNCDRAW*/);
|
||||
}
|
||||
|
||||
void RenderCore::EndFrame() {
|
||||
@ -322,7 +326,7 @@ void CRenderTarget::BindTarget() {
|
||||
}
|
||||
}
|
||||
|
||||
void CRenderTarget::Bind(Color color) {
|
||||
void CRenderTarget::Bind(Color color, BlendMode mode) {
|
||||
//C3D_RenderTargetSetClear(tgt, static_cast<C3D_ClearBits>(0), 0, 0); // don't clear again until marked to
|
||||
RenderCore::BindTexture(&tex, color);
|
||||
RenderCore::BindTexture(&tex, color, mode);
|
||||
}
|
||||
|
@ -9,19 +9,13 @@
|
||||
#include "starlight/datatypes/VRect.h"
|
||||
#include "starlight/datatypes/Color.h"
|
||||
|
||||
#include "starlight/gfx/Enums.h"
|
||||
|
||||
#include "starlight/util/WorkerThread.h"
|
||||
|
||||
namespace starlight {
|
||||
namespace gfx {
|
||||
class RenderCore;
|
||||
enum class BlendMode {
|
||||
Blend,
|
||||
Mask,
|
||||
Replace,
|
||||
|
||||
Normal = Blend
|
||||
};
|
||||
|
||||
class CTexture {
|
||||
protected:
|
||||
CTexture() = default;
|
||||
@ -31,7 +25,7 @@ namespace starlight {
|
||||
Vector2 txSize;
|
||||
|
||||
virtual ~CTexture() = default;
|
||||
virtual void Bind(Color color = Color::white) = 0;
|
||||
virtual void Bind(Color color = Color::white, BlendMode mode = BlendMode::Normal) = 0;
|
||||
};
|
||||
|
||||
class CRenderTarget : public CTexture {
|
||||
@ -51,7 +45,7 @@ namespace starlight {
|
||||
void Clear(Color color);
|
||||
void BindTarget();
|
||||
|
||||
void Bind(Color color = Color::white) override;
|
||||
void Bind(Color color = Color::white, BlendMode mode = BlendMode::Normal) override;
|
||||
};
|
||||
|
||||
class RenderCore {
|
||||
@ -67,6 +61,7 @@ namespace starlight {
|
||||
static void Open();
|
||||
static void Close();
|
||||
|
||||
static void SyncFrame();
|
||||
static void BeginFrame();
|
||||
static void EndFrame();
|
||||
|
||||
|
@ -41,8 +41,11 @@ void Thread::_FinishStart() {
|
||||
|
||||
void Thread::Yield() {
|
||||
if (state != ThreadState::Running) return; // not executing this right now, this would just futz it up
|
||||
state = ThreadState::Idle;
|
||||
svcWaitSynchronization(event, -1 /*U64_MAX*/);
|
||||
//svcWaitSynchronization(event, 65536);
|
||||
svcClearEvent(event);
|
||||
state = ThreadState::Running;
|
||||
}
|
||||
|
||||
void Thread::Resume() {
|
||||
|
@ -4,6 +4,7 @@
|
||||
roadmap to v0.5.1 {
|
||||
- clear bug workaround implemented
|
||||
^ maybe replace clearing with the workaround entirely?
|
||||
try to figure out why the workaround doesn't work in citra
|
||||
implement more blend modes {
|
||||
- flat replace
|
||||
masking
|
||||
@ -18,20 +19,19 @@ roadmap to v0.5.1 {
|
||||
fix `, ' and " glyph spacing/offset
|
||||
adjust /\ some?
|
||||
proper thread dispatch? {
|
||||
probably part of Application, actually
|
||||
|
||||
Application main loop keeps a(n abstracted) libctru TickCounter and keeps track of frame time
|
||||
thread objects are held in a std::list, Application dispatches resume events and splice()s them to the end until frame time reaches some proportion of 1/60s
|
||||
x.splice( x.end(), x, iter );
|
||||
- Application main loop keeps a(n abstracted) libctru TickCounter and keeps track of frame time
|
||||
- thread objects are held in a std::list, Application dispatches resume events and splice()s them to the end until frame time reaches some proportion of 1/60s
|
||||
- thread gets a yield function that calls svcWaitSynchronization on its resume event
|
||||
...and some mechanism for allowing it to opt out of the rest of the cycle
|
||||
|
||||
Trackable sideclass for threads; float progress 0..1, etc.
|
||||
MAKE THREADS END CLEANLY
|
||||
}
|
||||
} then by v0.5.5 {
|
||||
event propagation system of some sort; threadsafe to whatever extent is needed on 3DS
|
||||
figure out how to *actually* fix the clear bug...?
|
||||
} then consider these before 1.0 "gold" {
|
||||
replace some of the OptRef stuffs on invalidatable types with invalid checks; add implicit conversions from nullptr to invalid
|
||||
make closing forms a bit less finicky (add them to a separate list and let the Application remove them from the list)
|
||||
garbage collection for not-recently-used theme assets {
|
||||
- keep track of last-use in ThemeRefContainer
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "starlight/dialog/MessageBox.h"
|
||||
#include "starlight/dialog/OSK.h"
|
||||
|
||||
#include "ThreadTest.h"
|
||||
|
||||
using starlight::Vector2;
|
||||
using starlight::VRect;
|
||||
using starlight::Color;
|
||||
@ -88,6 +90,9 @@ void Core::Init() {
|
||||
// open a backdrop with the default asset
|
||||
sl::dialog::Backdrop::New()->Open();
|
||||
|
||||
// make a test thread
|
||||
std::make_shared<ThreadTest>()->Enqueue();
|
||||
|
||||
//
|
||||
};
|
||||
container->Add(button);
|
||||
|
21
testbed/source/ThreadTest.cpp
Normal file
21
testbed/source/ThreadTest.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
#include "ThreadTest.h"
|
||||
|
||||
#include "starlight/Application.h"
|
||||
#include "starlight/ConfigManager.h"
|
||||
|
||||
using starlight::Application;
|
||||
|
||||
void ThreadTest::Body() {
|
||||
auto& cc = Application::GetConfig("test");
|
||||
int count = 0;
|
||||
cc.Json()["pork"] = 0;
|
||||
cc.Save();
|
||||
cc.autoSave = true;
|
||||
|
||||
while(true) {
|
||||
|
||||
cc.Json()["pork"] = ++count;
|
||||
//cc.Save();
|
||||
Yield();
|
||||
}
|
||||
}
|
7
testbed/source/ThreadTest.h
Normal file
7
testbed/source/ThreadTest.h
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "starlight/threading/Thread.h"
|
||||
|
||||
class ThreadTest : public sl::threading::Thread {
|
||||
void Body() override;
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user