Skip to content

Commit

Permalink
graphics: simplify scaling (have plugin handle it)
Browse files Browse the repository at this point in the history
  • Loading branch information
JoepVanlier committed Jul 7, 2024
1 parent c5edccd commit 62c2105
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 53 deletions.
90 changes: 37 additions & 53 deletions plugin/components/graphics_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ struct YsfxGraphicsView::Impl final : public better::AsyncUpdater::Listener,
bool m_wantRetina = false;
juce::Image m_renderBitmap{juce::Image::ARGB, 1, 1, false};
double m_bitmapScale = 1;
int m_bitmapUnscaledWidth = 0;
int m_bitmapUnscaledHeight = 0;
using Ptr = std::shared_ptr<GfxTarget>;
};

Expand All @@ -78,9 +76,14 @@ struct YsfxGraphicsView::Impl final : public better::AsyncUpdater::Listener,
GfxTarget::Ptr m_gfxTarget;
GfxInputState::Ptr m_gfxInputState;

double m_pixelFactor = 1.0;

// whether the next @gfx is required to repaint the screen in full
bool m_gfxDirty = true;

// whether the jsfx had a first initialization of the gfx resolution or not
bool m_gfxInitialized = false;

//--------------------------------------------------------------------------
struct KeyPressed {
int jcode = 0;
Expand Down Expand Up @@ -230,6 +233,7 @@ void YsfxGraphicsView::setEffect(ysfx_t *fx)
m_impl->m_work.stop();

m_impl->m_gfxDirty = true;
m_impl->m_gfxInitialized = false;

if (!fx || !ysfx_has_section(fx, ysfx_section_gfx)) {
m_impl->m_gfxTimer.reset();
Expand Down Expand Up @@ -276,6 +280,9 @@ void YsfxGraphicsView::paint(juce::Graphics &g)
juce::Point<int> off = m_impl->getDisplayOffset();
Impl::GfxTarget *target = m_impl->m_gfxTarget.get();

// This is probably unwise
this->m_pixelFactor = max(1.0, g.getInternalContext().getPhysicalPixelScaleFactor());

///
std::lock_guard<std::mutex> lock{m_impl->m_asyncRepainter->m_mutex};
juce::Image &image = m_impl->m_asyncRepainter->m_bitmap;
Expand All @@ -285,12 +292,12 @@ void YsfxGraphicsView::paint(juce::Graphics &g)
{
g.fillAll(juce::Colours::black);
}
else if (target->m_bitmapScale == 1) {
else if (target->m_bitmapScale == 1.0) {
g.drawImageAt(image, off.x, off.y);
}
else {
juce::Rectangle<int> dest{off.x, off.y, target->m_bitmapUnscaledWidth, target->m_bitmapUnscaledHeight};
g.drawImage(image, dest.toFloat());
juce::Rectangle<int> dest{off.x, off.y, target->m_gfxWidth, target->m_gfxHeight};
g.drawImage(image, dest.toFloat() / this->m_pixelFactor);
}
}

Expand Down Expand Up @@ -472,8 +479,11 @@ void YsfxGraphicsView::Impl::tickGfx()
ysfx_get_gfx_dim(fx, gfxDim);

bool gfxWantRetina = ysfx_gfx_wants_retina(fx);
if (updateGfxTarget((int)gfxDim[0], (int)gfxDim[1], gfxWantRetina))

if (m_gfxInitialized ? updateGfxTarget(-1, -1, -1) : updateGfxTarget((int)gfxDim[0], (int)gfxDim[1], gfxWantRetina)) {
m_gfxDirty = true;
m_gfxInitialized = true;
}

///
std::shared_ptr<BackgroundWork::GfxMessage> msg{new BackgroundWork::GfxMessage};
Expand Down Expand Up @@ -503,51 +513,32 @@ bool YsfxGraphicsView::Impl::updateGfxTarget(int newWidth, int newHeight, int ne
{
GfxTarget *target = m_gfxTarget.get();

///
newWidth = (newWidth == -1) ? target->m_gfxWidth : newWidth;
newHeight = (newHeight == -1) ? target->m_gfxHeight : newHeight;
newRetina = (newRetina == -1) ? target->m_wantRetina : newRetina;

///
bool needsUpdate = false;
needsUpdate = needsUpdate || (newWidth != target->m_gfxWidth);
needsUpdate = needsUpdate || (newHeight != target->m_gfxHeight);
needsUpdate = needsUpdate || ((bool)newRetina != target->m_wantRetina);
double pixel_factor = m_self->m_pixelFactor;

///
int unscaledWidth = newWidth;
int unscaledHeight = newHeight;
// newWidth is set when the JSFX initializes
newWidth = (newWidth == -1) ? m_self->getWidth() : newWidth;
newHeight = (newHeight == -1) ? m_self->getHeight() : newHeight;
newRetina = (newRetina == -1) ? target->m_wantRetina : newRetina;

if (unscaledWidth <= 0)
unscaledWidth = m_self->getWidth();
if (unscaledHeight <= 0)
unscaledHeight = m_self->getHeight();
// Set internal JSFX texture size
int internal_width = newWidth * pixel_factor;
int internal_height = newHeight * pixel_factor;

needsUpdate = needsUpdate || (unscaledWidth != target->m_bitmapUnscaledWidth);
needsUpdate = needsUpdate || (unscaledHeight != target->m_bitmapUnscaledHeight);

///
double bitmapScale = 1;
int scaledWidth = unscaledWidth;
int scaledHeight = unscaledHeight;
if (newRetina) {
bitmapScale = 1; // TODO how to get the display scale factor?
scaledWidth = (int)std::ceil(unscaledWidth * bitmapScale);
scaledHeight = (int)std::ceil(unscaledHeight * bitmapScale);
}
needsUpdate = needsUpdate || (target->m_renderBitmap.getWidth() != juce::jmax(1, scaledWidth));
needsUpdate = needsUpdate || (target->m_renderBitmap.getHeight() != juce::jmax(1, scaledHeight));
bool needsUpdate = (
(target->m_gfxWidth != internal_width)
|| (target->m_gfxHeight != internal_height)
|| (target->m_wantRetina != newRetina)
|| (std::abs(target->m_bitmapScale - pixel_factor) > 1e-4)
);

if (needsUpdate) {
target = new GfxTarget;
m_gfxTarget.reset(target);
target->m_gfxWidth = newWidth;
target->m_gfxHeight = newHeight;
target->m_gfxWidth = internal_width;
target->m_gfxHeight = internal_height;
target->m_wantRetina = (bool)newRetina;
target->m_renderBitmap = juce::Image(juce::Image::ARGB, juce::jmax(1, scaledWidth), juce::jmax(1, scaledHeight), true);
target->m_bitmapScale = bitmapScale;
target->m_bitmapUnscaledWidth = unscaledWidth;
target->m_bitmapUnscaledHeight = unscaledHeight;
target->m_renderBitmap = juce::Image(juce::Image::ARGB, juce::jmax(1, internal_width), juce::jmax(1, internal_height), true);
target->m_bitmapScale = pixel_factor;
}

return needsUpdate;
Expand Down Expand Up @@ -581,15 +572,8 @@ void YsfxGraphicsView::Impl::updateYsfxMouseButtons(const juce::MouseEvent &even

juce::Point<int> YsfxGraphicsView::Impl::getDisplayOffset() const
{
int w = m_self->getWidth();
int h = m_self->getHeight();
int bw = m_gfxTarget->m_bitmapUnscaledWidth;
int bh = m_gfxTarget->m_bitmapUnscaledHeight;

juce::Point<int> pt;
pt.x = (bw < w) ? ((w - bw) / 2) : 0;
pt.y = (bh < h) ? ((h - bh) / 2) : 0;
return pt;
// Let JSFX handle the UX offsetting themselves
return juce::Point<int>{0, 0};
}

int YsfxGraphicsView::Impl::showYsfxMenu(void *userdata, const char *desc, int32_t xpos, int32_t ypos)
Expand Down Expand Up @@ -786,7 +770,7 @@ void YsfxGraphicsView::Impl::BackgroundWork::processGfxMessage(GfxMessage &msg)
gc.pixel_height = (uint32_t)bdata.height;
gc.pixel_stride = (uint32_t)bdata.lineStride;
gc.pixels = bdata.data;
gc.scale_factor = target->m_bitmapScale;
gc.scale_factor = 1.0; // This is handled by setting the UI size in the plugin ourselves
gc.show_menu = &showYsfxMenu;
gc.set_cursor = &setYsfxCursor;
gc.get_drop_file = &getYsfxDropFile;
Expand Down
2 changes: 2 additions & 0 deletions plugin/components/graphics_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ class YsfxGraphicsView : public juce::Component {
void mouseWheelMove(const juce::MouseEvent &event, const juce::MouseWheelDetails &wheel) override;

private:
double m_pixelFactor{1.0};

struct Impl;
std::unique_ptr<Impl> m_impl;
};

0 comments on commit 62c2105

Please sign in to comment.