Skip to content

Commit

Permalink
karm-gfx: Started isolating the cpu rasterizer.
Browse files Browse the repository at this point in the history
  • Loading branch information
sleepy-monax committed Sep 1, 2024
1 parent 486f2d4 commit f6a2e9f
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 65 deletions.
4 changes: 2 additions & 2 deletions src/libs/karm-gfx/benchs/main.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include <karm-cli/cursor.h>
#include <karm-gfx/context.h>
#include <karm-gfx/cpu/canvas.h>
#include <karm-sys/entry.h>
#include <karm-sys/time.h>

Expand All @@ -12,7 +12,7 @@ Async::Task<> entryPointAsync(Sys::Context &) {
for (isize size = 100; size < 1000; size += 10) {
f64 scale = size / 100.0;

Gfx::Context g;
Gfx::CpuCanvas g;
g.begin(surface->mutPixels());
g.scale(scale);

Expand Down
99 changes: 49 additions & 50 deletions src/libs/karm-gfx/context.cpp → src/libs/karm-gfx/cpu/canvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,78 +2,77 @@
#include <karm-logger/logger.h>
#include <karm-math/funcs.h>

#include "context.h"
#include "stroke.h"
#include "canvas.h"

namespace Karm::Gfx {

// MARK: Buffers ---------------------------------------------------------------

void Context::begin(MutPixels p) {
void CpuCanvas::begin(MutPixels p) {
_pixels = p;
_stack.pushBack({
.clip = pixels().bound(),
});
}

void Context::end() {
void CpuCanvas::end() {
if (_stack.len() != 1) [[unlikely]]
panic("save/restore mismatch");

_stack.popBack();
_pixels = NONE;
}

MutPixels Context::mutPixels() {
MutPixels CpuCanvas::mutPixels() {
return _pixels.unwrap("no pixels");
}

// Get the pxeils being drawn on.
Pixels Context::pixels() const {
Pixels CpuCanvas::pixels() const {
return _pixels.unwrap("no pixels");
}

Context::Scope &Context::current() {
CpuCanvas::Scope &CpuCanvas::current() {
return last(_stack);
}

Context::Scope const &Context::current() const {
CpuCanvas::Scope const &CpuCanvas::current() const {
return last(_stack);
}

// MARK: Context Operations ----------------------------------------------------

void Context::push() {
void CpuCanvas::push() {
if (_stack.len() > 100) [[unlikely]]
panic("context stack overflow");

_stack.pushBack(current());
}

void Context::pop() {
void CpuCanvas::pop() {
if (_stack.len() == 1) [[unlikely]]
panic("context without save");

_stack.popBack();
}

void Context::fillStyle(Fill fill) {
void CpuCanvas::fillStyle(Fill fill) {
current().fill = fill;
}

void Context::strokeStyle(Stroke style) {
void CpuCanvas::strokeStyle(Stroke style) {
current().stroke = style;
}

void Context::transform(Math::Trans2f trans) {
void CpuCanvas::transform(Math::Trans2f trans) {
auto &t = current().trans;
t = trans.multiply(t);
}

// MARK: Path Operations -------------------------------------------------------

void Context::_fillImpl(auto fill, auto format, FillRule fillRule) {
_rast.fill(_poly, current().clip, fillRule, [&](Rast::Frag frag) {
void CpuCanvas::_fillImpl(auto fill, auto format, FillRule fillRule) {
_rast.fill(_poly, current().clip, fillRule, [&](CpuRast::Frag frag) {
auto pixels = mutPixels();
auto *pixel = pixels.pixelUnsafe(frag.xy);
auto color = fill.sample(frag.uv);
Expand All @@ -83,13 +82,13 @@ void Context::_fillImpl(auto fill, auto format, FillRule fillRule) {
});
}

void Context::_FillSmoothImpl(auto fill, auto format, FillRule fillRule) {
void CpuCanvas::_FillSmoothImpl(auto fill, auto format, FillRule fillRule) {
Math::Vec2f last = {0, 0};
auto fillComponent = [&](auto comp, Math::Vec2f pos) {
_poly.offset(pos - last);
last = pos;

_rast.fill(_poly, current().clip, fillRule, [&](Rast::Frag frag) {
_rast.fill(_poly, current().clip, fillRule, [&](CpuRast::Frag frag) {
u8 *pixel = static_cast<u8 *>(mutPixels().pixelUnsafe(frag.xy));
auto color = fill.sample(frag.uv);
auto c = format.load(pixel);
Expand All @@ -103,7 +102,7 @@ void Context::_FillSmoothImpl(auto fill, auto format, FillRule fillRule) {
fillComponent(Color::BLUE_COMPONENT, _lcdLayout.blue);
}

void Context::_fill(Fill fill, FillRule fillRule) {
void CpuCanvas::_fill(Fill fill, FillRule fillRule) {
fill.visit([&](auto fill) {
pixels().fmt().visit([&](auto format) {
if (_useSpaa)
Expand All @@ -114,83 +113,83 @@ void Context::_fill(Fill fill, FillRule fillRule) {
});
}

void Context::beginPath() {
void CpuCanvas::beginPath() {
_path.clear();
}

void Context::closePath() {
void CpuCanvas::closePath() {
_path.close();
}

void Context::moveTo(Math::Vec2f p, Math::Path::Flags flags) {
void CpuCanvas::moveTo(Math::Vec2f p, Math::Path::Flags flags) {
_path.moveTo(p, flags);
}

void Context::lineTo(Math::Vec2f p, Math::Path::Flags flags) {
void CpuCanvas::lineTo(Math::Vec2f p, Math::Path::Flags flags) {
_path.lineTo(p, flags);
}

void Context::hlineTo(f64 x, Math::Path::Flags flags) {
void CpuCanvas::hlineTo(f64 x, Math::Path::Flags flags) {
_path.hlineTo(x, flags);
}

void Context::vlineTo(f64 y, Math::Path::Flags flags) {
void CpuCanvas::vlineTo(f64 y, Math::Path::Flags flags) {
_path.vlineTo(y, flags);
}

void Context::cubicTo(Math::Vec2f cp1, Math::Vec2f cp2, Math::Vec2f p, Math::Path::Flags flags) {
void CpuCanvas::cubicTo(Math::Vec2f cp1, Math::Vec2f cp2, Math::Vec2f p, Math::Path::Flags flags) {
_path.cubicTo(cp1, cp2, p, flags);
}

void Context::quadTo(Math::Vec2f cp, Math::Vec2f p, Math::Path::Flags flags) {
void CpuCanvas::quadTo(Math::Vec2f cp, Math::Vec2f p, Math::Path::Flags flags) {
_path.quadTo(cp, p, flags);
}

void Context::arcTo(Math::Vec2f radii, f64 angle, Math::Vec2f p, Math::Path::Flags flags) {
void CpuCanvas::arcTo(Math::Vec2f radii, f64 angle, Math::Vec2f p, Math::Path::Flags flags) {
_path.arcTo(radii, angle, p, flags);
}

void Context::line(Math::Edgef line) {
void CpuCanvas::line(Math::Edgef line) {
_path.line(line);
}

void Context::curve(Math::Curvef curve) {
void CpuCanvas::curve(Math::Curvef curve) {
_path.curve(curve);
}

void Context::rect(Math::Rectf rect, Math::Radiif radii) {
void CpuCanvas::rect(Math::Rectf rect, Math::Radiif radii) {
_path.rect(rect, radii);
}

void Context::path(Math::Path const &path) {
void CpuCanvas::path(Math::Path const &path) {
_path.path(path);
}

void Context::ellipse(Math::Ellipsef ellipse) {
void CpuCanvas::ellipse(Math::Ellipsef ellipse) {
_path.ellipse(ellipse);
}

void Context::fill(FillRule rule) {
void CpuCanvas::fill(FillRule rule) {
_poly.clear();
createSolid(_poly, _path);
_poly.transform(current().trans);
_fill(current().fill, rule);
}

void Context::stroke() {
void CpuCanvas::stroke() {
_poly.clear();
createStroke(_poly, _path, current().stroke);
_poly.transform(current().trans);
_fill(current().stroke.fill);
}

void Context::clip(FillRule) {
void CpuCanvas::clip(FillRule) {
notImplemented();
}

// MARK: Shape Operations ------------------------------------------------------

[[gnu::flatten]] void Context::_fillRect(Math::Recti r, Gfx::Color color) {
[[gnu::flatten]] void CpuCanvas::_fillRect(Math::Recti r, Gfx::Color color) {
r = current().trans.apply(r.cast<f64>()).cast<isize>();
r = current().clip.clipTo(r);

Expand All @@ -210,7 +209,7 @@ void Context::clip(FillRule) {
}
}

void Context::fill(Math::Recti r, Math::Radiif radii) {
void CpuCanvas::fill(Math::Recti r, Math::Radiif radii) {
beginPath();
rect(r.cast<f64>(), radii);

Expand All @@ -226,38 +225,38 @@ void Context::fill(Math::Recti r, Math::Radiif radii) {
}
}

void Context::clip(Math::Rectf rect) {
void CpuCanvas::clip(Math::Rectf rect) {
rect = current().trans.apply(rect.cast<f64>());
current().clip = rect.cast<isize>().clipTo(current().clip);
}

void Context::stroke(Math::Path const &path) {
void CpuCanvas::stroke(Math::Path const &path) {
_poly.clear();
createStroke(_poly, path, current().stroke);
_poly.transform(current().trans);
_fill(current().stroke.fill);
}

void Context::fill(Math::Path const &path, FillRule rule) {
void CpuCanvas::fill(Math::Path const &path, FillRule rule) {
_poly.clear();
createSolid(_poly, path);
_poly.transform(current().trans);
_fill(current().fill, rule);
}

void Context::fill(Text::Font &font, Text::Glyph glyph, Math::Vec2f baseline) {
void CpuCanvas::fill(Text::Font &font, Text::Glyph glyph, Math::Vec2f baseline) {
_useSpaa = true;
Canvas::fill(font, glyph, baseline);
_useSpaa = false;
}

// MARK: Clear Operations ------------------------------------------------------

void Context::clear(Color color) {
void CpuCanvas::clear(Color color) {
clear(current().clip, color);
}

void Context::clear(Math::Recti rect, Color color) {
void CpuCanvas::clear(Math::Recti rect, Color color) {
rect = current().trans.apply(rect.cast<f64>()).cast<isize>();
rect = current().clip.clipTo(rect);
mutPixels()
Expand All @@ -267,14 +266,14 @@ void Context::clear(Math::Recti rect, Color color) {

// MARK: Plot Operations ---------------------------------------------------

void Context::plot(Math::Vec2i point, Color color) {
void CpuCanvas::plot(Math::Vec2i point, Color color) {
point = current().trans.apply(point.cast<f64>()).cast<isize>();
if (current().clip.contains(point)) {
mutPixels().blend(point, color);
}
}

void Context::plot(Math::Edgei edge, Color color) {
void CpuCanvas::plot(Math::Edgei edge, Color color) {
isize dx = Math::abs(edge.ex - edge.sx);
isize sx = edge.sx < edge.ex ? 1 : -1;

Expand All @@ -299,7 +298,7 @@ void Context::plot(Math::Edgei edge, Color color) {
}
}

void Context::plot(Math::Recti rect, Color color) {
void CpuCanvas::plot(Math::Recti rect, Color color) {
rect = {rect.xy, rect.wh - 1};
plot(Math::Edgei{rect.topStart(), rect.topEnd()}, color);
plot(Math::Edgei{rect.topEnd(), rect.bottomEnd()}, color);
Expand All @@ -309,7 +308,7 @@ void Context::plot(Math::Recti rect, Color color) {

// MARK: Blit Operations -------------------------------------------------------

[[gnu::flatten]] void Context::_blit(
[[gnu::flatten]] void CpuCanvas::_blit(
Pixels src, Math::Recti srcRect, auto srcFmt,
MutPixels dest, Math::Recti destRect, auto destFmt
) {
Expand Down Expand Up @@ -340,7 +339,7 @@ void Context::plot(Math::Recti rect, Color color) {
}
}

void Context::blit(Math::Recti src, Math::Recti dest, Pixels p) {
void CpuCanvas::blit(Math::Recti src, Math::Recti dest, Pixels p) {
auto d = mutPixels();
d.fmt().visit([&](auto dfmt) {
p.fmt().visit([&](auto pfmt) {
Expand All @@ -351,11 +350,11 @@ void Context::blit(Math::Recti src, Math::Recti dest, Pixels p) {

// MARK: Filter Operations -----------------------------------------------------

void Context::apply(Filter filter) {
void CpuCanvas::apply(Filter filter) {
apply(filter, pixels().bound());
}

void Context::apply(Filter filter, Math::Recti r) {
void CpuCanvas::apply(Filter filter, Math::Recti r) {
r = current().trans.apply(r.cast<f64>()).cast<isize>();
r = current().clip.clipTo(r);

Expand Down
14 changes: 7 additions & 7 deletions src/libs/karm-gfx/context.h → src/libs/karm-gfx/cpu/canvas.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#pragma once

#include "buffer.h"
#include "canvas.h"
#include "fill.h"
#include "filters.h"
#include "../buffer.h"
#include "../canvas.h"
#include "../fill.h"
#include "../filters.h"
#include "../stroke.h"
#include "rast.h"
#include "stroke.h"

namespace Karm::Gfx {

Expand All @@ -19,7 +19,7 @@ static LcdLayout RGB = {{+0.33, 0.0}, {0.0, 0.0}, {-0.33, 0.0}};
static LcdLayout BGR = {{-0.33, 0.0}, {0.0, 0.0}, {+0.33, 0.0}};
static LcdLayout VRGB = {{0.0, +0.33}, {0.0, 0.0}, {0.0, -0.33}};

struct Context : public Canvas {
struct CpuCanvas : public Canvas {
struct Scope {
Fill fill = Gfx::WHITE;
Stroke stroke{};
Expand All @@ -31,7 +31,7 @@ struct Context : public Canvas {
Vec<Scope> _stack{};
Math::Path _path{};
Math::Polyf _poly;
Rast _rast{};
CpuRast _rast{};
LcdLayout _lcdLayout = RGB;
bool _useSpaa = false;

Expand Down
4 changes: 2 additions & 2 deletions src/libs/karm-gfx/rast.h → src/libs/karm-gfx/cpu/rast.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
#include <karm-base/range.h>
#include <karm-math/poly.h>

#include "types.h"
#include "../types.h"

namespace Karm::Gfx {

struct Rast {
struct CpuRast {
static constexpr auto AA = 3;
static constexpr auto UNIT = 1.0f / AA;
static constexpr auto HALF_UNIT = 1.0f / AA / 2.0;
Expand Down
Loading

0 comments on commit f6a2e9f

Please sign in to comment.