blob: 7ba6bf812e416dcf23f6c3981a030037f8408e10 [file] [log] [blame]
#include "../api/implicit_cast.h"
#include "../api/pixel_formats.h"
#include "../api/draw.h"
#include "slides.h"
#include <SDL.h>
#include <chrono>
#include <cstdio>
#include <cstdlib>
#include <memory>
using namespace eskia;
#if 0
static constexpr auto PIXEL_FORMAT = SDL_PIXELFORMAT_RGB565;
using Pixel = BGR_565;
constexpr auto src = src_BGR_565,
srcover = srcover_BGR_565;
#elif 0
static constexpr auto PIXEL_FORMAT = SDL_PIXELFORMAT_BGR565;
using Pixel = RGB_565;
constexpr auto src = src_RGB_565,
srcover = srcover_RGB_565;
#elif 0
static constexpr auto PIXEL_FORMAT = SDL_PIXELFORMAT_RGB24;
using Pixel = RGB_888;
constexpr auto src = src_RGB_888,
srcover = srcover_RGB_888;
#elif 1
static constexpr auto PIXEL_FORMAT = SDL_PIXELFORMAT_RGBA32;
using Pixel = RGBA_8888;
constexpr auto src = src_RGBA_8888,
srcover = srcover_RGBA_8888;
#else
static constexpr auto PIXEL_FORMAT = SDL_PIXELFORMAT_BGRA32;
using Pixel = BGRA_8888;
constexpr auto src = src_BGRA_8888,
srcover = srcover_BGRA_8888;
#endif
template <typename T, typename C>
static std::unique_ptr<T,C> make_unique(C cleanup, T* ptr) {
return {ptr, cleanup};
}
int main(int, char**) {
int w = 400,
h = 400;
SDL_Init(SDL_INIT_VIDEO);
auto window = make_unique(SDL_DestroyWindow,
SDL_CreateWindow("demo",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
w,h,
SDL_WINDOW_ALLOW_HIGHDPI));
auto renderer = make_unique(SDL_DestroyRenderer,
SDL_CreateRenderer(window.get(), -1, 0));
// Workaround for the window not drawing until you move/resize on Mac 10.14.
SDL_PumpEvents();
SDL_GetWindowSize(window.get(), &w,&h);
SDL_SetWindowSize(window.get(), w, h);
auto tex = make_unique(SDL_DestroyTexture,
SDL_CreateTexture(renderer.get(),
PIXEL_FORMAT,
SDL_TEXTUREACCESS_STREAMING,
w,h));
auto buf = std::make_unique<Pixel[]>(implicit_cast<size_t>(w*h));
bool done = false;
auto last_title_update = std::chrono::steady_clock::now();
auto slide_iterator = slides;
auto slide = *slide_iterator;
Frame frame{implicit_cast<void*>(buf.get()), w,h, sizeof(Pixel), w, src,srcover};
while (!done) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
default: break;
case SDL_QUIT:
done = true;
break;
case SDL_KEYUP:
switch (event.key.keysym.sym) {
case SDLK_RIGHT:
if ( slide_iterator[+1] ) {
slide = *(++slide_iterator);
}
break;
case SDLK_LEFT:
if ( slide_iterator > slides ) {
slide = *(--slide_iterator);
}
break;
}
}
}
const auto start = std::chrono::steady_clock::now();
{
Paint paint;
paint.color = RGBA_8888{255,255,255,255};
frame.draw({0,0,w,h}, paint, single_color, frame.src);
}
const auto clear = std::chrono::steady_clock::now();
{
slide(&frame);
}
const auto draw = std::chrono::steady_clock::now();
// The rest is format converting, uploading, etc.
// Push that up to our texture.
SDL_UpdateTexture(tex.get(), nullptr, buf.get(), implicit_cast<int>(sizeof(Pixel))*w);
// Copy the texture to the window backbuffer.
SDL_RenderClear(renderer.get());
SDL_RenderCopy(renderer.get(), tex.get(), nullptr, nullptr);
// Swap buffers.
SDL_RenderPresent(renderer.get());
// Our draw and everything SDL needs to do on the CPU is done.
const auto push = std::chrono::steady_clock::now();
if (last_title_update < push - std::chrono::milliseconds(100)) {
last_title_update = push;
std::chrono::duration<double, std::milli> clear_ms = clear - start,
draw_ms = draw - clear,
push_ms = push - draw;
char title[128];
sprintf(title, "%s %.2g + %.2g + %.2g = %.2g ms per frame",
slide(nullptr),
clear_ms.count(), draw_ms.count(), push_ms.count(),
clear_ms.count() + draw_ms.count() + push_ms.count());
SDL_SetWindowTitle(window.get(), title);
}
}
SDL_Quit();
return 0;
}