all repos — mgba @ 36daee6de33f8b404d6238d285a4c0d20680a35c

mGBA Game Boy Advance Emulator

Merge commit 'a21d773ae8dd52b6e2e1e7b34f8bca4ec3d5b457'
Jeffrey Pfau jeffrey@endrift.com
Sat, 06 Jun 2015 23:10:21 -0700
commit

36daee6de33f8b404d6238d285a4c0d20680a35c

parent

12505766e1ab83954ab216a5828cd064834056e8

A src/platform/opengl/gl.c

@@ -0,0 +1,121 @@

+/* Copyright (c) 2013-2015 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "gl.h" + +#include "gba/video.h" + +static const GLint _glVertices[] = { + 0, 0, + 256, 0, + 256, 256, + 0, 256 +}; + +static const GLint _glTexCoords[] = { + 0, 0, + 1, 0, + 1, 1, + 0, 1 +}; + +static void GBAGLContextInit(struct VideoBackend* v, WHandle handle) { + UNUSED(handle); + struct GBAGLContext* context = (struct GBAGLContext*) v; + glGenTextures(1, &context->tex); + glBindTexture(GL_TEXTURE_2D, context->tex); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); +#ifndef _WIN32 + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +#endif + +#ifdef COLOR_16_BIT +#ifdef COLOR_5_6_5 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0); +#else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0); +#endif +#else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); +#endif +} + +static void GBAGLContextDeinit(struct VideoBackend* v) { + struct GBAGLContext* context = (struct GBAGLContext*) v; + glDeleteTextures(1, &context->tex); +} + +static void GBAGLContextResized(struct VideoBackend* v, int w, int h) { + int drawW = w; + int drawH = h; + if (v->lockAspectRatio) { + if (w * 2 > h * 3) { + drawW = h * 3 / 2; + } else if (w * 2 < h * 3) { + drawH = w * 2 / 3; + } + } + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + glViewport((w - drawW) / 2, (h - drawH) / 2, drawW, drawH); +} + +static void GBAGLContextClear(struct VideoBackend* v) { + UNUSED(v); + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); +} + +void GBAGLContextDrawFrame(struct VideoBackend* v) { + struct GBAGLContext* context = (struct GBAGLContext*) v; + glEnable(GL_TEXTURE_2D); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_INT, 0, _glVertices); + glTexCoordPointer(2, GL_INT, 0, _glTexCoords); + glMatrixMode (GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, 0, 0, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glBindTexture(GL_TEXTURE_2D, context->tex); + if (v->filter) { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } else { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); +} + +void GBAGLContextPostFrame(struct VideoBackend* v, const void* frame) { + struct GBAGLContext* context = (struct GBAGLContext*) v; + glBindTexture(GL_TEXTURE_2D, context->tex); +#ifdef COLOR_16_BIT +#ifdef COLOR_5_6_5 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, frame); +#else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, frame); +#endif +#else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, frame); +#endif +} + +void GBAGLContextCreate(struct GBAGLContext* context) { + context->d.init = GBAGLContextInit; + context->d.deinit = GBAGLContextDeinit; + context->d.resized = GBAGLContextResized; + context->d.swap = 0; + context->d.clear = GBAGLContextClear; + context->d.postFrame = GBAGLContextPostFrame; + context->d.drawFrame = GBAGLContextDrawFrame; + context->d.setMessage = 0; + context->d.clearMessage = 0; +}
A src/platform/opengl/gl.h

@@ -0,0 +1,25 @@

+/* Copyright (c) 2013-2015 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef GL_H +#define GL_H + +#ifdef __APPLE__ +#include <OpenGL/gl.h> +#else +#include <GL/gl.h> +#endif + +#include "platform/video-backend.h" + +struct GBAGLContext { + struct VideoBackend d; + + GLuint tex; +}; + +void GBAGLContextCreate(struct GBAGLContext*); + +#endif
M src/platform/qt/CMakeLists.txtsrc/platform/qt/CMakeLists.txt

@@ -39,6 +39,8 @@ set(BUILD_QT OFF PARENT_SCOPE)

return() endif() +list(APPEND PLATFORM_SRC ${PLATFORM_SRC} ${CMAKE_SOURCE_DIR}/src/platform/opengl/gl.c) + get_target_property(QT_TYPE Qt5::Core TYPE) if(QT_TYPE STREQUAL STATIC_LIBRARY) set(QT_STATIC ON)
M src/platform/qt/DisplayGL.cppsrc/platform/qt/DisplayGL.cpp

@@ -14,20 +14,6 @@ }

using namespace QGBA; -static const GLint _glVertices[] = { - 0, 0, - 256, 0, - 256, 256, - 0, 256 -}; - -static const GLint _glTexCoords[] = { - 0, 0, - 1, 0, - 1, 1, - 0, 1 -}; - DisplayGL::DisplayGL(const QGLFormat& format, QWidget* parent) : Display(parent) , m_gl(new EmptyGLWidget(format, this))

@@ -154,10 +140,16 @@ PainterGL::PainterGL(QGLWidget* parent)

: m_gl(parent) , m_drawTimer(nullptr) , m_messageTimer(this) - , m_lockAspectRatio(false) - , m_filter(false) , m_context(nullptr) { + GBAGLContextCreate(&m_backend); + m_backend.d.swap = [](VideoBackend* v) { + PainterGL* painter = static_cast<PainterGL*>(v->user); + painter->m_gl->swapBuffers(); + }; + m_backend.d.user = this; + m_backend.d.filter = false; + m_backend.d.lockAspectRatio = false; m_messageFont.setFamily("Source Code Pro"); m_messageFont.setStyleHint(QFont::Monospace); m_messageFont.setPixelSize(13);

@@ -174,16 +166,7 @@ }

void PainterGL::setBacking(const uint32_t* backing) { m_gl->makeCurrent(); - glBindTexture(GL_TEXTURE_2D, m_tex); -#ifdef COLOR_16_BIT -#ifdef COLOR_5_6_5 - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, backing); -#else - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, backing); -#endif -#else - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, backing); -#endif + m_backend.d.postFrame(&m_backend.d, backing); m_gl->doneCurrent(); }

@@ -193,43 +176,31 @@ int w = m_size.width();

int h = m_size.height(); int drawW = w; int drawH = h; - if (m_lockAspectRatio) { + if (m_backend.d.lockAspectRatio) { if (w * 2 > h * 3) { drawW = h * 3 / 2; } else if (w * 2 < h * 3) { drawH = w * 2 / 3; } } - m_viewport = QRect((w - drawW) / 2, (h - drawH) / 2, drawW, drawH); - m_painter.begin(m_gl->context()->device()); m_world.reset(); - m_world.translate(m_viewport.x(), m_viewport.y()); + m_world.translate((w - drawW) / 2, (h - drawH) / 2); m_world.scale(qreal(drawW) / VIDEO_HORIZONTAL_PIXELS, qreal(drawH) / VIDEO_VERTICAL_PIXELS); - m_painter.setWorldTransform(m_world); - m_painter.setFont(m_messageFont); m_message.prepare(m_world, m_messageFont); - m_painter.end(); if (m_drawTimer) { forceDraw(); } } void PainterGL::lockAspectRatio(bool lock) { - m_lockAspectRatio = lock; + m_backend.d.lockAspectRatio = lock; if (m_drawTimer) { forceDraw(); } } void PainterGL::filter(bool filter) { - m_filter = filter; - m_gl->makeCurrent(); - if (m_filter) { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } else { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - m_gl->doneCurrent(); + m_backend.d.filter = filter; if (m_drawTimer) { forceDraw(); }

@@ -237,24 +208,7 @@ }

void PainterGL::start() { m_gl->makeCurrent(); - glEnable(GL_TEXTURE_2D); - glGenTextures(1, &m_tex); - glBindTexture(GL_TEXTURE_2D, m_tex); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - if (m_filter) { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } else { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, GL_INT, 0, _glVertices); - glTexCoordPointer(2, GL_INT, 0, _glTexCoords); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT); + m_backend.d.init(&m_backend.d, (void*) m_gl->winId()); m_gl->doneCurrent(); m_drawTimer = new QTimer;

@@ -267,19 +221,17 @@

void PainterGL::draw() { GBASyncWaitFrameStart(&m_context->sync, m_context->frameskip); m_painter.begin(m_gl->context()->device()); - m_painter.setWorldTransform(m_world); performDraw(); m_painter.end(); GBASyncWaitFrameEnd(&m_context->sync); - m_gl->swapBuffers(); + m_backend.d.swap(&m_backend.d); } void PainterGL::forceDraw() { m_painter.begin(m_gl->context()->device()); - m_painter.setWorldTransform(m_world); performDraw(); m_painter.end(); - m_gl->swapBuffers(); + m_backend.d.swap(&m_backend.d); } void PainterGL::stop() {

@@ -287,10 +239,9 @@ m_drawTimer->stop();

delete m_drawTimer; m_drawTimer = nullptr; m_gl->makeCurrent(); - glDeleteTextures(1, &m_tex); - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT); - m_gl->swapBuffers(); + m_backend.d.clear(&m_backend.d); + m_backend.d.swap(&m_backend.d); + m_backend.d.deinit(&m_backend.d); m_gl->doneCurrent(); m_gl->context()->moveToThread(m_gl->thread()); moveToThread(m_gl->thread());

@@ -309,21 +260,11 @@ }

void PainterGL::performDraw() { m_painter.beginNativePainting(); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, 0, 0, 1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glViewport(0, 0, m_size.width() * m_gl->devicePixelRatio(), m_size.height() * m_gl->devicePixelRatio()); - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT); - QRect viewport(m_viewport.topLeft() * m_gl->devicePixelRatio(), m_viewport.size() * m_gl->devicePixelRatio()); - glViewport(viewport.x(), viewport.y(), viewport.width(), viewport.height()); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - if (m_context->sync.videoFrameWait) { - glFlush(); - } + float r = m_gl->devicePixelRatio(); + m_backend.d.resized(&m_backend.d, m_size.width() * r, m_size.height() * r); + m_backend.d.drawFrame(&m_backend.d); m_painter.endNativePainting(); + m_painter.setWorldTransform(m_world); m_painter.setRenderHint(QPainter::Antialiasing); m_painter.setFont(m_messageFont); m_painter.setPen(Qt::black);
M src/platform/qt/DisplayGL.hsrc/platform/qt/DisplayGL.h

@@ -13,6 +13,10 @@ #include <QStaticText>

#include <QThread> #include <QTimer> +extern "C" { +#include "platform/opengl/gl.h" +} + struct GBAThread; namespace QGBA {

@@ -94,11 +98,8 @@ QThread* m_thread;

QTimer* m_drawTimer; QTimer m_messageTimer; GBAThread* m_context; - GLuint m_tex; + GBAGLContext m_backend; QSize m_size; - bool m_lockAspectRatio; - bool m_filter; - QRect m_viewport; QTransform m_world; QFont m_messageFont; };
M src/platform/sdl/CMakeLists.txtsrc/platform/sdl/CMakeLists.txt

@@ -67,6 +67,7 @@ else()

list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/sw-sdl.c) if(BUILD_GL) list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/gl-sdl.c) + list(APPEND PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/opengl/gl.c) add_definitions(-DBUILD_GL) find_package(OpenGL REQUIRED) include_directories(${OPENGL_INCLUDE_DIR})
M src/platform/sdl/gl-sdl.csrc/platform/sdl/gl-sdl.c

@@ -6,47 +6,22 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "main.h" #include "gba/supervisor/thread.h" - -#ifdef __APPLE__ -#include <OpenGL/gl.h> -#else -#include <GL/gl.h> -#endif - -#ifdef BUILD_GL -static const GLint _glVertices[] = { - 0, 0, - 256, 0, - 256, 256, - 0, 256 -}; +#include "platform/opengl/gl.h" -static const GLint _glTexCoords[] = { - 0, 0, - 1, 0, - 1, 1, - 0, 1 -}; -#endif - -static void _doViewport(int w, int h, struct SDLSoftwareRenderer* renderer) { - int drawW = w; - int drawH = h; - if (renderer->lockAspectRatio) { - if (w * 2 > h * 3) { - drawW = h * 3 / 2; - } else if (w * 2 < h * 3) { - drawH = w * 2 / 3; - } - } - glViewport((w - drawW) / 2, (h - drawH) / 2, drawW, drawH); - glClear(GL_COLOR_BUFFER_BIT); +static void _sdlSwap(struct VideoBackend* context) { + struct SDLSoftwareRenderer* renderer = (struct SDLSoftwareRenderer*) context->user; #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_GL_SwapWindow(renderer->window); #else SDL_GL_SwapBuffers(); #endif - glClear(GL_COLOR_BUFFER_BIT); +} + +static void _doViewport(int w, int h, struct VideoBackend* v) { + v->resized(v, w, h); + v->clear(v); + v->swap(v); + v->clear(v); } static bool GBASDLGLInit(struct SDLSoftwareRenderer* renderer);

@@ -89,48 +64,24 @@ SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 32, SDL_OPENGL);

#endif #endif - renderer->d.outputBuffer = malloc(VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL); - renderer->d.outputBufferStride = VIDEO_HORIZONTAL_PIXELS; - glGenTextures(1, &renderer->tex); - glBindTexture(GL_TEXTURE_2D, renderer->tex); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - if (renderer->filter) { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } else { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } -#ifndef _WIN32 - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); -#endif + renderer->d.outputBuffer = malloc(256 * 256 * BYTES_PER_PIXEL); + renderer->d.outputBufferStride = 256; -#ifdef COLOR_16_BIT -#ifdef COLOR_5_6_5 - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0); -#else - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0); -#endif -#else - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); -#endif + GBAGLContextCreate(&renderer->gl); + renderer->gl.d.user = renderer; + renderer->gl.d.lockAspectRatio = renderer->lockAspectRatio; + renderer->gl.d.filter = renderer->filter; + renderer->gl.d.swap = _sdlSwap; + renderer->gl.d.init(&renderer->gl.d, 0); - _doViewport(renderer->viewportWidth, renderer->viewportHeight, renderer); + _doViewport(renderer->viewportWidth, renderer->viewportHeight, &renderer->gl.d); return true; } void GBASDLGLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer) { SDL_Event event; + struct VideoBackend* v = &renderer->gl.d; - glEnable(GL_TEXTURE_2D); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, GL_INT, 0, _glVertices); - glTexCoordPointer(2, GL_INT, 0, _glTexCoords); - glMatrixMode (GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, 0, 0, 1); while (context->state < THREAD_EXITING) { while (SDL_PollEvent(&event)) { GBASDLHandleEvent(context, &renderer->player, &event);

@@ -138,37 +89,24 @@ #if SDL_VERSION_ATLEAST(2, 0, 0)

// Event handling can change the size of the screen if (renderer->player.windowUpdated) { SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight); - _doViewport(renderer->viewportWidth, renderer->viewportHeight, renderer); + _doViewport(renderer->viewportWidth, renderer->viewportHeight, v); renderer->player.windowUpdated = 0; } #endif } if (GBASyncWaitFrameStart(&context->sync, context->frameskip)) { - glBindTexture(GL_TEXTURE_2D, renderer->tex); -#ifdef COLOR_16_BIT -#ifdef COLOR_5_6_5 - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, renderer->d.outputBuffer); -#else - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, renderer->d.outputBuffer); -#endif -#else - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, GL_RGBA, GL_UNSIGNED_BYTE, renderer->d.outputBuffer); -#endif - if (context->sync.videoFrameWait) { - glFlush(); - } + v->postFrame(v, renderer->d.outputBuffer); } - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + v->drawFrame(v); GBASyncWaitFrameEnd(&context->sync); -#if SDL_VERSION_ATLEAST(2, 0, 0) - SDL_GL_SwapWindow(renderer->window); -#else - SDL_GL_SwapBuffers(); -#endif + v->swap(v); } } void GBASDLGLDeinit(struct SDLSoftwareRenderer* renderer) { + if (renderer->gl.d.deinit) { + renderer->gl.d.deinit(&renderer->gl.d); + } free(renderer->d.outputBuffer); }
M src/platform/sdl/main.hsrc/platform/sdl/main.h

@@ -12,11 +12,7 @@ #include "sdl-audio.h"

#include "sdl-events.h" #ifdef BUILD_GL -#ifdef __APPLE__ -#include <OpenGL/gl.h> -#else -#include <GL/gl.h> -#endif +#include "platform/opengl/gl.h" #endif #ifdef BUILD_RASPI

@@ -59,7 +55,7 @@ bool lockAspectRatio;

bool filter; #ifdef BUILD_GL - GLuint tex; + struct GBAGLContext gl; #endif #ifdef USE_PIXMAN
A src/platform/video-backend.h

@@ -0,0 +1,34 @@

+/* Copyright (c) 2013-2015 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef VIDEO_BACKEND_H +#define VIDEO_BACKEND_H + +#include "util/common.h" + +#ifdef _WIN32 +typedef HWND WHandle; +#else +typedef void* WHandle; +#endif + +struct VideoBackend { + void (*init)(struct VideoBackend*, WHandle handle); + void (*deinit)(struct VideoBackend*); + void (*swap)(struct VideoBackend*); + void (*clear)(struct VideoBackend*); + void (*resized)(struct VideoBackend*, int w, int h); + void (*postFrame)(struct VideoBackend*, const void* frame); + void (*drawFrame)(struct VideoBackend*); + void (*setMessage)(struct VideoBackend*, const char* message); + void (*clearMessage)(struct VideoBackend*); + + void* user; + + bool filter; + bool lockAspectRatio; +}; + +#endif