mirror of https://github.com/mgba-emu/mgba.git
GBA Video: GL screenshots
This commit is contained in:
parent
ac7ae74822
commit
8a26a7977c
|
@ -32,6 +32,7 @@ enum mVideoLoggerEvent {
|
|||
LOGGER_EVENT_INIT,
|
||||
LOGGER_EVENT_DEINIT,
|
||||
LOGGER_EVENT_RESET,
|
||||
LOGGER_EVENT_GET_PIXELS,
|
||||
};
|
||||
|
||||
struct mVideoLoggerDirtyInfo {
|
||||
|
@ -73,6 +74,9 @@ struct mVideoLogger {
|
|||
uint16_t* vram;
|
||||
uint16_t* oam;
|
||||
uint16_t* palette;
|
||||
|
||||
const void* pixelBuffer;
|
||||
size_t pixelStride;
|
||||
};
|
||||
|
||||
void mVideoLoggerRendererCreate(struct mVideoLogger* logger, bool readonly);
|
||||
|
|
|
@ -121,6 +121,8 @@ struct GBAVideoGLShader {
|
|||
struct GBAVideoGLRenderer {
|
||||
struct GBAVideoRenderer d;
|
||||
|
||||
uint32_t* temporaryBuffer;
|
||||
|
||||
struct GBAVideoGLBackground bg[4];
|
||||
|
||||
int oamMax;
|
||||
|
|
|
@ -283,11 +283,13 @@ static void GBVideoProxyRendererGetPixels(struct GBVideoRenderer* renderer, size
|
|||
proxyRenderer->logger->lock(proxyRenderer->logger);
|
||||
// Insert an extra item into the queue to make sure it gets flushed
|
||||
mVideoLoggerRendererFlush(proxyRenderer->logger);
|
||||
proxyRenderer->logger->wait(proxyRenderer->logger);
|
||||
}
|
||||
proxyRenderer->backend->getPixels(proxyRenderer->backend, stride, pixels);
|
||||
if (proxyRenderer->logger->block && proxyRenderer->logger->wait) {
|
||||
proxyRenderer->logger->postEvent(proxyRenderer->logger, LOGGER_EVENT_GET_PIXELS);
|
||||
mVideoLoggerRendererFlush(proxyRenderer->logger);
|
||||
proxyRenderer->logger->unlock(proxyRenderer->logger);
|
||||
*pixels = proxyRenderer->logger->pixelBuffer;
|
||||
*stride = proxyRenderer->logger->pixelStride;
|
||||
} else {
|
||||
proxyRenderer->backend->getPixels(proxyRenderer->backend, stride, pixels);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -310,13 +310,13 @@ static void _GBACoreSetVideoGLTex(struct mCore* core, unsigned texid) {
|
|||
}
|
||||
|
||||
static void _GBACoreGetPixels(struct mCore* core, const void** buffer, size_t* stride) {
|
||||
struct GBACore* gbacore = (struct GBACore*) core;
|
||||
gbacore->renderer.d.getPixels(&gbacore->renderer.d, stride, buffer);
|
||||
struct GBA* gba = core->board;
|
||||
gba->video.renderer->getPixels(gba->video.renderer, stride, buffer);
|
||||
}
|
||||
|
||||
static void _GBACorePutPixels(struct mCore* core, const void* buffer, size_t stride) {
|
||||
struct GBACore* gbacore = (struct GBACore*) core;
|
||||
gbacore->renderer.d.putPixels(&gbacore->renderer.d, stride, buffer);
|
||||
struct GBA* gba = core->board;
|
||||
gba->video.renderer->putPixels(gba->video.renderer, stride, buffer);
|
||||
}
|
||||
|
||||
static struct blip_t* _GBACoreGetAudioChannel(struct mCore* core, int ch) {
|
||||
|
|
|
@ -152,6 +152,9 @@ static void _handleEvent(struct mVideoLogger* logger, enum mVideoLoggerEvent eve
|
|||
case LOGGER_EVENT_RESET:
|
||||
proxyRenderer->backend->reset(proxyRenderer->backend);
|
||||
break;
|
||||
case LOGGER_EVENT_GET_PIXELS:
|
||||
proxyRenderer->backend->getPixels(proxyRenderer->backend, &logger->pixelStride, &logger->pixelBuffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -305,10 +308,13 @@ static void GBAVideoProxyRendererGetPixels(struct GBAVideoRenderer* renderer, si
|
|||
proxyRenderer->logger->lock(proxyRenderer->logger);
|
||||
// Insert an extra item into the queue to make sure it gets flushed
|
||||
mVideoLoggerRendererFlush(proxyRenderer->logger);
|
||||
}
|
||||
proxyRenderer->backend->getPixels(proxyRenderer->backend, stride, pixels);
|
||||
if (proxyRenderer->logger->block && proxyRenderer->logger->wait) {
|
||||
proxyRenderer->logger->postEvent(proxyRenderer->logger, LOGGER_EVENT_GET_PIXELS);
|
||||
mVideoLoggerRendererFlush(proxyRenderer->logger);
|
||||
proxyRenderer->logger->unlock(proxyRenderer->logger);
|
||||
*pixels = proxyRenderer->logger->pixelBuffer;
|
||||
*stride = proxyRenderer->logger->pixelStride;
|
||||
} else {
|
||||
proxyRenderer->backend->getPixels(proxyRenderer->backend, stride, pixels);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <mgba/internal/arm/macros.h>
|
||||
#include <mgba/internal/gba/io.h>
|
||||
#include <mgba/internal/gba/renderers/cache-set.h>
|
||||
#include <mgba-util/memory.h>
|
||||
|
||||
static void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer);
|
||||
static void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer);
|
||||
|
@ -435,6 +436,8 @@ static void _initFramebufferTexture(GLuint tex, GLenum format, GLenum attachment
|
|||
|
||||
void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) {
|
||||
struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer;
|
||||
glRenderer->temporaryBuffer = NULL;
|
||||
|
||||
glGenFramebuffers(GBA_GL_FBO_MAX, glRenderer->fbo);
|
||||
glGenTextures(GBA_GL_TEX_MAX, glRenderer->layers);
|
||||
|
||||
|
@ -552,6 +555,9 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) {
|
|||
|
||||
void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer) {
|
||||
struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer;
|
||||
if (glRenderer->temporaryBuffer) {
|
||||
mappedMemoryFree(glRenderer->temporaryBuffer, GBA_VIDEO_HORIZONTAL_PIXELS * GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale * glRenderer->scale);
|
||||
}
|
||||
glDeleteFramebuffers(GBA_GL_FBO_MAX, glRenderer->fbo);
|
||||
glDeleteTextures(GBA_GL_TEX_MAX, glRenderer->layers);
|
||||
glDeleteTextures(1, &glRenderer->paletteTex);
|
||||
|
@ -928,7 +934,16 @@ void GBAVideoGLRendererFinishFrame(struct GBAVideoRenderer* renderer) {
|
|||
}
|
||||
|
||||
void GBAVideoGLRendererGetPixels(struct GBAVideoRenderer* renderer, size_t* stride, const void** pixels) {
|
||||
|
||||
struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer;
|
||||
*stride = GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale;
|
||||
if (!glRenderer->temporaryBuffer) {
|
||||
glRenderer->temporaryBuffer = anonymousMemoryMap(GBA_VIDEO_HORIZONTAL_PIXELS * GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale * glRenderer->scale * BYTES_PER_PIXEL);
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_OUTPUT]);
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glReadPixels(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, GL_RGBA, GL_UNSIGNED_BYTE, (void*) glRenderer->temporaryBuffer);
|
||||
*pixels = glRenderer->temporaryBuffer;
|
||||
}
|
||||
|
||||
void GBAVideoGLRendererPutPixels(struct GBAVideoRenderer* renderer, size_t stride, const void* pixels) {
|
||||
|
|
Loading…
Reference in New Issue