diff --git a/core/renderer/backend/RenderTarget.h b/core/renderer/backend/RenderTarget.h index 7a70e57cc1f4..5b588a8c071d 100644 --- a/core/renderer/backend/RenderTarget.h +++ b/core/renderer/backend/RenderTarget.h @@ -30,43 +30,54 @@ class RenderTarget : public ax::Object void setColorAttachment(ColorAttachment attachment) { - for (auto colorItem : _color) + for (int i = 0; i < MAX_COLOR_ATTCHMENT; ++i) + { + auto colorItem = _color[i]; + if (colorItem.texture != attachment[i].texture || colorItem.level != attachment[i].level) + _dirtyFlags |= getMRTColorFlag(i); AX_SAFE_RELEASE(colorItem.texture); + } memcpy(_color, attachment, sizeof(ColorAttachment)); for (auto colorItem : _color) AX_SAFE_RETAIN(colorItem.texture); - - _dirty = true; }; - void setColorAttachment(TextureBackend* attachment, int level = 0, int index = 0) { - AX_SAFE_RELEASE(_color[index].texture); - _color[index].texture = attachment; - _color[index].level = level; - AX_SAFE_RETAIN(_color[index].texture); - _dirty = true; + void setColorAttachment(TextureBackend* attachment, int level = 0, int index = 0) + { + if (_color[index].texture != attachment || _color[index].level != level) + { + _dirtyFlags |= getMRTColorFlag(index); + AX_SAFE_RELEASE(_color[index].texture); + _color[index].texture = attachment; + _color[index].level = level; + AX_SAFE_RETAIN(_color[index].texture); + } } void setDepthAttachment(TextureBackend* attachment, int level = 0) { - AX_SAFE_RELEASE(_depth.texture); - _depth.texture = attachment; - _depth.level = level; - AX_SAFE_RETAIN(_depth.texture); - - _dirty = true; + if (_depth.texture != attachment || _depth.level != level) + { + _dirtyFlags |= TargetBufferFlags::DEPTH; + AX_SAFE_RELEASE(_depth.texture); + _depth.texture = attachment; + _depth.level = level; + AX_SAFE_RETAIN(_depth.texture); + } }; void setStencilAttachment(TextureBackend* attachment, int level = 0) { - AX_SAFE_RELEASE(_stencil.texture); - _stencil.texture = attachment; - _stencil.level = level; - AX_SAFE_RETAIN(_stencil.texture); - - _dirty = true; + if (_stencil.texture != attachment || _depth.level != level) + { + _dirtyFlags |= TargetBufferFlags::STENCIL; + AX_SAFE_RELEASE(_stencil.texture); + _stencil.texture = attachment; + _stencil.level = level; + AX_SAFE_RETAIN(_stencil.texture); + } }; - - bool isDirty() const { return _dirty; } + + bool isDirty() const { return !!_dirtyFlags; } ColorAttachment _color{}; RenderBuffer _depth{}; @@ -74,7 +85,7 @@ class RenderTarget : public ax::Object protected: bool _defaultRenderTarget = false; - mutable bool _dirty = false; + mutable TargetBufferFlags _dirtyFlags{}; }; NS_AX_BACKEND_END diff --git a/core/renderer/backend/metal/RenderTargetMTL.mm b/core/renderer/backend/metal/RenderTargetMTL.mm index e39a8a8df6ba..3a9a34e900e7 100644 --- a/core/renderer/backend/metal/RenderTargetMTL.mm +++ b/core/renderer/backend/metal/RenderTargetMTL.mm @@ -122,7 +122,7 @@ static MTLStoreAction getStoreAction(const RenderPassDescriptor& params, TargetB } #endif - _dirty = false; + _dirtyFlags = TargetBufferFlags::NONE; } RenderTargetMTL::Attachment RenderTargetMTL::getColorAttachment(int index) const diff --git a/core/renderer/backend/opengl/RenderTargetGL.cpp b/core/renderer/backend/opengl/RenderTargetGL.cpp index 0f70f2861cf8..de701a71a5bb 100644 --- a/core/renderer/backend/opengl/RenderTargetGL.cpp +++ b/core/renderer/backend/opengl/RenderTargetGL.cpp @@ -43,41 +43,50 @@ void RenderTargetGL::unbindFrameBuffer() const __gl->bindFrameBuffer(0); } -void RenderTargetGL::update() const { - if (!_dirty) return; - if(!_defaultRenderTarget) { - { // color attachments +void RenderTargetGL::update() const +{ + if (!_dirtyFlags) + return; + if (!_defaultRenderTarget) + { + if (bitmask::any(_dirtyFlags, TargetBufferFlags::COLOR_ALL)) + { // color attachments GLenum bufs[MAX_COLOR_ATTCHMENT] = {GL_NONE}; for (size_t i = 0; i < MAX_COLOR_ATTCHMENT; ++i) { - GLuint texture = 0; - GLint level = 0; - if (_color[i]) - { - texture = static_cast(_color[i].texture->getHandler()); - level = _color[i].level; + auto textureInfo = _color[i]; + if (textureInfo.texture) bufs[i] = GL_COLOR_ATTACHMENT0 + i; - } - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, texture, level); + if (bitmask::any(_dirtyFlags, getMRTColorFlag(i))) + glFramebufferTexture2D( + GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, + static_cast(textureInfo.texture ? textureInfo.texture->getHandler() : 0), + textureInfo.level); } - #if AX_TARGET_PLATFORM == AX_PLATFORM_WIN32 || AX_TARGET_PLATFORM == AX_PLATFORM_LINUX +#if AX_GLES_PROFILE != 200 glDrawBuffers(MAX_COLOR_ATTCHMENT, bufs); - #endif +#endif CHECK_GL_ERROR_DEBUG(); } - // depth attacmhemt - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, - _depth.texture != nullptr ? _depth.texture->getHandler() : 0, _depth.level); - CHECK_GL_ERROR_DEBUG(); + if (bitmask::any(_dirtyFlags, TargetBufferFlags::DEPTH)) + { + // depth attacmhemt + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, + _depth.texture != nullptr ? _depth.texture->getHandler() : 0, _depth.level); + CHECK_GL_ERROR_DEBUG(); + } - // stencil attachment - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, - _stencil.texture != nullptr ? _stencil.texture->getHandler() : 0, _stencil.level); - CHECK_GL_ERROR_DEBUG(); + if (bitmask::any(_dirtyFlags, TargetBufferFlags::STENCIL)) + { + // stencil attachment + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, + _stencil.texture != nullptr ? _stencil.texture->getHandler() : 0, _stencil.level); + CHECK_GL_ERROR_DEBUG(); + } } - _dirty = false; + _dirtyFlags = TargetBufferFlags::NONE; } NS_AX_BACKEND_END