From 86a6b04d4ab45c634fe2bf509f2242963f0fda06 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 4 Mar 2019 21:54:50 -0500 Subject: [PATCH 1/5] Begins attempts to keep track of display metrics. i.e. a system that can both make smart decisions about when to use a lower resolution, and hopefully allow some sort of flywheel-esque horizontal retrace synchronisation. And possibly some raster beam chasing? --- .../Clock Signal.xcodeproj/project.pbxproj | 8 ++++- Outputs/DisplayMetrics.cpp | 20 +++++++++++ Outputs/DisplayMetrics.hpp | 34 +++++++++++++++++++ Outputs/OpenGL/ScanTarget.cpp | 22 ++++++++++++ Outputs/OpenGL/ScanTarget.hpp | 12 ++++++- 5 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 Outputs/DisplayMetrics.cpp create mode 100644 Outputs/DisplayMetrics.hpp diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 274d62ce5..0c58b16d3 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -215,6 +215,7 @@ 4B595FAE2086DFBA0083CAA8 /* AudioToggle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B595FAC2086DFBA0083CAA8 /* AudioToggle.cpp */; }; 4B5FADBA1DE3151600AEC565 /* FileHolder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5FADB81DE3151600AEC565 /* FileHolder.cpp */; }; 4B5FADC01DE3BF2B00AEC565 /* Microdisc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5FADBE1DE3BF2B00AEC565 /* Microdisc.cpp */; }; + 4B622AE5222E0AD5008B59F2 /* DisplayMetrics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B622AE3222E0AD5008B59F2 /* DisplayMetrics.cpp */; }; 4B643F3A1D77AD1900D431D6 /* CSStaticAnalyser.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B643F391D77AD1900D431D6 /* CSStaticAnalyser.mm */; }; 4B643F3F1D77B88000D431D6 /* DocumentController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B643F3E1D77B88000D431D6 /* DocumentController.swift */; }; 4B69FB3D1C4D908A00B5F0AA /* Tape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B69FB3B1C4D908A00B5F0AA /* Tape.cpp */; }; @@ -897,6 +898,8 @@ 4B5FADB91DE3151600AEC565 /* FileHolder.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FileHolder.hpp; sourceTree = ""; }; 4B5FADBE1DE3BF2B00AEC565 /* Microdisc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Microdisc.cpp; path = Oric/Microdisc.cpp; sourceTree = ""; }; 4B5FADBF1DE3BF2B00AEC565 /* Microdisc.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Microdisc.hpp; path = Oric/Microdisc.hpp; sourceTree = ""; }; + 4B622AE3222E0AD5008B59F2 /* DisplayMetrics.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DisplayMetrics.cpp; path = ../../Outputs/DisplayMetrics.cpp; sourceTree = ""; }; + 4B622AE4222E0AD5008B59F2 /* DisplayMetrics.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = DisplayMetrics.hpp; path = ../../Outputs/DisplayMetrics.hpp; sourceTree = ""; }; 4B643F381D77AD1900D431D6 /* CSStaticAnalyser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSStaticAnalyser.h; path = StaticAnalyser/CSStaticAnalyser.h; sourceTree = ""; }; 4B643F391D77AD1900D431D6 /* CSStaticAnalyser.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = CSStaticAnalyser.mm; path = StaticAnalyser/CSStaticAnalyser.mm; sourceTree = ""; }; 4B643F3C1D77AE5C00D431D6 /* CSMachine+Target.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CSMachine+Target.h"; sourceTree = ""; }; @@ -1780,7 +1783,9 @@ 4B366DFD1B5C165F0026627B /* Outputs */ = { isa = PBXGroup; children = ( + 4B622AE3222E0AD5008B59F2 /* DisplayMetrics.cpp */, 4B05401D219D1618001BF69C /* ScanTarget.cpp */, + 4B622AE4222E0AD5008B59F2 /* DisplayMetrics.hpp */, 4BD601A920D89F2A00CBCE57 /* Log.hpp */, 4BF52672218E752E00313227 /* ScanTarget.hpp */, 4B0CCC411C62D0B3001CAC5F /* CRT */, @@ -3025,8 +3030,8 @@ 4BD5D2672199148100DDF17D /* ScanTargetGLSLFragments.cpp */, 4BD191D9219113B80042E144 /* OpenGL.hpp */, 4BD191F32191180E0042E144 /* ScanTarget.hpp */, - 4BD424DC2193B5340097291A /* Primitives */, 4B961408222760E0001A7BF2 /* Screenshot.hpp */, + 4BD424DC2193B5340097291A /* Primitives */, ); name = OpenGL; path = ../../Outputs/OpenGL; @@ -3895,6 +3900,7 @@ 4BD3A30B1EE755C800B5B501 /* Video.cpp in Sources */, 4B5FADBA1DE3151600AEC565 /* FileHolder.cpp in Sources */, 4B643F3A1D77AD1900D431D6 /* CSStaticAnalyser.mm in Sources */, + 4B622AE5222E0AD5008B59F2 /* DisplayMetrics.cpp in Sources */, 4B1497881EE4A1DA00CE2596 /* ZX80O81P.cpp in Sources */, 4B894520201967B4007DE474 /* StaticAnalyser.cpp in Sources */, 4B2B3A4B1F9B8FA70062DABF /* Typer.cpp in Sources */, diff --git a/Outputs/DisplayMetrics.cpp b/Outputs/DisplayMetrics.cpp new file mode 100644 index 000000000..7e9300258 --- /dev/null +++ b/Outputs/DisplayMetrics.cpp @@ -0,0 +1,20 @@ +// +// DisplayMetrics.cpp +// Clock Signal +// +// Created by Thomas Harte on 04/03/2019. +// Copyright © 2019 Thomas Harte. All rights reserved. +// + +#include "DisplayMetrics.hpp" + +using namespace Outputs::Display; + +void Metrics::announce_event(ScanTarget::Event event) { +} + +void Metrics::announce_did_resize() { +} + +void Metrics::announce_draw_status(size_t lines, std::chrono::high_resolution_clock::duration duration, bool complete) { +} diff --git a/Outputs/DisplayMetrics.hpp b/Outputs/DisplayMetrics.hpp new file mode 100644 index 000000000..cba50a16b --- /dev/null +++ b/Outputs/DisplayMetrics.hpp @@ -0,0 +1,34 @@ +// +// DisplayMetrics.hpp +// Clock Signal +// +// Created by Thomas Harte on 04/03/2019. +// Copyright © 2019 Thomas Harte. All rights reserved. +// + +#ifndef DisplayMetrics_hpp +#define DisplayMetrics_hpp + +#include "ScanTarget.hpp" +#include + +namespace Outputs { +namespace Display { + +/*! + A class to derive various metrics about the input to a ScanTarget, + based purely on empirical observation. In particular it is intended + to allow for host-client frame synchronisation. +*/ +class Metrics { + public: + void announce_event(ScanTarget::Event event); + + void announce_did_resize(); + void announce_draw_status(size_t lines, std::chrono::high_resolution_clock::duration duration, bool complete); +}; + +} +} + +#endif /* DisplayMetrics_hpp */ diff --git a/Outputs/OpenGL/ScanTarget.cpp b/Outputs/OpenGL/ScanTarget.cpp index ade949552..c7a72765b 100644 --- a/Outputs/OpenGL/ScanTarget.cpp +++ b/Outputs/OpenGL/ScanTarget.cpp @@ -254,6 +254,9 @@ void ScanTarget::submit() { } void ScanTarget::announce(Event event, bool is_visible, const Outputs::Display::ScanTarget::Scan::EndPoint &location, uint8_t composite_amplitude) { + // Forward the event to the display metrics tracker. + display_metrics_.announce_event(event); + if(event == ScanTarget::Event::EndVerticalRetrace) { // The previous-frame-is-complete flag is subject to a two-slot queue because // measurement for *this* frame needs to begin now, meaning that the previous @@ -383,14 +386,26 @@ void ScanTarget::setup_pipeline() { input_shader_->set_uniform("textureName", GLint(SourceDataTextureUnit - GL_TEXTURE0)); } +Outputs::Display::Metrics &ScanTarget::display_metrics() { + return display_metrics_; +} + void ScanTarget::update(int output_width, int output_height) { if(fence_ != nullptr) { // if the GPU is still busy, don't wait; we'll catch it next time if(glClientWaitSync(fence_, GL_SYNC_FLUSH_COMMANDS_BIT, 0) == GL_TIMEOUT_EXPIRED) { + display_metrics_.announce_draw_status( + lines_submitted_, + std::chrono::high_resolution_clock::now() - line_submission_begin_time_, + false); return; } fence_ = nullptr; } + display_metrics_.announce_draw_status( + lines_submitted_, + std::chrono::high_resolution_clock::now() - line_submission_begin_time_, + true); // Spin until the is-drawing flag is reset; the wait sync above will deal // with instances where waiting is inappropriate. @@ -403,10 +418,16 @@ void ScanTarget::update(int output_width, int output_height) { modals_are_dirty_ = false; } + // Determine the start time of this submission group. + line_submission_begin_time_ = std::chrono::high_resolution_clock::now(); + // Grab the current read and submit pointers. const auto submit_pointers = submit_pointers_.load(); const auto read_pointers = read_pointers_.load(); + // Determine how many lines are about to be submitted. + lines_submitted_ = (read_pointers.line + line_buffer_.size() - submit_pointers.line) % line_buffer_.size(); + // Submit scans; only the new ones need to be communicated. size_t new_scans = (submit_pointers.scan_buffer + scan_buffer_.size() - read_pointers.scan_buffer) % scan_buffer_.size(); if(new_scans) { @@ -536,6 +557,7 @@ void ScanTarget::update(int output_width, int output_height) { const int proportional_width = (framebuffer_height * 4) / 3; const bool did_create_accumulation_texture = !accumulation_texture_ || ( /* !synchronous && */ (accumulation_texture_->get_width() != proportional_width || accumulation_texture_->get_height() != framebuffer_height)); if(did_create_accumulation_texture) { + display_metrics_.announce_did_resize(); std::unique_ptr new_framebuffer( new TextureTarget( GLsizei(proportional_width), diff --git a/Outputs/OpenGL/ScanTarget.hpp b/Outputs/OpenGL/ScanTarget.hpp index 1f2e001a5..bf4db9167 100644 --- a/Outputs/OpenGL/ScanTarget.hpp +++ b/Outputs/OpenGL/ScanTarget.hpp @@ -9,8 +9,9 @@ #ifndef ScanTarget_hpp #define ScanTarget_hpp -#include "../ScanTarget.hpp" #include "../Log.hpp" +#include "../DisplayMetrics.hpp" +#include "../ScanTarget.hpp" #include "OpenGL.hpp" #include "Primitives/TextureTarget.hpp" @@ -21,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +49,9 @@ class ScanTarget: public Outputs::Display::ScanTarget { /*! Processes all the latest input, at a resolution suitable for later output to a framebuffer of the specified size. */ void update(int output_width, int output_height); + /*! @returns The DisplayMetrics object that this ScanTarget has been providing with announcements and draw overages. */ + Metrics &display_metrics(); + private: #ifndef NDEBUG struct OpenGLVersionDumper { @@ -78,6 +83,11 @@ class ScanTarget: public Outputs::Display::ScanTarget { bool output_is_visible_ = false; + Metrics display_metrics_; + + size_t lines_submitted_ = 0; + std::chrono::high_resolution_clock::time_point line_submission_begin_time_; + // Extends the definition of a Scan to include two extra fields, // relevant to the way that this scan target processes video. struct Scan { From 5660007221fdb8ec92519b0e5024f878c187924b Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 5 Mar 2019 21:41:20 -0500 Subject: [PATCH 2/5] Experimentally introduces adaptive quality intermediate buffers. --- Outputs/DisplayMetrics.cpp | 59 +++++++++++++++++++++ Outputs/DisplayMetrics.hpp | 10 ++++ Outputs/OpenGL/Primitives/TextureTarget.cpp | 2 +- Outputs/OpenGL/ScanTarget.cpp | 24 +++++++-- Outputs/OpenGL/ScanTarget.hpp | 2 + 5 files changed, 91 insertions(+), 6 deletions(-) diff --git a/Outputs/DisplayMetrics.cpp b/Outputs/DisplayMetrics.cpp index 7e9300258..3814298d2 100644 --- a/Outputs/DisplayMetrics.cpp +++ b/Outputs/DisplayMetrics.cpp @@ -8,13 +8,72 @@ #include "DisplayMetrics.hpp" +#include + using namespace Outputs::Display; +// MARK: Frame size estimation. + void Metrics::announce_event(ScanTarget::Event event) { + switch(event) { + case ScanTarget::Event::EndHorizontalRetrace: + ++lines_this_frame_; + break; + case ScanTarget::Event::EndVerticalRetrace: + add_line_total(lines_this_frame_); + lines_this_frame_ = 0; + break; + default: break; + } } +void Metrics::add_line_total(int total) { +// std::cout << total << '\n'; +} + +float Metrics::lines_per_frame_estimate() { + return 1.0f; // TODO. +} + +// MARK: GPU processing speed decisions. + void Metrics::announce_did_resize() { + frames_missed_ = frames_hit_ = 0; } void Metrics::announce_draw_status(size_t lines, std::chrono::high_resolution_clock::duration duration, bool complete) { + if(!complete) { + ++frames_missed_; + } else { + ++frames_hit_; + } + + // Don't allow the record of history to extend too far into the past. + if(frames_hit_ + frames_missed_ > 200) { + // Subtract from whichever wasn't just incremented, to ensure the + // most recent information is more important than the historic stuff. + if(!complete) { + --frames_hit_; + } else { + --frames_missed_; + } + + // Rebalance if either thing has gone negative. + if(frames_hit_ < 0) { + frames_missed_ += frames_hit_; + frames_hit_ = 0; + } + if(frames_missed_ < 0) { + frames_hit_ += frames_missed_; + frames_missed_ = 0; + } + } +} + +bool Metrics::should_lower_resolution() { + // If less than 100 frames are on record, return no opinion; otherwise + // suggest a lower resolution if more than 10 frames in the last 100-200 + // took too long to produce. + if(frames_hit_ + frames_missed_ < 100) return false; + return frames_missed_ > 10; } diff --git a/Outputs/DisplayMetrics.hpp b/Outputs/DisplayMetrics.hpp index cba50a16b..77eccad1a 100644 --- a/Outputs/DisplayMetrics.hpp +++ b/Outputs/DisplayMetrics.hpp @@ -26,6 +26,16 @@ class Metrics { void announce_did_resize(); void announce_draw_status(size_t lines, std::chrono::high_resolution_clock::duration duration, bool complete); + + bool should_lower_resolution(); + float lines_per_frame_estimate(); + + private: + int lines_this_frame_ = 0; + void add_line_total(int); + + int frames_hit_ = 0; + int frames_missed_ = 0; }; } diff --git a/Outputs/OpenGL/Primitives/TextureTarget.cpp b/Outputs/OpenGL/Primitives/TextureTarget.cpp index 0ffed6a6f..9382f062a 100644 --- a/Outputs/OpenGL/Primitives/TextureTarget.cpp +++ b/Outputs/OpenGL/Primitives/TextureTarget.cpp @@ -33,7 +33,7 @@ TextureTarget::TextureTarget(GLsizei width, GLsizei height, GLenum texture_unit, bind_texture(); // Set dimensions and set the user-supplied magnification filter. - test_gl(glTexImage2D, GL_TEXTURE_2D, 0, GL_RGBA, GLsizei(expanded_width_), GLsizei(expanded_height_), 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + test_gl(glTexImage2D, GL_TEXTURE_2D, 0, GL_RGB, GLsizei(expanded_width_), GLsizei(expanded_height_), 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); test_gl(glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); test_gl(glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); diff --git a/Outputs/OpenGL/ScanTarget.cpp b/Outputs/OpenGL/ScanTarget.cpp index c7a72765b..303c51f88 100644 --- a/Outputs/OpenGL/ScanTarget.cpp +++ b/Outputs/OpenGL/ScanTarget.cpp @@ -13,6 +13,7 @@ #include #include +#include using namespace Outputs::Display::OpenGL; @@ -550,13 +551,26 @@ void ScanTarget::update(int output_width, int output_height) { test_gl(glDrawArraysInstanced, GL_TRIANGLE_STRIP, 0, 4, GLsizei(new_scans)); } - // Ensure the accumulation buffer is properly sized. - // TODO: based on a decision about host speed, potentially switch to the std::min fragment as shown below, - // which would limit total output buffer size to 1440x1080. - const int framebuffer_height = output_height;//std::min(output_height, 1080); + // Logic for reducing resolution: start doing so if the metrics object reports that + // it's a good idea. Go up to a quarter of the requested resolution, subject to + // clamping at each stage. If the output resolution changes, or anything else about + // the output pipeline, just start trying the highest size again. + if(display_metrics_.should_lower_resolution()) { + resolution_reduction_level_ = std::min(resolution_reduction_level_+1, 4); + } + if(output_height_ != output_height || did_setup_pipeline) { + resolution_reduction_level_ = 1; + output_height_ = output_height; + } + const int min_framebuffer_height = (resolution_reduction_level_ > 1) ? 2160 / resolution_reduction_level_ : std::numeric_limits::max(); + + // Ensure the accumulation buffer is properly sized, allowing for the metrics object's + // feelings about whether too high a resolution is being used. + int framebuffer_height = std::min(output_height / resolution_reduction_level_, min_framebuffer_height); const int proportional_width = (framebuffer_height * 4) / 3; - const bool did_create_accumulation_texture = !accumulation_texture_ || ( /* !synchronous && */ (accumulation_texture_->get_width() != proportional_width || accumulation_texture_->get_height() != framebuffer_height)); + const bool did_create_accumulation_texture = !accumulation_texture_ || ( (accumulation_texture_->get_width() != proportional_width || accumulation_texture_->get_height() != framebuffer_height)); if(did_create_accumulation_texture) { + LOG("Changed output resolution to " << proportional_width << " by " << framebuffer_height); display_metrics_.announce_did_resize(); std::unique_ptr new_framebuffer( new TextureTarget( diff --git a/Outputs/OpenGL/ScanTarget.hpp b/Outputs/OpenGL/ScanTarget.hpp index bf4db9167..fa2a5ebf7 100644 --- a/Outputs/OpenGL/ScanTarget.hpp +++ b/Outputs/OpenGL/ScanTarget.hpp @@ -84,6 +84,8 @@ class ScanTarget: public Outputs::Display::ScanTarget { bool output_is_visible_ = false; Metrics display_metrics_; + int resolution_reduction_level_ = 1; + int output_height_ = 0; size_t lines_submitted_ = 0; std::chrono::high_resolution_clock::time_point line_submission_begin_time_; From f18132d6742a42e4d7423cc23d1382d374e97abf Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 5 Mar 2019 22:01:58 -0500 Subject: [PATCH 3/5] Makes effort to round out draft 1 of Outputs::Display::Metrics. --- Outputs/DisplayMetrics.cpp | 19 ++++++++++++++----- Outputs/DisplayMetrics.hpp | 15 ++++++++++++++- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/Outputs/DisplayMetrics.cpp b/Outputs/DisplayMetrics.cpp index 3814298d2..3df043af6 100644 --- a/Outputs/DisplayMetrics.cpp +++ b/Outputs/DisplayMetrics.cpp @@ -8,7 +8,7 @@ #include "DisplayMetrics.hpp" -#include +#include using namespace Outputs::Display; @@ -19,8 +19,10 @@ void Metrics::announce_event(ScanTarget::Event event) { case ScanTarget::Event::EndHorizontalRetrace: ++lines_this_frame_; break; - case ScanTarget::Event::EndVerticalRetrace: + case ScanTarget::Event::BeginVerticalRetrace: add_line_total(lines_this_frame_); + break; + case ScanTarget::Event::EndVerticalRetrace: lines_this_frame_ = 0; break; default: break; @@ -28,11 +30,18 @@ void Metrics::announce_event(ScanTarget::Event event) { } void Metrics::add_line_total(int total) { -// std::cout << total << '\n'; + line_total_history_[line_total_history_pointer_] = total; + line_total_history_pointer_ = (line_total_history_pointer_ + 1) % line_total_history_.size(); } -float Metrics::lines_per_frame_estimate() { - return 1.0f; // TODO. +float Metrics::visible_lines_per_frame_estimate() { + // Just average the number of records contained in line_total_history_ to provide this estimate; + // that array should be an even number, to allow for potential interlaced sources. + return float(std::accumulate(line_total_history_.begin(), line_total_history_.end(), 0)) / float(line_total_history_.size()); +} + +int Metrics::current_line() { + return lines_this_frame_; } // MARK: GPU processing speed decisions. diff --git a/Outputs/DisplayMetrics.hpp b/Outputs/DisplayMetrics.hpp index 77eccad1a..4854e950b 100644 --- a/Outputs/DisplayMetrics.hpp +++ b/Outputs/DisplayMetrics.hpp @@ -10,6 +10,8 @@ #define DisplayMetrics_hpp #include "ScanTarget.hpp" + +#include #include namespace Outputs { @@ -22,16 +24,27 @@ namespace Display { */ class Metrics { public: + /// Notifies Metrics of a beam event. void announce_event(ScanTarget::Event event); + /// Notifies Metrics that the size of the output buffer has changed. void announce_did_resize(); + /// Provides Metrics with a new data point for output speed estimation. void announce_draw_status(size_t lines, std::chrono::high_resolution_clock::duration duration, bool complete); + /// @returns @c true if Metrics thinks a lower output buffer resolution is desirable in the abstract; @c false otherwise. bool should_lower_resolution(); - float lines_per_frame_estimate(); + + /// @returns An estimate of the number of lines being produced per frame, excluding vertical sync. + float visible_lines_per_frame_estimate(); + + /// @returns The number of lines since vertical retrace ended. + int current_line(); private: int lines_this_frame_ = 0; + std::array line_total_history_; + size_t line_total_history_pointer_ = 0; void add_line_total(int); int frames_hit_ = 0; From 7441e3f4c58445245f92631fb0acc28665099210 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 5 Mar 2019 22:10:32 -0500 Subject: [PATCH 4/5] Corrects aspect ratio when changing accumulation texture size. --- Outputs/OpenGL/ScanTarget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Outputs/OpenGL/ScanTarget.cpp b/Outputs/OpenGL/ScanTarget.cpp index 303c51f88..7b0452311 100644 --- a/Outputs/OpenGL/ScanTarget.cpp +++ b/Outputs/OpenGL/ScanTarget.cpp @@ -585,7 +585,7 @@ void ScanTarget::update(int output_width, int output_height) { test_gl(glActiveTexture, AccumulationTextureUnit); accumulation_texture_->bind_texture(); - accumulation_texture_->draw(float(output_width) / float(output_height)); + accumulation_texture_->draw(4.0f / 3.0f); test_gl(glClear, GL_STENCIL_BUFFER_BIT); From 84422676cbe3e22561271c626a713da47b3b746e Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 6 Mar 2019 19:19:30 -0500 Subject: [PATCH 5/5] Switches to more coherent logic about buffer sizing. --- Outputs/OpenGL/ScanTarget.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Outputs/OpenGL/ScanTarget.cpp b/Outputs/OpenGL/ScanTarget.cpp index 7b0452311..a2d46c5ee 100644 --- a/Outputs/OpenGL/ScanTarget.cpp +++ b/Outputs/OpenGL/ScanTarget.cpp @@ -562,11 +562,10 @@ void ScanTarget::update(int output_width, int output_height) { resolution_reduction_level_ = 1; output_height_ = output_height; } - const int min_framebuffer_height = (resolution_reduction_level_ > 1) ? 2160 / resolution_reduction_level_ : std::numeric_limits::max(); // Ensure the accumulation buffer is properly sized, allowing for the metrics object's // feelings about whether too high a resolution is being used. - int framebuffer_height = std::min(output_height / resolution_reduction_level_, min_framebuffer_height); + const int framebuffer_height = std::max(output_height / resolution_reduction_level_, std::min(540, output_height)); const int proportional_width = (framebuffer_height * 4) / 3; const bool did_create_accumulation_texture = !accumulation_texture_ || ( (accumulation_texture_->get_width() != proportional_width || accumulation_texture_->get_height() != framebuffer_height)); if(did_create_accumulation_texture) {