From 8dd7c9b924938c45af538775a6aff3ddd4a145a9 Mon Sep 17 00:00:00 2001 From: rogerman Date: Wed, 22 Feb 2017 17:07:11 -0800 Subject: [PATCH] GPU: No more need for clients to specify whether to apply the master brightness on a per-scanline basis or on a per-framebuffer basis; GPUSubsystem can now automatically switch between applying per-scanline or applying per-framebuffer. --- desmume/src/GPU.cpp | 67 +++++++++++++++++++++------------------------ desmume/src/GPU.h | 20 ++------------ 2 files changed, 34 insertions(+), 53 deletions(-) diff --git a/desmume/src/GPU.cpp b/desmume/src/GPU.cpp index a51e3bcb8..5cdb0a0e5 100644 --- a/desmume/src/GPU.cpp +++ b/desmume/src/GPU.cpp @@ -353,8 +353,6 @@ GPUEngineBase::GPUEngineBase() _enableColorEffectCustom[GPULayerID_BG2] = NULL; _enableColorEffectCustom[GPULayerID_BG3] = NULL; _enableColorEffectCustom[GPULayerID_OBJ] = NULL; - - _willApplyMasterBrightnessPerScanline = true; } GPUEngineBase::~GPUEngineBase() @@ -4014,54 +4012,52 @@ void GPUEngineBase::_RenderLine_LayerOBJ(GPUEngineCompositorInfo &compInfo, item } } -bool GPUEngineBase::WillApplyMasterBrightnessPerScanline() const -{ - return this->_willApplyMasterBrightnessPerScanline; -} - -void GPUEngineBase::SetWillApplyMasterBrightnessPerScanline(bool willApply) -{ - this->_willApplyMasterBrightnessPerScanline = willApply; -} - void GPUEngineBase::UpdateMasterBrightnessDisplayInfo(NDSDisplayInfo &mutableInfo) { - if (this->_willApplyMasterBrightnessPerScanline) + const GPUEngineCompositorInfo &compInfoZero = this->_currentCompositorInfo[0]; + bool needsApply = false; + bool processPerScanline = false; + + for (size_t line = 0; line < GPU_FRAMEBUFFER_NATIVE_HEIGHT; line++) { - bool needsApply = false; + const GPUEngineCompositorInfo &compInfo = this->_currentCompositorInfo[line]; - for (size_t line = 0; line < GPU_FRAMEBUFFER_NATIVE_HEIGHT; line++) + if ( !needsApply && + (compInfo.renderState.masterBrightnessIntensity != 0) && + ((compInfo.renderState.masterBrightnessMode == GPUMasterBrightMode_Up) || (compInfo.renderState.masterBrightnessMode == GPUMasterBrightMode_Down)) ) { - const GPUEngineCompositorInfo &compInfo = this->_currentCompositorInfo[line]; - - if ( (compInfo.renderState.masterBrightnessIntensity != 0) && ((compInfo.renderState.masterBrightnessMode == GPUMasterBrightMode_Up) || (compInfo.renderState.masterBrightnessMode == GPUMasterBrightMode_Down)) ) - { - needsApply = true; - } - - mutableInfo.masterBrightnessMode[this->_targetDisplayID][line] = compInfo.renderState.masterBrightnessMode; - mutableInfo.masterBrightnessIntensity[this->_targetDisplayID][line] = compInfo.renderState.masterBrightnessIntensity; + needsApply = true; } - mutableInfo.needApplyMasterBrightness[this->_targetDisplayID] = needsApply; - } - else - { - const GPUEngineCompositorInfo &compInfo = this->_currentCompositorInfo[0]; - mutableInfo.needApplyMasterBrightness[this->_targetDisplayID] = (compInfo.renderState.masterBrightnessIntensity != 0) && ((compInfo.renderState.masterBrightnessMode == GPUMasterBrightMode_Up) || (compInfo.renderState.masterBrightnessMode == GPUMasterBrightMode_Down)); + mutableInfo.masterBrightnessMode[this->_targetDisplayID][line] = compInfo.renderState.masterBrightnessMode; + mutableInfo.masterBrightnessIntensity[this->_targetDisplayID][line] = compInfo.renderState.masterBrightnessIntensity; - for (size_t line = 0; line < GPU_FRAMEBUFFER_NATIVE_HEIGHT; line++) + if ( !processPerScanline && + ((compInfo.renderState.masterBrightnessMode != compInfoZero.renderState.masterBrightnessMode) || + (compInfo.renderState.masterBrightnessIntensity != compInfoZero.renderState.masterBrightnessIntensity)) ) { - mutableInfo.masterBrightnessMode[this->_targetDisplayID][line] = compInfo.renderState.masterBrightnessMode; - mutableInfo.masterBrightnessIntensity[this->_targetDisplayID][line] = compInfo.renderState.masterBrightnessIntensity; + processPerScanline = true; } } + + mutableInfo.masterBrightnessDiffersPerLine[this->_targetDisplayID] = processPerScanline; + mutableInfo.needApplyMasterBrightness[this->_targetDisplayID] = needsApply; } template void GPUEngineBase::ApplyMasterBrightness(const NDSDisplayInfo &displayInfo) { - if (this->_willApplyMasterBrightnessPerScanline) + // Most games maintain the exact same master brightness values for all 192 lines, so we + // can easily apply the master brightness to the entire framebuffer at once, which is + // faster than applying it per scanline. + // + // However, some games need to have the master brightness values applied on a per-scanline + // basis since they can differ for each scanline. For example, Mega Man Zero Collection + // purposely changes the master brightness intensity to 31 on line 0, 0 on line 16, and + // then back to 31 on line 176. Since the MMZC are originally GBA games, the master + // brightness intensity changes are done to disable the unused scanlines on the NDS. + + if (displayInfo.masterBrightnessDiffersPerLine[this->_targetDisplayID]) { for (size_t line = 0; line < GPU_FRAMEBUFFER_NATIVE_HEIGHT; line++) { @@ -7428,8 +7424,7 @@ void GPUSubsystem::RenderLine(const size_t l) this->_engineSub->UpdateRenderStates(l); const bool isDisplayCaptureNeeded = this->_engineMain->WillDisplayCapture(l); - const bool isFramebufferRenderNeeded[2] = { CommonSettings.showGpu.main && ( !this->_engineMain->IsMasterBrightFullIntensityAtLineZero() || this->_engineMain->WillApplyMasterBrightnessPerScanline() ), - CommonSettings.showGpu.sub && ( !this->_engineSub->IsMasterBrightFullIntensityAtLineZero() || this->_engineSub->WillApplyMasterBrightnessPerScanline() ) }; + const bool isFramebufferRenderNeeded[2] = { CommonSettings.showGpu.main, CommonSettings.showGpu.sub }; if (l == 0) { diff --git a/desmume/src/GPU.h b/desmume/src/GPU.h index 573822a4c..3e2adf272 100644 --- a/desmume/src/GPU.h +++ b/desmume/src/GPU.h @@ -1098,6 +1098,9 @@ typedef struct // true - The display performed a custom-sized render. // false - The display performed a native-sized render. + bool masterBrightnessDiffersPerLine[2]; // Reports if the master brightness values may differ per scanline. If true, then it will + // need to be applied on a per-scanline basis. Otherwise, it can be applied to the entire + // framebuffer. For most NDS games, this field will be false. u8 masterBrightnessMode[2][GPU_FRAMEBUFFER_NATIVE_HEIGHT]; // The master brightness mode of each display line. u8 masterBrightnessIntensity[2][GPU_FRAMEBUFFER_NATIVE_HEIGHT]; // The master brightness intensity of each display line. @@ -1328,7 +1331,6 @@ protected: CACHE_ALIGN u8 _h_win[2][GPU_FRAMEBUFFER_NATIVE_WIDTH]; NDSDisplayID _targetDisplayID; - bool _willApplyMasterBrightnessPerScanline; CACHE_ALIGN FragmentColor _internalRenderLineTargetNative[GPU_FRAMEBUFFER_NATIVE_WIDTH]; CACHE_ALIGN u8 _renderLineLayerIDNative[GPU_FRAMEBUFFER_NATIVE_WIDTH]; @@ -1481,22 +1483,6 @@ public: bool GetLayerEnableState(const size_t layerIndex); void SetLayerEnableState(const size_t layerIndex, bool theState); - // By default, the master brightness will be applied on a per-scanline basis. This is - // necessary for certain games, such as Mega Man Zero Collection, that purposely change - // the the master brightness in the middle of the frame. With this particular game, it - // will change the master brightness to 31 on line 0, 0 on line 16, and back to 31 on - // line 176. Originally being a GBA game, this is done to disable unused scanlines on - // the NDS. - // - // However, applying the master brightness per scanline is slower than applying it on - // the entire framebuffer. To apply the master brightness to the entire framebuffer - // instead, call SetWillApplyMasterBrightnessPerScanline() and pass a value of "false". - // This should be safe for the vast majority of games, since games usually won't change - // the master brightness mid-frame, and even those that do will look fine when using - // the master brightness value from line 0. - bool WillApplyMasterBrightnessPerScanline() const; - void SetWillApplyMasterBrightnessPerScanline(bool willApply); - void UpdateMasterBrightnessDisplayInfo(NDSDisplayInfo &mutableInfo); template void ApplyMasterBrightness(const NDSDisplayInfo &displayInfo); template void ApplyMasterBrightness(void *dst, const size_t pixCount, const GPUMasterBrightMode mode, const u8 intensity);