diff --git a/include/mgba/core/core.h b/include/mgba/core/core.h index fe08ae0cd..124b02411 100644 --- a/include/mgba/core/core.h +++ b/include/mgba/core/core.h @@ -70,6 +70,7 @@ struct mCore { void (*desiredVideoDimensions)(struct mCore*, unsigned* width, unsigned* height); void (*setVideoBuffer)(struct mCore*, color_t* buffer, size_t stride); + void (*setVideoGLTex)(struct mCore*, unsigned texid); void (*getPixels)(struct mCore*, const void** buffer, size_t* stride); void (*putPixels)(struct mCore*, const void* buffer, size_t stride); diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index 402b81afe..4467bee9c 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -62,10 +62,9 @@ struct GBAVideoGLRenderer { struct GBAVideoGLBackground bg[4]; GLuint fbo[2]; - GLuint layers[4]; + GLuint layers[3]; - color_t* outputBuffer; - int outputBufferStride; + GLuint outputTex; GLuint paletteTex; bool paletteDirty; diff --git a/src/gb/core.c b/src/gb/core.c index 99f11029d..20e383393 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -233,6 +233,11 @@ static void _GBCoreSetVideoBuffer(struct mCore* core, color_t* buffer, size_t st gbcore->renderer.outputBufferStride = stride; } +static void _GBCoreSetVideoGLTex(struct mCore* core, unsigned texid) { + UNUSED(core); + UNUSED(texid); +} + static void _GBCoreGetPixels(struct mCore* core, const void** buffer, size_t* stride) { struct GBCore* gbcore = (struct GBCore*) core; gbcore->renderer.d.getPixels(&gbcore->renderer.d, stride, buffer); @@ -887,6 +892,7 @@ struct mCore* GBCoreCreate(void) { core->loadConfig = _GBCoreLoadConfig; core->desiredVideoDimensions = _GBCoreDesiredVideoDimensions; core->setVideoBuffer = _GBCoreSetVideoBuffer; + core->setVideoGLTex = _GBCoreSetVideoGLTex; core->getPixels = _GBCoreGetPixels; core->putPixels = _GBCorePutPixels; core->getAudioChannel = _GBCoreGetAudioChannel; diff --git a/src/gba/core.c b/src/gba/core.c index 3feb64176..2c6207d8b 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -168,9 +168,11 @@ static bool _GBACoreInit(struct mCore* core) { gba->rtcSource = &core->rtc.d; GBAVideoSoftwareRendererCreate(&gbacore->renderer); - GBAVideoGLRendererCreate(&gbacore->glRenderer); gbacore->renderer.outputBuffer = NULL; + GBAVideoGLRendererCreate(&gbacore->glRenderer); + gbacore->glRenderer.outputTex = -1; + #ifndef DISABLE_THREADING mVideoThreadProxyCreate(&gbacore->threadProxy); #endif @@ -274,11 +276,14 @@ static void _GBACoreSetVideoBuffer(struct mCore* core, color_t* buffer, size_t s struct GBACore* gbacore = (struct GBACore*) core; gbacore->renderer.outputBuffer = buffer; gbacore->renderer.outputBufferStride = stride; - gbacore->glRenderer.outputBuffer = buffer; - gbacore->glRenderer.outputBufferStride = stride; memset(gbacore->renderer.scanlineDirty, 0xFFFFFFFF, sizeof(gbacore->renderer.scanlineDirty)); } +static void _GBACoreSetVideoGLTex(struct mCore* core, unsigned texid) { + struct GBACore* gbacore = (struct GBACore*) core; + gbacore->glRenderer.outputTex = 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); @@ -401,9 +406,16 @@ static void _GBACoreChecksum(const struct mCore* core, void* data, enum mCoreChe static void _GBACoreReset(struct mCore* core) { struct GBACore* gbacore = (struct GBACore*) core; struct GBA* gba = (struct GBA*) core->board; - if (gbacore->renderer.outputBuffer) { - struct GBAVideoRenderer* renderer = &gbacore->renderer.d; + if (gbacore->renderer.outputBuffer || gbacore->glRenderer.outputTex != (unsigned) -1) { + struct GBAVideoRenderer* renderer; + if (gbacore->renderer.outputBuffer) { + renderer = &gbacore->renderer.d; + } int fakeBool; + if (gbacore->glRenderer.outputTex != (unsigned) -1 && mCoreConfigGetIntValue(&core->config, "hwaccelVideo", &fakeBool) && fakeBool) { + renderer = &gbacore->glRenderer.d; + mCoreConfigGetIntValue(&core->config, "videoScale", &gbacore->glRenderer.scale); + } #ifndef DISABLE_THREADING if (mCoreConfigGetIntValue(&core->config, "threadedVideo", &fakeBool) && fakeBool) { if (!core->videoLogger) { @@ -411,10 +423,6 @@ static void _GBACoreReset(struct mCore* core) { } } #endif - if (mCoreConfigGetIntValue(&core->config, "hwaccelVideo", &fakeBool) && fakeBool) { - renderer = &gbacore->glRenderer.d; - mCoreConfigGetIntValue(&core->config, "videoScale", &gbacore->glRenderer.scale); - } if (core->videoLogger) { gbacore->proxyRenderer.logger = core->videoLogger; GBAVideoProxyRendererCreate(&gbacore->proxyRenderer, renderer); @@ -951,6 +959,7 @@ struct mCore* GBACoreCreate(void) { core->loadConfig = _GBACoreLoadConfig; core->desiredVideoDimensions = _GBACoreDesiredVideoDimensions; core->setVideoBuffer = _GBACoreSetVideoBuffer; + core->setVideoGLTex = _GBACoreSetVideoGLTex; core->getPixels = _GBACoreGetPixels; core->putPixels = _GBACorePutPixels; core->getAudioChannel = _GBACoreGetAudioChannel; diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 36e2602f8..e662a2779 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -229,7 +229,7 @@ void _compileBackground(struct GBAVideoGLRenderer* glRenderer, GLuint program, c void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; glGenFramebuffers(2, glRenderer->fbo); - glGenTextures(4, glRenderer->layers); + glGenTextures(3, glRenderer->layers); glGenTextures(1, &glRenderer->paletteTex); glBindTexture(GL_TEXTURE_2D, glRenderer->paletteTex); @@ -248,21 +248,21 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[1]); - glBindTexture(GL_TEXTURE_2D, glRenderer->layers[2]); + glBindTexture(GL_TEXTURE_2D, glRenderer->outputTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glRenderer->layers[2], 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glRenderer->outputTex, 0); - glBindTexture(GL_TEXTURE_2D, glRenderer->layers[3]); + glBindTexture(GL_TEXTURE_2D, glRenderer->layers[2]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, glRenderer->layers[3], 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, glRenderer->layers[2], 0); glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -331,7 +331,7 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; glDeleteFramebuffers(2, glRenderer->fbo); - glDeleteTextures(4, glRenderer->layers); + glDeleteTextures(3, glRenderer->layers); glDeleteTextures(1, &glRenderer->paletteTex); glDeleteTextures(1, &glRenderer->vramTex); glDeleteTextures(1, &glRenderer->oamTex); @@ -652,12 +652,8 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { } void GBAVideoGLRendererFinishFrame(struct GBAVideoRenderer* renderer) { - struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; - glFinish(); - glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[1]); - glPixelStorei(GL_PACK_ROW_LENGTH, glRenderer->outputBufferStride); - glReadPixels(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, GL_RGBA, GL_UNSIGNED_BYTE, glRenderer->outputBuffer); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + UNUSED(renderer); + glFlush(); } void GBAVideoGLRendererGetPixels(struct GBAVideoRenderer* renderer, size_t* stride, const void** pixels) {