Retinafy the video display

This commit is contained in:
Thomas Goyne 2013-12-27 09:56:39 -08:00
parent c8368a500b
commit f0d35a1cf3
3 changed files with 30 additions and 11 deletions

View file

@ -42,15 +42,19 @@ RetinaHelper::RetinaHelper(wxWindow *window)
: window(window) : window(window)
, observer([RetinaObserver new]) , observer([RetinaObserver new])
{ {
NSView *view = window->GetHandle();
RetinaObserver *obs = (id)observer; RetinaObserver *obs = (id)observer;
obs.window = window->GetHandle().window; obs.window = view.window;
obs.block = ^{ ScaleFactorChanged(GetScaleFactor()); }; obs.block = ^{ ScaleFactorChanged(GetScaleFactor()); };
NSNotificationCenter *nc = NSNotificationCenter.defaultCenter; NSNotificationCenter *nc = NSNotificationCenter.defaultCenter;
[nc addObserver:(id)observer [nc addObserver:(id)observer
selector:@selector(backingPropertiesDidChange:) selector:@selector(backingPropertiesDidChange:)
name:NSWindowDidChangeBackingPropertiesNotification name:NSWindowDidChangeBackingPropertiesNotification
object:window->GetHandle().window]; object:view.window];
if ([view respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)])
view.wantsBestResolutionOpenGLSurface = YES;
} }
RetinaHelper::~RetinaHelper() { RetinaHelper::~RetinaHelper() {

View file

@ -43,6 +43,7 @@
#include "include/aegisub/hotkey.h" #include "include/aegisub/hotkey.h"
#include "include/aegisub/menu.h" #include "include/aegisub/menu.h"
#include "options.h" #include "options.h"
#include "retina_helper.h"
#include "spline_curve.h" #include "spline_curve.h"
#include "subs_controller.h" #include "subs_controller.h"
#include "threaded_frame_source.h" #include "threaded_frame_source.h"
@ -99,6 +100,13 @@ VideoDisplay::VideoDisplay(
, toolBar(visualSubToolBar) , toolBar(visualSubToolBar)
, zoomBox(zoomBox) , zoomBox(zoomBox)
, freeSize(freeSize) , freeSize(freeSize)
, retina_helper(agi::util::make_unique<RetinaHelper>(this))
, scale_factor(retina_helper->GetScaleFactor())
, scale_factor_connection(retina_helper->AddScaleFactorListener([=](int new_scale_factor) {
double new_zoom = zoomValue * new_scale_factor / scale_factor;
scale_factor = new_scale_factor;
SetZoom(new_zoom);
}))
{ {
zoomBox->SetValue(wxString::Format("%g%%", zoomValue * 100.)); zoomBox->SetValue(wxString::Format("%g%%", zoomValue * 100.));
zoomBox->Bind(wxEVT_COMBOBOX, &VideoDisplay::SetZoomFromBox, this); zoomBox->Bind(wxEVT_COMBOBOX, &VideoDisplay::SetZoomFromBox, this);
@ -199,7 +207,7 @@ void VideoDisplay::Render() try {
E(glMatrixMode(GL_PROJECTION)); E(glMatrixMode(GL_PROJECTION));
E(glLoadIdentity()); E(glLoadIdentity());
E(glOrtho(0.0f, videoSize.GetWidth(), videoSize.GetHeight(), 0.0f, -1000.0f, 1000.0f)); E(glOrtho(0.0f, videoSize.GetWidth() / scale_factor, videoSize.GetHeight() / scale_factor, 0.0f, -1000.0f, 1000.0f));
if (OPT_GET("Video/Overscan Mask")->GetBool()) { if (OPT_GET("Video/Overscan Mask")->GetBool()) {
double ar = con->videoController->GetAspectRatioValue(); double ar = con->videoController->GetAspectRatioValue();
@ -272,7 +280,7 @@ void VideoDisplay::PositionVideo() {
if (!con->videoController->IsLoaded() || !IsShownOnScreen()) return; if (!con->videoController->IsLoaded() || !IsShownOnScreen()) return;
viewport_left = 0; viewport_left = 0;
viewport_bottom = GetClientSize().GetHeight() - videoSize.GetHeight(); viewport_bottom = GetClientSize().GetHeight() * scale_factor - videoSize.GetHeight();
viewport_top = 0; viewport_top = 0;
viewport_width = videoSize.GetWidth(); viewport_width = videoSize.GetWidth();
viewport_height = videoSize.GetHeight(); viewport_height = videoSize.GetHeight();
@ -300,7 +308,8 @@ void VideoDisplay::PositionVideo() {
} }
if (tool) if (tool)
tool->SetDisplayArea(viewport_left, viewport_top, viewport_width, viewport_height); tool->SetDisplayArea(viewport_left / scale_factor, viewport_top / scale_factor,
viewport_width / scale_factor, viewport_height / scale_factor);
Render(); Render();
} }
@ -320,12 +329,12 @@ void VideoDisplay::UpdateSize() {
wxSize cs = GetClientSize(); wxSize cs = GetClientSize();
wxSize oldSize = top->GetSize(); wxSize oldSize = top->GetSize();
top->SetSize(top->GetSize() + videoSize - cs); top->SetSize(top->GetSize() + videoSize / scale_factor - cs);
SetClientSize(cs + top->GetSize() - oldSize); SetClientSize(cs + top->GetSize() - oldSize);
} }
else { else {
SetMinClientSize(videoSize); SetMinClientSize(videoSize / scale_factor);
SetMaxClientSize(videoSize); SetMaxClientSize(videoSize / scale_factor);
GetGrandParent()->Layout(); GetGrandParent()->Layout();
} }
@ -335,7 +344,7 @@ void VideoDisplay::UpdateSize() {
void VideoDisplay::OnSizeEvent(wxSizeEvent &event) { void VideoDisplay::OnSizeEvent(wxSizeEvent &event) {
if (freeSize) { if (freeSize) {
videoSize = GetClientSize(); videoSize = GetClientSize() * scale_factor;
PositionVideo(); PositionVideo();
zoomValue = double(viewport_height) / con->videoController->GetHeight(); zoomValue = double(viewport_height) / con->videoController->GetHeight();
zoomBox->ChangeValue(wxString::Format("%g%%", zoomValue * 100.)); zoomBox->ChangeValue(wxString::Format("%g%%", zoomValue * 100.));
@ -419,7 +428,8 @@ void VideoDisplay::SetTool(std::unique_ptr<VisualToolBase> new_tool) {
else { else {
// UpdateSize fits the window to the video, which we don't want to do // UpdateSize fits the window to the video, which we don't want to do
GetGrandParent()->Layout(); GetGrandParent()->Layout();
tool->SetDisplayArea(viewport_left, viewport_top, viewport_width, viewport_height); tool->SetDisplayArea(viewport_left / scale_factor, viewport_top / scale_factor,
viewport_width / scale_factor, viewport_height / scale_factor);
} }
} }

View file

@ -42,13 +42,14 @@
#include <wx/glcanvas.h> #include <wx/glcanvas.h>
// Prototypes // Prototypes
struct FrameReadyEvent; class RetinaHelper;
class VideoContext; class VideoContext;
class VideoOutGL; class VideoOutGL;
class VisualToolBase; class VisualToolBase;
class wxComboBox; class wxComboBox;
class wxTextCtrl; class wxTextCtrl;
class wxToolBar; class wxToolBar;
struct FrameReadyEvent;
struct VideoFrame; struct VideoFrame;
namespace agi { namespace agi {
@ -106,6 +107,10 @@ class VideoDisplay : public wxGLCanvas {
/// Frame which will replace the currently visible frame on the next render /// Frame which will replace the currently visible frame on the next render
std::shared_ptr<VideoFrame> pending_frame; std::shared_ptr<VideoFrame> pending_frame;
std::unique_ptr<RetinaHelper> retina_helper;
int scale_factor;
agi::signal::Connection scale_factor_connection;
/// @brief Draw an overscan mask /// @brief Draw an overscan mask
/// @param horizontal_percent The percent of the video reserved horizontally /// @param horizontal_percent The percent of the video reserved horizontally
/// @param vertical_percent The percent of the video reserved vertically /// @param vertical_percent The percent of the video reserved vertically