diff --git a/Engine/EffectInstance.cpp b/Engine/EffectInstance.cpp
index 968793e8a..b104c29d6 100644
--- a/Engine/EffectInstance.cpp
+++ b/Engine/EffectInstance.cpp
@@ -814,7 +814,7 @@ EffectInstance::getImage(int inputNb,
/*
* These are the data fields stored in the TLS from the on-going render action or instance changed action
*/
- unsigned int mipMapLevel = Image::getLevelFromScale(scale.x);
+ unsigned int mipMapLevel = scale.toMipmapLevel();
RoIMap inputsRoI;
bool isIdentity = false;
EffectInstancePtr identityInput;
@@ -1176,7 +1176,7 @@ EffectInstance::calcDefaultRegionOfDefinition(U64 /*hash*/,
RectD *rod)
{
- unsigned int mipMapLevel = Image::getLevelFromScale(scale.x);
+ unsigned int mipMapLevel = scale.toMipmapLevel();
RectI format = getOutputFormat();
double par = getAspectRatio(-1);
*rod = format.toCanonical_noClipping(mipMapLevel, par);
@@ -1258,7 +1258,7 @@ EffectInstance::ifInfiniteApplyHeuristic(U64 hash,
bool isProjectFormat;
RenderScale inputScale = scale;
if (input->supportsRenderScaleMaybe() == eSupportsNo) {
- inputScale.x = inputScale.y = 1.;
+ inputScale = RenderScale::identity;
}
StatusEnum st = input->getRegionOfDefinition_public(hash, time, inputScale, view, &inputRod, &isProjectFormat);
if (st != eStatusFailed) {
@@ -1281,7 +1281,7 @@ EffectInstance::ifInfiniteApplyHeuristic(U64 hash,
RectI format = getOutputFormat();
assert(!format.isNull());
double par = getAspectRatio(-1);
- unsigned int mipMapLevel = Image::getLevelFromScale(scale.x);
+ unsigned int mipMapLevel = scale.toMipmapLevel();
canonicalFormat = format.toCanonical_noClipping(mipMapLevel, par);
}
@@ -1351,7 +1351,7 @@ EffectInstance::getRegionsOfInterest(double time,
//Tiles not supported: get the RoD as RoI
RectD rod;
bool isPF;
- RenderScale inpScale(input->supportsRenderScale() ? scale.x : 1.);
+ RenderScale inpScale = (input->supportsRenderScale() ? scale : RenderScale::identity);
StatusEnum stat = input->getRegionOfDefinition_public(input->getRenderHash(), time, inpScale, view, &rod, &isPF);
if (stat == eStatusFailed) {
return;
@@ -2060,10 +2060,11 @@ EffectInstance::transformInputRois(const EffectInstance* self,
invertTransform = Transform::matInverse(*it->second.cat, det);
}
- Transform::Matrix3x3 canonicalToPixel = Transform::matCanonicalToPixel(par, scale.x,
- scale.y, false);
- Transform::Matrix3x3 pixelToCanonical = Transform::matPixelToCanonical(par, scale.x,
- scale.y, false);
+ const auto scalePt = scale.toOfxPointD();
+ Transform::Matrix3x3 canonicalToPixel = Transform::matCanonicalToPixel(par, scalePt.x,
+ scalePt.y, false);
+ Transform::Matrix3x3 pixelToCanonical = Transform::matPixelToCanonical(par, scalePt.x,
+ scalePt.y, false);
invertTransform = Transform::matMul(Transform::matMul(pixelToCanonical, invertTransform), canonicalToPixel);
Transform::transformRegionFromRoD(foundRoI->second, invertTransform, transformedRenderWindow);
@@ -2275,7 +2276,7 @@ EffectInstance::Implementation::tiledRenderingFunctor(const RectToRender & rectT
}
#ifndef NDEBUG
- RenderScale scale( Image::getScaleFromMipMapLevel(mipMapLevel) );
+ RenderScale scale = RenderScale::fromMipmapLevel(mipMapLevel);
// check the dimensions of all input and output images
const RectD & dstRodCanonical = firstPlaneToRender.renderMappedImage->getRoD();
const RectI dstBounds = dstRodCanonical.toPixelEnclosing(firstPlaneToRender.renderMappedImage->getMipMapLevel(), par); // compute dstRod at level 0
@@ -2401,10 +2402,9 @@ EffectInstance::Implementation::renderHandler(const EffectTLSDataPtr& tls,
RenderActionArgs actionArgs;
actionArgs.byPassCache = byPassCache;
actionArgs.processChannels = processChannels;
- actionArgs.mappedScale.x = actionArgs.mappedScale.y = Image::getScaleFromMipMapLevel( firstPlane.renderMappedImage->getMipMapLevel() );
+ actionArgs.mappedScale = RenderScale::fromMipmapLevel(firstPlane.renderMappedImage->getMipMapLevel());
assert(isSupportedRenderScale(_publicInterface->supportsRenderScaleMaybe(), actionArgs.mappedScale));
- actionArgs.originalScale.x = Image::getScaleFromMipMapLevel(mipMapLevel);
- actionArgs.originalScale.y = actionArgs.originalScale.x;
+ actionArgs.originalScale = RenderScale::fromMipmapLevel(mipMapLevel);
actionArgs.draftMode = frameArgs->draftMode;
actionArgs.useOpenGL = planes.useOpenGL;
@@ -3303,7 +3303,7 @@ EffectInstance::drawOverlay_public(double time,
RenderScale actualScale;
if ( !canHandleRenderScaleForOverlays() ) {
- actualScale.x = actualScale.y = 1.;
+ actualScale = RenderScale::identity;
} else {
actualScale = renderScale;
}
@@ -3335,7 +3335,7 @@ EffectInstance::onOverlayPenDown_public(double time,
RenderScale actualScale;
if ( !canHandleRenderScaleForOverlays() ) {
- actualScale.x = actualScale.y = 1.;
+ actualScale = RenderScale::identity;
} else {
actualScale = renderScale;
}
@@ -3379,7 +3379,7 @@ EffectInstance::onOverlayPenDoubleClicked_public(double time,
RenderScale actualScale;
if ( !canHandleRenderScaleForOverlays() ) {
- actualScale.x = actualScale.y = 1.;
+ actualScale = RenderScale::identity;
} else {
actualScale = renderScale;
}
@@ -3425,7 +3425,7 @@ EffectInstance::onOverlayPenMotion_public(double time,
RenderScale actualScale;
if ( !canHandleRenderScaleForOverlays() ) {
- actualScale.x = actualScale.y = 1.;
+ actualScale = RenderScale::identity;
} else {
actualScale = renderScale;
}
@@ -3471,7 +3471,7 @@ EffectInstance::onOverlayPenUp_public(double time,
RenderScale actualScale;
if ( !canHandleRenderScaleForOverlays() ) {
- actualScale.x = actualScale.y = 1.;
+ actualScale = RenderScale::identity;
} else {
actualScale = renderScale;
}
@@ -3515,7 +3515,7 @@ EffectInstance::onOverlayKeyDown_public(double time,
RenderScale actualScale;
if ( !canHandleRenderScaleForOverlays() ) {
- actualScale.x = actualScale.y = 1.;
+ actualScale = RenderScale::identity;
} else {
actualScale = renderScale;
}
@@ -3551,7 +3551,7 @@ EffectInstance::onOverlayKeyUp_public(double time,
RenderScale actualScale;
if ( !canHandleRenderScaleForOverlays() ) {
- actualScale.x = actualScale.y = 1.;
+ actualScale = RenderScale::identity;
} else {
actualScale = renderScale;
}
@@ -3587,7 +3587,7 @@ EffectInstance::onOverlayKeyRepeat_public(double time,
RenderScale actualScale;
if ( !canHandleRenderScaleForOverlays() ) {
- actualScale.x = actualScale.y = 1.;
+ actualScale = RenderScale::identity;
} else {
actualScale = renderScale;
}
@@ -3620,7 +3620,7 @@ EffectInstance::onOverlayFocusGained_public(double time,
RenderScale actualScale;
if ( !canHandleRenderScaleForOverlays() ) {
- actualScale.x = actualScale.y = 1.;
+ actualScale = RenderScale::identity;
} else {
actualScale = renderScale;
}
@@ -3654,7 +3654,7 @@ EffectInstance::onOverlayFocusLost_public(double time,
RenderScale actualScale;
if ( !canHandleRenderScaleForOverlays() ) {
- actualScale.x = actualScale.y = 1.;
+ actualScale = RenderScale::identity;
} else {
actualScale = renderScale;
}
@@ -3815,7 +3815,7 @@ EffectInstance::getRegionOfDefinitionFromCache(U64 hash,
RectD* rod,
bool* isProjectFormat)
{
- unsigned int mipMapLevel = Image::getLevelFromScale(scale.x);
+ unsigned int mipMapLevel = scale.toMipmapLevel();
bool foundInCache = _imp->actionsCache->getRoDResult(hash, time, view, mipMapLevel, rod);
if (foundInCache) {
@@ -3844,7 +3844,7 @@ EffectInstance::getRegionOfDefinition_public(U64 hash,
return eStatusFailed;
}
- unsigned int mipMapLevel = Image::getLevelFromScale(scale.x);
+ unsigned int mipMapLevel = scale.toMipmapLevel();
bool foundInCache = _imp->actionsCache->getRoDResult(hash, time, view, mipMapLevel, rod);
if (foundInCache) {
if (isProjectFormat) {
@@ -3881,12 +3881,11 @@ EffectInstance::getRegionOfDefinition_public(U64 hash,
}
StatusEnum ret;
- RenderScale scaleOne(1.);
{
RECURSIVE_ACTION();
- ret = getRegionOfDefinition(hash, time, supportsRenderScaleMaybe() == eSupportsNo ? scaleOne : scale, view, rod);
+ ret = getRegionOfDefinition(hash, time, supportsRenderScaleMaybe() == eSupportsNo ? RenderScale::identity : scale, view, rod);
if ( (ret != eStatusOK) && (ret != eStatusReplyDefault) ) {
// rod is not valid
@@ -4643,11 +4642,11 @@ EffectInstance::redrawOverlayInteract()
RenderScale
EffectInstance::getOverlayInteractRenderScale() const
{
- RenderScale renderScale(1.);
+ RenderScale renderScale;
if (isDoingInteractAction() && _imp->overlaysViewport) {
unsigned int mmLevel = _imp->overlaysViewport->getCurrentRenderScale();
- renderScale.x = renderScale.y = Image::getScaleFromMipMapLevel(mmLevel);
+ renderScale = RenderScale::fromMipmapLevel(mmLevel);
}
return renderScale;
@@ -5070,7 +5069,6 @@ EffectInstancePtr
EffectInstance::getNearestNonIdentity(double time)
{
U64 hash = getRenderHash();
- RenderScale scale(1.);
Format frmt;
getApp()->getProject()->getProjectDefaultFormat(&frmt);
@@ -5078,7 +5076,7 @@ EffectInstance::getNearestNonIdentity(double time)
double inputTimeIdentity;
int inputNbIdentity;
ViewIdx inputView;
- if ( !isIdentity_public(true, hash, time, scale, frmt, ViewIdx(0), &inputTimeIdentity, &inputView, &inputNbIdentity) ) {
+ if ( !isIdentity_public(true, hash, time, RenderScale::identity, frmt, ViewIdx(0), &inputTimeIdentity, &inputView, &inputNbIdentity) ) {
return shared_from_this();
} else {
if (inputNbIdentity < 0) {
diff --git a/Engine/EffectInstance.h b/Engine/EffectInstance.h
index b50e56c58..1c0d915c6 100644
--- a/Engine/EffectInstance.h
+++ b/Engine/EffectInstance.h
@@ -39,6 +39,7 @@
#include "Engine/Knob.h" // for KnobHolder
#include "Engine/RectD.h"
#include "Engine/RectI.h"
+#include "Engine/RenderScale.h"
#include "Engine/RenderStats.h"
#include "Engine/EngineFwd.h"
#include "Engine/ParallelRenderArgs.h"
@@ -158,7 +159,7 @@ GCC_DIAG_SUGGEST_OVERRIDE_ON
RenderRoIArgs()
: time(0)
- , scale(1.)
+ , scale()
, mipMapLevel(0)
, view(0)
, roi()
@@ -1132,7 +1133,7 @@ GCC_DIAG_SUGGEST_OVERRIDE_ON
**/
static bool isSupportedRenderScale(SupportsEnum supportsRS, const RenderScale renderScale)
{
- return (supportsRS != eSupportsNo) || (renderScale.x == 1. && renderScale.y == 1.);
+ return (supportsRS != eSupportsNo) || (renderScale == RenderScale::identity);
}
public:
diff --git a/Engine/EffectInstanceRenderRoI.cpp b/Engine/EffectInstanceRenderRoI.cpp
index f6cf35875..d6c05e7ec 100644
--- a/Engine/EffectInstanceRenderRoI.cpp
+++ b/Engine/EffectInstanceRenderRoI.cpp
@@ -386,7 +386,7 @@ EffectInstance::renderRoI(const RenderRoIArgs & args,
} else {
renderMappedMipMapLevel = args.mipMapLevel;
}
- RenderScale renderMappedScale( Image::getScaleFromMipMapLevel(renderMappedMipMapLevel) );
+ RenderScale renderMappedScale( RenderScale::fromMipmapLevel(renderMappedMipMapLevel) );
assert(isSupportedRenderScale(supportsRS, renderMappedScale));
@@ -426,7 +426,7 @@ EffectInstance::renderRoI(const RenderRoIArgs & args,
supportsRS = supportsRenderScaleMaybe();
renderFullScaleThenDownscale = (supportsRS == eSupportsNo && mipMapLevel != 0);
if (renderFullScaleThenDownscale) {
- renderMappedScale.x = renderMappedScale.y = 1.;
+ renderMappedScale = RenderScale::identity;
renderMappedMipMapLevel = 0;
}
}
@@ -572,7 +572,7 @@ EffectInstance::renderRoI(const RenderRoIArgs & args,
if ( (supportsRS == eSupportsMaybe) && (mipMapLevel != 0) ) {
// supportsRenderScaleMaybe may have changed, update it
renderFullScaleThenDownscale = true;
- renderMappedScale.x = renderMappedScale.y = 1.;
+ renderMappedScale = RenderScale::identity;
renderMappedMipMapLevel = 0;
}
@@ -838,7 +838,7 @@ EffectInstance::renderRoI(const RenderRoIArgs & args,
if (renderFullScaleThenDownscale) {
renderFullScaleThenDownscale = false;
renderMappedMipMapLevel = args.mipMapLevel;
- renderMappedScale.x = renderMappedScale.y = Image::getScaleFromMipMapLevel(renderMappedMipMapLevel);
+ renderMappedScale = RenderScale::fromMipmapLevel(renderMappedMipMapLevel);
if (frameArgs->tilesSupported) {
roi = args.roi;
if ( !roi.clipIfOverlaps(downscaledImageBoundsNc) ) {
@@ -1864,7 +1864,7 @@ EffectInstance::renderRoIInternal(EffectInstance* self,
}
}
- RenderScale renderMappedScale( Image::getScaleFromMipMapLevel(renderMappedMipMapLevel) );
+ RenderScale renderMappedScale( RenderScale::fromMipmapLevel(renderMappedMipMapLevel) );
RenderingFunctorRetEnum renderStatus = eRenderingFunctorRetOK;
if ( planesToRender->rectsToRender.empty() ) {
retCode = EffectInstance::eRenderRoIStatusImageAlreadyRendered;
diff --git a/Engine/Engine.pro b/Engine/Engine.pro
index 221cb7e25..748d7be8e 100644
--- a/Engine/Engine.pro
+++ b/Engine/Engine.pro
@@ -173,6 +173,7 @@ SOURCES += \
ReadNode.cpp \
RectD.cpp \
RectI.cpp \
+ RenderScale.cpp \
RenderStats.cpp \
RotoContext.cpp \
RotoDrawableItem.cpp \
@@ -343,6 +344,7 @@ HEADERS += \
RectDSerialization.h \
RectI.h \
RectISerialization.h \
+ RenderScale.h \
RenderStats.h \
RotoContext.h \
RotoContextPrivate.h \
diff --git a/Engine/EngineFwd.h b/Engine/EngineFwd.h
index f3a53c1c6..55f1bf6fb 100644
--- a/Engine/EngineFwd.h
+++ b/Engine/EngineFwd.h
@@ -233,6 +233,7 @@ class ProjectSerialization;
class RectD;
class RectI;
class RenderEngine;
+class RenderScale;
class RenderStats;
class RenderingFlagSetter;
class RotoContext;
diff --git a/Engine/Image.cpp b/Engine/Image.cpp
index a56efba90..ce51db876 100644
--- a/Engine/Image.cpp
+++ b/Engine/Image.cpp
@@ -2333,12 +2333,6 @@ Image::buildMipMapLevel(const RectD& dstRoD,
}
} // buildMipMapLevel
-double
-Image::getScaleFromMipMapLevel(unsigned int level)
-{
- return 1. / (1 << level);
-}
-
#ifndef M_LN2
#define M_LN2 0.693147180559945309417232121458176568 /* loge(2) */
#endif
diff --git a/Engine/Image.h b/Engine/Image.h
index 4449f5531..e57aeaf25 100644
--- a/Engine/Image.h
+++ b/Engine/Image.h
@@ -322,11 +322,6 @@ class Image
return this->_params->getMipMapLevel();
}
- double getScale() const
- {
- return getScaleFromMipMapLevel( getMipMapLevel() );
- }
-
unsigned int getComponentsCount() const;
const ImagePlaneDesc& getComponents() const
{
@@ -766,7 +761,6 @@ class Image
void upscaleMipMap(const RectI & roi, unsigned int fromLevel, unsigned int toLevel, Image* output) const;
- static double getScaleFromMipMapLevel(unsigned int level);
static unsigned int getLevelFromScale(double s);
/**
diff --git a/Engine/Node.cpp b/Engine/Node.cpp
index 117aebe80..c69bf50ad 100644
--- a/Engine/Node.cpp
+++ b/Engine/Node.cpp
@@ -1641,12 +1641,11 @@ Node::makeInfoForInput(int inputNumber) const
ss << "" << tr("Frame range:").toStdString() << " " << first << " - " << last << "
";
}
{
- RenderScale scale(1.);
RectD rod;
bool isProjectFormat;
StatusEnum stat = input->getRegionOfDefinition_public(getHashValue(),
time,
- scale, ViewIdx(0), &rod, &isProjectFormat);
+ RenderScale::identity, ViewIdx(0), &rod, &isProjectFormat);
if (stat != eStatusFailed) {
ss << "" << tr("Region of Definition (at t=%1):").arg(time).toStdString() << " ";
ss << tr("left = %1 bottom = %2 right = %3 top = %4").arg(rod.x1).arg(rod.y1).arg(rod.x2).arg(rod.y2).toStdString() << "
";
@@ -3301,7 +3300,6 @@ Node::makePreviewImage(SequenceTime time,
ComputingPreviewSetter_RAII computingPreviewRAII( _imp.get() );
RectD rod;
bool isProjectFormat;
- RenderScale scale(1.);
U64 nodeHash = getHashValue();
EffectInstance* effect = 0;
NodeGroup* isGroup = dynamic_cast( _imp->effect.get() );
@@ -3317,7 +3315,7 @@ Node::makePreviewImage(SequenceTime time,
effect->clearPersistentMessage(false);
- StatusEnum stat = effect->getRegionOfDefinition_public(nodeHash, time, scale, ViewIdx(0), &rod, &isProjectFormat);
+ StatusEnum stat = effect->getRegionOfDefinition_public(nodeHash, time, RenderScale::identity, ViewIdx(0), &rod, &isProjectFormat);
if ( (stat == eStatusFailed) || rod.isNull() ) {
return false;
}
@@ -3329,8 +3327,7 @@ Node::makePreviewImage(SequenceTime time,
int closestPowerOf2 = std::max(closestPowerOf2X, closestPowerOf2Y);
unsigned int mipMapLevel = std::min(std::log( (double)closestPowerOf2 ) / std::log(2.), 5.);
- scale.x = Image::getScaleFromMipMapLevel(mipMapLevel);
- scale.y = scale.x;
+ const RenderScale scale = RenderScale::fromMipmapLevel(mipMapLevel);
const double par = effect->getAspectRatio(-1);
const RectI renderWindow = rod.toPixelEnclosing(mipMapLevel, par);
@@ -4811,7 +4808,6 @@ Node::onRefreshIdentityStateRequestReceived()
ProjectPtr project = getApp()->getProject();
double time = project->currentFrame();
- RenderScale scale(1.);
double inputTime = 0;
U64 hash = getHashValue();
bool viewAware = _imp->effect->isViewAware();
@@ -4834,7 +4830,7 @@ Node::onRefreshIdentityStateRequestReceived()
for (int i = 0; i < nViews; ++i) {
int identityInputNb = -1;
ViewIdx identityView;
- bool isViewIdentity = _imp->effect->isIdentity_public(true, hash, time, scale, frmt, ViewIdx(i), &inputTime, &identityView, &identityInputNb);
+ bool isViewIdentity = _imp->effect->isIdentity_public(true, hash, time, RenderScale::identity, frmt, ViewIdx(i), &inputTime, &identityView, &identityInputNb);
if ( (i > 0) && ( (isViewIdentity != isIdentity) || (identityInputNb != inputNb) || (identityView.value() != i) ) ) {
isIdentity = false;
inputNb = -1;
@@ -5167,7 +5163,6 @@ Node::Implementation::onLayerChanged(int inputNb,
}
if (!isRefreshingInputRelatedData) {
///Clip preferences have changed
- RenderScale s(1.);
effect->refreshMetadata_public(true);
}
if ( !enabledChan[0].lock() ) {
@@ -5273,7 +5268,6 @@ Node::Implementation::onMaskSelectorChanged(int inputNb,
if (!isRefreshingInputRelatedData) {
///Clip preferences have changed
- RenderScale s(1.);
effect->refreshMetadata_public(true);
}
}
@@ -5819,7 +5813,6 @@ addIdentityNodesRecursively(const Node* caller,
/*
Very unlikely that there's no request pass. But we still check
*/
- RenderScale scale(1.);
double inputTimeId;
ViewIdx identityView;
int inputNbId;
@@ -5829,7 +5822,7 @@ addIdentityNodesRecursively(const Node* caller,
RectI format = node->getEffectInstance()->getOutputFormat();
- isIdentity = node->getEffectInstance()->isIdentity_public(true, renderHash, time, scale, format, view, &inputTimeId, &identityView, &inputNbId);
+ isIdentity = node->getEffectInstance()->isIdentity_public(true, renderHash, time, RenderScale::identity, format, view, &inputTimeId, &identityView, &inputNbId);
}
@@ -6111,14 +6104,12 @@ Node::refreshAllInputRelatedData(bool /*canChangeValues*/,
}
double time = (double)getApp()->getTimeLine()->currentFrame();
- RenderScale scaleOne(1.);
///Render scale support might not have been set already because getRegionOfDefinition could have failed until all non optional inputs were connected
if (_imp->effect->supportsRenderScaleMaybe() == EffectInstance::eSupportsMaybe) {
RectD rod;
- StatusEnum stat = _imp->effect->getRegionOfDefinition(getHashValue(), time, scaleOne, ViewIdx(0), &rod);
+ StatusEnum stat = _imp->effect->getRegionOfDefinition(getHashValue(), time, RenderScale::identity, ViewIdx(0), &rod);
if (stat != eStatusFailed) {
- RenderScale scale(0.5);
- stat = _imp->effect->getRegionOfDefinition(getHashValue(), time, scale, ViewIdx(0), &rod);
+ stat = _imp->effect->getRegionOfDefinition(getHashValue(), time, RenderScale::fromMipmapLevel(1), ViewIdx(0), &rod);
if (stat != eStatusFailed) {
_imp->effect->setSupportsRenderScaleMaybe(EffectInstance::eSupportsYes);
} else {
@@ -7262,7 +7253,6 @@ Node::addUserComponents(const ImagePlaneDesc& comps)
}
if (!_imp->isRefreshingInputRelatedData) {
///Clip preferences have changed
- RenderScale s(1.);
getEffectInstance()->refreshMetadata_public(true);
}
{
diff --git a/Engine/NodeInputs.cpp b/Engine/NodeInputs.cpp
index 1be52f2e6..7af97bcf1 100644
--- a/Engine/NodeInputs.cpp
+++ b/Engine/NodeInputs.cpp
@@ -627,12 +627,11 @@ checkCanConnectNoMultiRes(const Node* output,
{
//http://openfx.sourceforge.net/Documentation/1.3/ofxProgrammingReference.html#kOfxImageEffectPropSupportsMultiResolution
//Check that the input has the same RoD that another input and that its rod is set to 0,0
- RenderScale scale(1.);
RectD rod;
bool isProjectFormat;
StatusEnum stat = input->getEffectInstance()->getRegionOfDefinition_public(input->getHashValue(),
output->getApp()->getTimeLine()->currentFrame(),
- scale,
+ RenderScale::identity,
ViewIdx(0),
&rod, &isProjectFormat);
@@ -660,7 +659,7 @@ checkCanConnectNoMultiRes(const Node* output,
RectD inputRod;
stat = inputNode->getEffectInstance()->getRegionOfDefinition_public(inputNode->getHashValue(),
output->getApp()->getTimeLine()->currentFrame(),
- scale,
+ RenderScale::identity,
ViewIdx(0),
&inputRod, &isProjectFormat);
if ( (stat == eStatusFailed) && !inputRod.isNull() ) {
diff --git a/Engine/OfxClipInstance.cpp b/Engine/OfxClipInstance.cpp
index a266a1b9b..3062fbb4a 100644
--- a/Engine/OfxClipInstance.cpp
+++ b/Engine/OfxClipInstance.cpp
@@ -601,7 +601,7 @@ OfxClipInstance::getRegionOfDefinitionInternal(OfxTime time,
bool isProjectFormat;
U64 nodeHash = associatedNode->getRenderHash();
RectD rod;
- RenderScale scale( Image::getScaleFromMipMapLevel(mipmapLevel) );
+ const RenderScale scale = RenderScale::fromMipmapLevel(mipmapLevel);
StatusEnum st = associatedNode->getRegionOfDefinition_public(nodeHash, time, scale, view, &rod, &isProjectFormat);
if (st == eStatusFailed) {
ret->x1 = 0.;
@@ -971,7 +971,7 @@ OfxClipInstance::getInputImageInternal(const OfxTime time,
}
- RenderScale renderScale( Image::getScaleFromMipMapLevel(mipMapLevel) );
+ const RenderScale renderScale = RenderScale::fromMipmapLevel(mipMapLevel);
RectD bounds;
if (optionalBounds) {
bounds.x1 = optionalBounds->x1;
@@ -1368,8 +1368,8 @@ OfxImageCommon::OfxImageCommon(OFX::Host::ImageEffect::ImageBase* ofxImageBase,
assert(internalImage);
- unsigned int mipMapLevel = internalImage->getMipMapLevel();
- RenderScale scale( NATRON_NAMESPACE::Image::getScaleFromMipMapLevel(mipMapLevel) );
+ const unsigned int mipMapLevel = internalImage->getMipMapLevel();
+ const OfxPointD scale = RenderScale::fromMipmapLevel(mipMapLevel).toOfxPointD();
ofxImageBase->setDoubleProperty(kOfxImageEffectPropRenderScale, scale.x, 0);
ofxImageBase->setDoubleProperty(kOfxImageEffectPropRenderScale, scale.y, 1);
diff --git a/Engine/OfxEffectInstance.cpp b/Engine/OfxEffectInstance.cpp
index 2b36ae9d8..2c786c538 100644
--- a/Engine/OfxEffectInstance.cpp
+++ b/Engine/OfxEffectInstance.cpp
@@ -694,9 +694,6 @@ OfxEffectInstance::tryInitializeOverlayInteracts()
OfxPluginEntryPoint *overlayEntryPoint = _imp->effect->getOverlayInteractMainEntry();
if (overlayEntryPoint) {
_imp->overlayInteract.reset( new OfxOverlayInteract(*_imp->effect, 8, true) );
- double sx, sy;
- effectInstance()->getRenderScaleRecursive(sx, sy);
- RenderScale s(sx, sy);
{
ClipsThreadStorageSetter clipSetter(effectInstance(),
@@ -1209,7 +1206,7 @@ OfxEffectInstance::onInputChanged(int inputNo)
OfxClipInstance* clip = getClipCorrespondingToInput(inputNo);
assert(clip);
double time = getApp()->getTimeLine()->currentFrame();
- RenderScale s(1.);
+ const OfxPointD scale = {1., 1.};
{
@@ -1222,7 +1219,7 @@ OfxEffectInstance::onInputChanged(int inputNo)
assert(_imp->effect);
_imp->effect->beginInstanceChangedAction(kOfxChangeUserEdited);
- _imp->effect->clipInstanceChangedAction(clip->getName(), kOfxChangeUserEdited, time, s);
+ _imp->effect->clipInstanceChangedAction(clip->getName(), kOfxChangeUserEdited, time, scale);
_imp->effect->endInstanceChangedAction(kOfxChangeUserEdited);
}
}
@@ -1397,12 +1394,12 @@ OfxEffectInstance::getRegionOfDefinition(U64 /*hash*/,
assert(_imp->effect);
- unsigned int mipMapLevel = Image::getLevelFromScale(scale.x);
+ unsigned int mipMapLevel = scale.toMipmapLevel();
// getRegionOfDefinition may be the first action with renderscale called on any effect.
// it may have to check for render scale support.
SupportsEnum supportsRS = supportsRenderScaleMaybe();
- bool scaleIsOne = (scale.x == 1. && scale.y == 1.);
+ bool scaleIsOne = scale == RenderScale::identity;
if ( (supportsRS == eSupportsNo) && !scaleIsOne ) {
qDebug() << "getRegionOfDefinition called with render scale != 1, but effect does not support render scale!";
@@ -1419,11 +1416,11 @@ OfxEffectInstance::getRegionOfDefinition(U64 /*hash*/,
assert(_imp->effect);
if (getRecursionLevel() > 1) {
- stat = _imp->effect->getRegionOfDefinitionAction(time, scale, view, ofxRod);
+ stat = _imp->effect->getRegionOfDefinitionAction(time, scale.toOfxPointD(), view, ofxRod);
} else {
///Take the preferences lock so that it cannot be modified throughout the action.
QReadLocker preferencesLocker(&_imp->preferencesLock);
- stat = _imp->effect->getRegionOfDefinitionAction(time, scale, view, ofxRod);
+ stat = _imp->effect->getRegionOfDefinitionAction(time, scale.toOfxPointD(), view, ofxRod);
}
if (supportsRS == eSupportsMaybe) {
OfxRectD tmpRod;
@@ -1537,7 +1534,7 @@ OfxEffectInstance::calcDefaultRegionOfDefinition(U64 /*hash*/,
throw std::runtime_error("OfxEffectInstance not initialized");
}
- unsigned int mipMapLevel = Image::getLevelFromScale(scale.x);
+ unsigned int mipMapLevel = scale.toMipmapLevel();
OfxRectD ofxRod;
{
@@ -1560,9 +1557,9 @@ OfxEffectInstance::calcDefaultRegionOfDefinition(U64 /*hash*/,
// the following ofxh function does the job
QReadLocker preferencesLocker(&_imp->preferencesLock);
- ofxRod = _imp->effect->calcDefaultRegionOfDefinition(time, scale, view);
+ ofxRod = _imp->effect->calcDefaultRegionOfDefinition(time, scale.toOfxPointD(), view);
} else {
- ofxRod = _imp->effect->calcDefaultRegionOfDefinition(time, scale, view);
+ ofxRod = _imp->effect->calcDefaultRegionOfDefinition(time, scale.toOfxPointD(), view);
}
}
rod->x1 = ofxRod.x1;
@@ -1603,7 +1600,7 @@ OfxEffectInstance::getRegionsOfInterest(double time,
OfxStatus stat;
///before calling getRoIaction set the relevant info on the clips
- unsigned int mipMapLevel = Image::getLevelFromScale(scale.x);
+ unsigned int mipMapLevel = scale.toMipmapLevel();
{
SET_CAN_SET_VALUE(false);
@@ -1616,7 +1613,7 @@ OfxEffectInstance::getRegionsOfInterest(double time,
///Take the preferences lock so that it cannot be modified throughout the action.
QReadLocker preferencesLocker(&_imp->preferencesLock);
assert(_imp->effect);
- stat = _imp->effect->getRegionOfInterestAction( (OfxTime)time, scale, view,
+ stat = _imp->effect->getRegionOfInterestAction( (OfxTime)time, scale.toOfxPointD(), view,
roi, inputRois );
}
@@ -1834,7 +1831,7 @@ OfxEffectInstance::isIdentity(double time,
throw std::logic_error("isIdentity called with an unsupported RenderScale");
}
- unsigned int mipMapLevel = Image::getLevelFromScale(scale.x);
+ unsigned int mipMapLevel = scale.toMipmapLevel();
OfxStatus stat;
{
@@ -1855,11 +1852,11 @@ OfxEffectInstance::isIdentity(double time,
int identityView = view;
string identityPlane = kFnOfxImagePlaneColour;
if (getRecursionLevel() > 1) {
- stat = _imp->effect->isIdentityAction(inputTimeOfx, field, ofxRoI, scale, identityView, identityPlane, inputclip);
+ stat = _imp->effect->isIdentityAction(inputTimeOfx, field, ofxRoI, scale.toOfxPointD(), identityView, identityPlane, inputclip);
} else {
///Take the preferences lock so that it cannot be modified throughout the action.
QReadLocker preferencesLocker(&_imp->preferencesLock);
- stat = _imp->effect->isIdentityAction(inputTimeOfx, field, ofxRoI, scale, identityView, identityPlane, inputclip);
+ stat = _imp->effect->isIdentityAction(inputTimeOfx, field, ofxRoI, scale.toOfxPointD(), identityView, identityPlane, inputclip);
}
if (identityView != view || identityPlane != kFnOfxImagePlaneColour) {
//#pragma message WARN("can Natron RB2-multiplane2 handle isIdentity across views and planes?")
@@ -1946,7 +1943,7 @@ OfxEffectInstance::beginSequenceRender(double first,
assert(isSupportedRenderScale(supportsRenderScaleMaybe(), scale));
OfxStatus stat;
- unsigned int mipMapLevel = Image::getLevelFromScale(scale.x);
+ unsigned int mipMapLevel = scale.toMipmapLevel();
{
ClipsThreadStorageSetter clipSetter(effectInstance(),
view,
@@ -1960,7 +1957,7 @@ OfxEffectInstance::beginSequenceRender(double first,
///Take the preferences lock so that it cannot be modified throughout the action.
QReadLocker preferencesLocker(&_imp->preferencesLock);
stat = effectInstance()->beginRenderAction(first, last, step,
- interactive, scale,
+ interactive, scale.toOfxPointD(),
isSequentialRender, isRenderResponseToUserInteraction,
isOpenGLRender, oglData, draftMode, view);
}
@@ -1988,7 +1985,7 @@ OfxEffectInstance::endSequenceRender(double first,
assert(isSupportedRenderScale(supportsRenderScaleMaybe(), scale));
OfxStatus stat;
- unsigned int mipMapLevel = Image::getLevelFromScale(scale.x);
+ unsigned int mipMapLevel = scale.toMipmapLevel();
{
ClipsThreadStorageSetter clipSetter(effectInstance(),
view,
@@ -2001,7 +1998,7 @@ OfxEffectInstance::endSequenceRender(double first,
///Take the preferences lock so that it cannot be modified throughout the action.
QReadLocker preferencesLocker(&_imp->preferencesLock);
stat = effectInstance()->endRenderAction(first, last, step,
- interactive, scale,
+ interactive, scale.toOfxPointD(),
isSequentialRender, isRenderResponseToUserInteraction,
isOpenGLRender, oglData, draftMode, view);
}
@@ -2078,7 +2075,7 @@ OfxEffectInstance::render(const RenderActionArgs& args)
RenderThreadStorageSetter clipSetter(effectInstance(),
args.view,
- Image::getLevelFromScale(args.originalScale.x),
+ args.originalScale.toMipmapLevel(),
firstPlane.first,
args.inputImages);
OfxGLContextEffectData* isOfxGLData = dynamic_cast( args.glContextData.get() );
@@ -2089,7 +2086,7 @@ OfxEffectInstance::render(const RenderActionArgs& args)
stat = _imp->effect->renderAction( (OfxTime)args.time,
field,
ofxRoI,
- args.mappedScale,
+ args.mappedScale.toOfxPointD(),
args.isSequentialRender,
args.isRenderResponseToUserInteraction,
args.useOpenGL,
@@ -2203,7 +2200,7 @@ OfxEffectInstance::drawOverlay(double time,
}
if (_imp->overlayInteract) {
SET_CAN_SET_VALUE(false);
- _imp->overlayInteract->drawAction(time, renderScale, view, _imp->overlayInteract->hasColorPicker() ? &_imp->overlayInteract->getLastColorPickerColor() : /*colourPicker=*/0);
+ _imp->overlayInteract->drawAction(time, renderScale.toOfxPointD(), view, _imp->overlayInteract->hasColorPicker() ? &_imp->overlayInteract->getLastColorPickerColor() : /*colourPicker=*/0);
}
}
@@ -2238,7 +2235,7 @@ OfxEffectInstance::onOverlayPenDown(double time,
SET_CAN_SET_VALUE(true);
- OfxStatus stat = _imp->overlayInteract->penDownAction(time, renderScale, view, _imp->overlayInteract->hasColorPicker() ? &_imp->overlayInteract->getLastColorPickerColor() : /*colourPicker=*/0, penPos, penPosViewport, pressure);
+ OfxStatus stat = _imp->overlayInteract->penDownAction(time, renderScale.toOfxPointD(), view, _imp->overlayInteract->hasColorPicker() ? &_imp->overlayInteract->getLastColorPickerColor() : /*colourPicker=*/0, penPos, penPosViewport, pressure);
if ( (getRecursionLevel() == 1) && checkIfOverlayRedrawNeeded() ) {
@@ -2279,7 +2276,7 @@ OfxEffectInstance::onOverlayPenMotion(double time,
OfxStatus stat;
SET_CAN_SET_VALUE(true);
- stat = _imp->overlayInteract->penMotionAction(time, renderScale, view, _imp->overlayInteract->hasColorPicker() ? &_imp->overlayInteract->getLastColorPickerColor() : /*colourPicker=*/0, penPos, penPosViewport, pressure);
+ stat = _imp->overlayInteract->penMotionAction(time, renderScale.toOfxPointD(), view, _imp->overlayInteract->hasColorPicker() ? &_imp->overlayInteract->getLastColorPickerColor() : /*colourPicker=*/0, penPos, penPosViewport, pressure);
if ( (getRecursionLevel() == 1) && checkIfOverlayRedrawNeeded() ) {
stat = _imp->overlayInteract->redraw();
@@ -2315,7 +2312,7 @@ OfxEffectInstance::onOverlayPenUp(double time,
penPosViewport.y = viewportPos.y();
SET_CAN_SET_VALUE(true);
- OfxStatus stat = _imp->overlayInteract->penUpAction(time, renderScale, view, _imp->overlayInteract->hasColorPicker() ? &_imp->overlayInteract->getLastColorPickerColor() : /*colourPicker=*/0, penPos, penPosViewport, pressure);
+ OfxStatus stat = _imp->overlayInteract->penUpAction(time, renderScale.toOfxPointD(), view, _imp->overlayInteract->hasColorPicker() ? &_imp->overlayInteract->getLastColorPickerColor() : /*colourPicker=*/0, penPos, penPosViewport, pressure);
if ( (getRecursionLevel() == 1) && checkIfOverlayRedrawNeeded() ) {
stat = _imp->overlayInteract->redraw();
@@ -2345,7 +2342,7 @@ OfxEffectInstance::onOverlayKeyDown(double time,
if (_imp->overlayInteract) {
QByteArray keyStr;
SET_CAN_SET_VALUE(true);
- OfxStatus stat = _imp->overlayInteract->keyDownAction( time, renderScale, view,_imp->overlayInteract->hasColorPicker() ? &_imp->overlayInteract->getLastColorPickerColor() : /*colourPicker=*/0, (int)key, keyStr.data() );
+ OfxStatus stat = _imp->overlayInteract->keyDownAction( time, renderScale.toOfxPointD(), view,_imp->overlayInteract->hasColorPicker() ? &_imp->overlayInteract->getLastColorPickerColor() : /*colourPicker=*/0, (int)key, keyStr.data() );
if ( (getRecursionLevel() == 1) && checkIfOverlayRedrawNeeded() ) {
stat = _imp->overlayInteract->redraw();
@@ -2373,7 +2370,7 @@ OfxEffectInstance::onOverlayKeyUp(double time,
if (_imp->overlayInteract) {
QByteArray keyStr;
SET_CAN_SET_VALUE(true);
- OfxStatus stat = _imp->overlayInteract->keyUpAction( time, renderScale, view, _imp->overlayInteract->hasColorPicker() ? &_imp->overlayInteract->getLastColorPickerColor() : /*colourPicker=*/0, (int)key, keyStr.data() );
+ OfxStatus stat = _imp->overlayInteract->keyUpAction( time, renderScale.toOfxPointD(), view, _imp->overlayInteract->hasColorPicker() ? &_imp->overlayInteract->getLastColorPickerColor() : /*colourPicker=*/0, (int)key, keyStr.data() );
if ( (getRecursionLevel() == 1) && checkIfOverlayRedrawNeeded() ) {
stat = _imp->overlayInteract->redraw();
@@ -2404,7 +2401,7 @@ OfxEffectInstance::onOverlayKeyRepeat(double time,
QByteArray keyStr;
SET_CAN_SET_VALUE(true);
- OfxStatus stat = _imp->overlayInteract->keyRepeatAction( time, renderScale, view, _imp->overlayInteract->hasColorPicker() ? &_imp->overlayInteract->getLastColorPickerColor() : /*colourPicker=*/0, (int)key, keyStr.data() );
+ OfxStatus stat = _imp->overlayInteract->keyRepeatAction( time, renderScale.toOfxPointD(), view, _imp->overlayInteract->hasColorPicker() ? &_imp->overlayInteract->getLastColorPickerColor() : /*colourPicker=*/0, (int)key, keyStr.data() );
if ( (getRecursionLevel() == 1) && checkIfOverlayRedrawNeeded() ) {
stat = _imp->overlayInteract->redraw();
@@ -2430,7 +2427,7 @@ OfxEffectInstance::onOverlayFocusGained(double time,
if (_imp->overlayInteract) {
OfxStatus stat;
SET_CAN_SET_VALUE(true);
- stat = _imp->overlayInteract->gainFocusAction(time, renderScale, view, _imp->overlayInteract->hasColorPicker() ? &_imp->overlayInteract->getLastColorPickerColor() : /*colourPicker=*/0);
+ stat = _imp->overlayInteract->gainFocusAction(time, renderScale.toOfxPointD(), view, _imp->overlayInteract->hasColorPicker() ? &_imp->overlayInteract->getLastColorPickerColor() : /*colourPicker=*/0);
if (stat == kOfxStatOK) {
return true;
}
@@ -2450,7 +2447,7 @@ OfxEffectInstance::onOverlayFocusLost(double time,
if (_imp->overlayInteract) {
OfxStatus stat;
SET_CAN_SET_VALUE(true);
- stat = _imp->overlayInteract->loseFocusAction(time, renderScale, view, _imp->overlayInteract->hasColorPicker() ? &_imp->overlayInteract->getLastColorPickerColor() : /*colourPicker=*/0);
+ stat = _imp->overlayInteract->loseFocusAction(time, renderScale.toOfxPointD(), view, _imp->overlayInteract->hasColorPicker() ? &_imp->overlayInteract->getLastColorPickerColor() : /*colourPicker=*/0);
if (stat == kOfxStatOK) {
return true;
}
@@ -2606,19 +2603,19 @@ OfxEffectInstance::knobChanged(KnobI* k,
ViewIdx v = ( view.isAll() || view.isCurrent() ) ? ViewIdx(0) : ViewIdx(view);
ClipsThreadStorageSetter clipSetter( effect,
v,
- Image::getLevelFromScale(renderScale.x) );
+ renderScale.toMipmapLevel() );
///This action as all the overlay interacts actions can trigger recursive actions, such as
///getClipPreferences() so we don't take the clips preferences lock for read here otherwise we would
///create a deadlock. This code then assumes that the instance changed action of the plug-in doesn't require
///the clip preferences to stay the same throughout the action.
- stat = effect->paramInstanceChangedAction(k->getOriginalName(), ofxReason, (OfxTime)time, renderScale);
+ stat = effect->paramInstanceChangedAction(k->getOriginalName(), ofxReason, (OfxTime)time, renderScale.toOfxPointD());
} else {
///This action as all the overlay interacts actions can trigger recursive actions, such as
///getClipPreferences() so we don't take the clips preferences lock for read here otherwise we would
///create a deadlock. This code then assumes that the instance changed action of the plug-in doesn't require
///the clip preferences to stay the same throughout the action.
- stat = effect->paramInstanceChangedAction(k->getOriginalName(), ofxReason, (OfxTime)time, renderScale);
+ stat = effect->paramInstanceChangedAction(k->getOriginalName(), ofxReason, (OfxTime)time, renderScale.toOfxPointD());
}
if ( (stat != kOfxStatOK) && (stat != kOfxStatReplyDefault) ) {
@@ -2994,10 +2991,10 @@ OfxEffectInstance::getTransform(double time,
ClipsThreadStorageSetter clipSetter( effectInstance(),
view,
- Image::getLevelFromScale(renderScale.x) );
+ renderScale.toMipmapLevel() );
try {
- stat = effectInstance()->getTransformAction( (OfxTime)time, field, renderScale, draftRender, view, clipName, tmpTransform );
+ stat = effectInstance()->getTransformAction( (OfxTime)time, field, renderScale.toOfxPointD(), draftRender, view, clipName, tmpTransform );
} catch (...) {
return eStatusFailed;
}
diff --git a/Engine/OfxImageEffectInstance.cpp b/Engine/OfxImageEffectInstance.cpp
index 3e78fe085..e73ed6d14 100644
--- a/Engine/OfxImageEffectInstance.cpp
+++ b/Engine/OfxImageEffectInstance.cpp
@@ -442,9 +442,10 @@ OfxImageEffectInstance::getRenderScaleRecursive(double &x,
///get the render scale of the 1st viewer
if ( !attachedViewers.empty() ) {
ViewerInstance* first = attachedViewers.front();
- int mipMapLevel = first->getMipMapLevel();
- x = Image::getScaleFromMipMapLevel( (unsigned int)mipMapLevel );
- y = x;
+ int mipmapLevel = first->getMipMapLevel();
+ const auto scale = RenderScale::fromMipmapLevel((unsigned int)mipmapLevel).toOfxPointD();
+ x = scale.x;
+ y = scale.y;
} else {
x = 1.;
y = 1.;
diff --git a/Engine/OutputSchedulerThread.cpp b/Engine/OutputSchedulerThread.cpp
index c1dee7c0a..49d7910bc 100644
--- a/Engine/OutputSchedulerThread.cpp
+++ b/Engine/OutputSchedulerThread.cpp
@@ -1085,11 +1085,10 @@ OutputSchedulerThread::startRender()
}
SequentialPreferenceEnum pref = effect->getSequentialPreference();
if ( (pref == eSequentialPreferenceOnlySequential) || (pref == eSequentialPreferencePreferSequential) ) {
- RenderScale scaleOne(1.);
if (effect->beginSequenceRender_public( firstFrame, lastFrame,
frameStep,
false,
- scaleOne, true,
+ RenderScale::identity, true,
true,
false,
ViewIdx(0),
@@ -1176,11 +1175,10 @@ OutputSchedulerThread::stopRender()
firstFrame = args->firstFrame;
lastFrame = args->lastFrame;
- RenderScale scaleOne(1.);
ignore_result( effect->endSequenceRender_public( firstFrame, lastFrame,
1,
!appPTR->isBackground(),
- scaleOne, true,
+ RenderScale::identity, true,
!appPTR->isBackground(),
false,
ViewIdx(0),
@@ -2245,8 +2243,8 @@ class DefaultRenderFrameRunnable
try {
////Writers always render at scale 1.
- int mipMapLevel = 0;
- RenderScale scale(1.);
+ const int mipmapLevel = 0;
+ const RenderScale scale = RenderScale::fromMipmapLevel(mipmapLevel);
RectD rod;
bool isProjectFormat;
@@ -2323,7 +2321,7 @@ class DefaultRenderFrameRunnable
{
FrameRequestMap request;
- stat = EffectInstance::computeRequestPass(time, viewsToRender[view], mipMapLevel, rod, activeInputNode, request);
+ stat = EffectInstance::computeRequestPass(time, viewsToRender[view], mipmapLevel, rod, activeInputNode, request);
if (stat == eStatusFailed) {
_imp->scheduler->notifyRenderFailure("Error caught while rendering");
@@ -2335,7 +2333,7 @@ class DefaultRenderFrameRunnable
std::map planes;
std::unique_ptr renderArgs( new EffectInstance::RenderRoIArgs(time, //< the time at which to render
scale, //< the scale at which to render
- mipMapLevel, //< the mipmap level (redundant with the scale)
+ mipmapLevel, //< the mipmap level (redundant with the scale)
viewsToRender[view], //< the view to render
false,
renderWindow, //< the region of interest (in pixel coordinates)
@@ -2406,8 +2404,6 @@ DefaultScheduler::processFrame(const BufferedFrames& frames)
//Only consider the first frame, we shouldn't have multiple view here anyway.
const BufferedFrame& frame = frames.front();
- ///Writers render to scale 1 always
- RenderScale scale(1.);
OutputEffectInstancePtr effect = _effect.lock();
U64 hash = effect->getHash();
bool isProjectFormat;
@@ -2444,6 +2440,8 @@ DefaultScheduler::processFrame(const BufferedFrames& frames)
false,
it->stats);
RectD rod;
+ ///Writers render to scale 1 always
+ const RenderScale scale;
ignore_result( effect->getRegionOfDefinition_public(hash, it->time, scale, it->view, &rod, &isProjectFormat) );
const RectI roi = rod.toPixelEnclosing(0, par);
diff --git a/Engine/ParallelRenderArgs.cpp b/Engine/ParallelRenderArgs.cpp
index 8043e7ede..4d3f062c4 100644
--- a/Engine/ParallelRenderArgs.cpp
+++ b/Engine/ParallelRenderArgs.cpp
@@ -246,9 +246,6 @@ EffectInstance::treeRecurseFunctor(bool isRenderFunctor,
///Do not count frames pre-fetched in RoI functor mode, it is harmless and may
///limit calculations that will be done later on anyway.
} else {
- RenderScale scaleOne(1.);
- RenderScale scale( Image::getScaleFromMipMapLevel(originalMipMapLevel) );
-
///Render the input image with the bit depth of its preference
ImageBitDepthEnum inputPrefDepth = inputEffect->getBitDepth(-1);
@@ -261,7 +258,7 @@ EffectInstance::treeRecurseFunctor(bool isRenderFunctor,
}
const unsigned int upstreamMipMapLevel = useScaleOneInputs ? 0 : originalMipMapLevel;
- const RenderScale & upstreamScale = useScaleOneInputs ? scaleOne : scale;
+ const RenderScale upstreamScale = useScaleOneInputs ? RenderScale::identity : RenderScale::fromMipmapLevel(originalMipMapLevel);
const RectI inputRoIPixelCoords = roi.toPixelEnclosing(upstreamMipMapLevel, inputPar);
std::map inputImgs;
@@ -344,7 +341,7 @@ EffectInstance::getInputsRoIsFunctor(bool useTransforms,
///Setup global data for the node for the whole frame render
NodeFrameRequestPtr tmp = std::make_shared();
- tmp->mappedScale.x = tmp->mappedScale.y = Image::getScaleFromMipMapLevel(mappedLevel);
+ tmp->mappedScale = RenderScale::fromMipmapLevel(mappedLevel);
tmp->nodeHash = effect->getRenderHash();
std::pair ret = requests.insert( std::make_pair(node, tmp) );
diff --git a/Engine/ParallelRenderArgs.h b/Engine/ParallelRenderArgs.h
index 04881cc4a..ca75b53df 100644
--- a/Engine/ParallelRenderArgs.h
+++ b/Engine/ParallelRenderArgs.h
@@ -35,6 +35,7 @@
#include "Global/GlobalDefines.h"
#include "Engine/RectD.h"
+#include "Engine/RenderScale.h"
#include "Engine/ViewIdx.h"
#include "Engine/EngineFwd.h"
diff --git a/Engine/PyNode.cpp b/Engine/PyNode.cpp
index f1071c1cf..3b84c3c47 100644
--- a/Engine/PyNode.cpp
+++ b/Engine/PyNode.cpp
@@ -967,9 +967,8 @@ Effect::getRegionOfDefinition(double time,
return rod;
}
U64 hash = getInternalNode()->getHashValue();
- RenderScale s(1.);
bool isProject;
- StatusEnum stat = getInternalNode()->getEffectInstance()->getRegionOfDefinition_public(hash, time, s, ViewIdx(view), &rod, &isProject);
+ StatusEnum stat = getInternalNode()->getEffectInstance()->getRegionOfDefinition_public(hash, time, RenderScale::identity, ViewIdx(view), &rod, &isProject);
if (stat != eStatusOK) {
return RectD();
}
diff --git a/Engine/RectD.cpp b/Engine/RectD.cpp
index 5d8e67c0a..1a2666123 100644
--- a/Engine/RectD.cpp
+++ b/Engine/RectD.cpp
@@ -30,17 +30,15 @@
#include
#include "Engine/RectI.h"
+#include "Engine/RenderScale.h"
NATRON_NAMESPACE_ENTER
RectI
-RectD::toPixelEnclosing(const RenderScale& scale,
+RectD::toPixelEnclosing(const RenderScale& renderScale,
double par) const
{
- return RectI(std::floor(x1 * scale.x / par),
- std::floor(y1 * scale.y),
- std::ceil(x2 * scale.x / par),
- std::ceil(y2 * scale.y));
+ return toPixelEnclosing(renderScale.toMipmapLevel(), par);
}
RectI
diff --git a/Engine/RenderScale.cpp b/Engine/RenderScale.cpp
new file mode 100644
index 000000000..6b5fea992
--- /dev/null
+++ b/Engine/RenderScale.cpp
@@ -0,0 +1,31 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * This file is part of Natron ,
+ * (C) 2018-2023 The Natron developers
+ * (C) 2013-2018 INRIA and Alexandre Gauthier-Foichat
+ *
+ * Natron is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Natron is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Natron. If not, see
+ * ***** END LICENSE BLOCK ***** */
+
+#include "RenderScale.h"
+
+#include "Global/Macros.h"
+
+#include "Engine/Image.h"
+
+NATRON_NAMESPACE_ENTER
+
+// static
+const RenderScale RenderScale::identity;
+
+NATRON_NAMESPACE_EXIT
diff --git a/Engine/RenderScale.h b/Engine/RenderScale.h
new file mode 100644
index 000000000..3a09eb8c6
--- /dev/null
+++ b/Engine/RenderScale.h
@@ -0,0 +1,60 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * This file is part of Natron ,
+ * (C) 2018-2023 The Natron developers
+ * (C) 2013-2018 INRIA and Alexandre Gauthier-Foichat
+ *
+ * Natron is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Natron is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Natron. If not, see
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef RENDERSCALE_H
+#define RENDERSCALE_H
+
+#include
+
+#include "Global/Macros.h"
+
+#include "ofxCore.h"
+
+NATRON_NAMESPACE_ENTER
+
+class RenderScale {
+public:
+ // Default constructed object has x & y scale set to 1.
+ constexpr RenderScale() = default;
+
+ // Named constant where x & y scale are both 1. (i.e the identity scale factor in both directions.)
+ static const RenderScale identity;
+
+ bool operator==(const RenderScale& rhs) const { return mipmapLevel == rhs.mipmapLevel; }
+ bool operator!=(const RenderScale& rhs) const { return !(*this == rhs); }
+
+ OfxPointD toOfxPointD() const
+ {
+ assert(mipmapLevel < 8 * sizeof(mipmapLevel));
+ const double scale = 1. / (1 << mipmapLevel);
+ return { scale, scale };
+ }
+
+ static RenderScale fromMipmapLevel(unsigned int mipmapLevel) { return RenderScale(mipmapLevel); }
+ unsigned int toMipmapLevel() const { return mipmapLevel; }
+
+private:
+ RenderScale(unsigned int mipmapLevel_) : mipmapLevel(mipmapLevel_) {}
+
+ unsigned int mipmapLevel = 0;
+};
+
+NATRON_NAMESPACE_EXIT
+
+#endif // RENDERSCALE_H
diff --git a/Engine/RotoPaint.cpp b/Engine/RotoPaint.cpp
index 7879edd99..c51e40c8c 100644
--- a/Engine/RotoPaint.cpp
+++ b/Engine/RotoPaint.cpp
@@ -1531,7 +1531,7 @@ RotoPaint::render(const RenderActionArgs& args)
copyChannels[i] = _imp->enabledKnobs[i].lock()->getValue();
}
- unsigned int mipMapLevel = Image::getLevelFromScale(args.mappedScale.x);
+ unsigned int mipMapLevel = args.mappedScale.toMipmapLevel();
RenderRoIArgs rotoPaintArgs(args.time,
args.mappedScale,
mipMapLevel,
diff --git a/Engine/RotoSmear.cpp b/Engine/RotoSmear.cpp
index 32e90791f..400730a88 100644
--- a/Engine/RotoSmear.cpp
+++ b/Engine/RotoSmear.cpp
@@ -213,7 +213,7 @@ RotoSmear::render(const RenderActionArgs& args)
assert(context);
bool duringPainting = isDuringPaintStrokeCreationThreadLocal();
- unsigned int mipmapLevel = Image::getLevelFromScale(args.originalScale.x);
+ unsigned int mipmapLevel = args.originalScale.toMipmapLevel();
std::list > > strokes;
int strokeIndex;
node->getLastPaintStrokePoints(args.time, mipmapLevel, &strokes, &strokeIndex);
diff --git a/Engine/TrackMarker.cpp b/Engine/TrackMarker.cpp
index 6f3a946e7..eb98dcd13 100644
--- a/Engine/TrackMarker.cpp
+++ b/Engine/TrackMarker.cpp
@@ -743,11 +743,9 @@ TrackMarker::resetCenter()
NodePtr input = context->getNode()->getInput(0);
if (input) {
SequenceTime time = input->getApp()->getTimeLine()->currentFrame();
- RenderScale scale;
- scale.x = scale.y = 1;
RectD rod;
bool isProjectFormat;
- StatusEnum stat = input->getEffectInstance()->getRegionOfDefinition_public(input->getHashValue(), time, scale, ViewIdx(0), &rod, &isProjectFormat);
+ StatusEnum stat = input->getEffectInstance()->getRegionOfDefinition_public(input->getHashValue(), time, RenderScale::identity, ViewIdx(0), &rod, &isProjectFormat);
Point center;
center.x = 0;
center.y = 0;
@@ -1197,10 +1195,8 @@ TrackMarker::getMarkerImage(int time,
true, //isAnalysis
false, //draftMode
RenderStatsPtr() );
- RenderScale scale;
- scale.x = scale.y = 1.;
EffectInstance::RenderRoIArgs args( time,
- scale,
+ RenderScale::identity,
mipmapLevel, //mipmaplevel
ViewIdx(0),
false,
diff --git a/Engine/TrackerContextPrivate.cpp b/Engine/TrackerContextPrivate.cpp
index d8f40aaf7..57ba0f20f 100644
--- a/Engine/TrackerContextPrivate.cpp
+++ b/Engine/TrackerContextPrivate.cpp
@@ -1499,7 +1499,7 @@ TrackerContextPrivate::getInputRoDAtTime(double time) const
if (!input) {
useProjFormat = true;
} else {
- StatusEnum stat = input->getEffectInstance()->getRegionOfDefinition_public(input->getHashValue(), time, RenderScale(1.), ViewIdx(0), &ret, 0);
+ StatusEnum stat = input->getEffectInstance()->getRegionOfDefinition_public(input->getHashValue(), time, RenderScale::identity, ViewIdx(0), &ret, 0);
if (stat == eStatusFailed) {
useProjFormat = true;
} else {
diff --git a/Engine/TrackerFrameAccessor.cpp b/Engine/TrackerFrameAccessor.cpp
index e2ec22656..572682232 100644
--- a/Engine/TrackerFrameAccessor.cpp
+++ b/Engine/TrackerFrameAccessor.cpp
@@ -335,8 +335,7 @@ TrackerFrameAccessor::GetImage(int /*clip*/,
}
// Not in accessor cache, call renderRoI
- RenderScale scale;
- scale.y = scale.x = Image::getScaleFromMipMapLevel( (unsigned int)downscale );
+ const RenderScale scale = RenderScale::fromMipmapLevel( (unsigned int)downscale );
RectD precomputedRoD;
diff --git a/Engine/TrackerNode.cpp b/Engine/TrackerNode.cpp
index 9a55edd21..4b0007610 100644
--- a/Engine/TrackerNode.cpp
+++ b/Engine/TrackerNode.cpp
@@ -2217,9 +2217,8 @@ TrackerNode::onOverlayPenMotion(double time,
if (prevDist != 0) {
double dist = std::sqrt( ( pos.x() - centerPoint.x) * ( pos.x() - centerPoint.x) + ( pos.y() - centerPoint.y) * ( pos.y() - centerPoint.y) );
double ratio = dist / prevDist;
- _imp->ui->selectedMarkerScale.x *= ratio;
- _imp->ui->selectedMarkerScale.x = MathUtils::clamp(_imp->ui->selectedMarkerScale.x, 0.05, 1.);
- _imp->ui->selectedMarkerScale.y = _imp->ui->selectedMarkerScale.x;
+
+ _imp->ui->selectedMarkerScale = MathUtils::clamp(_imp->ui->selectedMarkerScale * ratio, 0.05, 1.);
didSomething = true;
}
break;
@@ -2235,8 +2234,8 @@ TrackerNode::onOverlayPenMotion(double time,
}
double x = centerKnob->getValueAtTime(time, 0);
double y = centerKnob->getValueAtTime(time, 1);
- double dx = delta.x * _imp->ui->selectedMarkerScale.x;
- double dy = delta.y * _imp->ui->selectedMarkerScale.y;
+ double dx = delta.x * _imp->ui->selectedMarkerScale;
+ double dy = delta.y * _imp->ui->selectedMarkerScale;
x += dx;
y += dy;
centerKnob->setValuesAtTime(time, x, y, view, eValueChangedReasonPluginEdited);
diff --git a/Engine/TrackerNodeInteract.cpp b/Engine/TrackerNodeInteract.cpp
index fd129e685..493d4e0cc 100644
--- a/Engine/TrackerNodeInteract.cpp
+++ b/Engine/TrackerNodeInteract.cpp
@@ -90,11 +90,10 @@ TrackerNodeInteract::TrackerNodeInteract(TrackerNodePrivate* p)
, pboID(0)
, imageGetterWatcher()
, showMarkerTexture(false)
- , selectedMarkerScale()
+ , selectedMarkerScale(1.)
, selectedMarkerImg()
, isTracking(false)
{
- selectedMarkerScale.x = selectedMarkerScale.y = 1.;
}
TrackerNodeInteract::~TrackerNodeInteract()
@@ -920,7 +919,7 @@ TrackerNodeInteract::drawSelectedMarkerTexture(const std::pair&
topLeftTex.x = texCoords.x1; topLeftTex.y = texCoords.y2;
topRightTex.x = texCoords.x2; topRightTex.y = texCoords.y2;
btmRightTex.x = texCoords.x2; btmRightTex.y = texCoords.y1;
- Transform::Matrix3x3 m = Transform::matTransformCanonical(0, 0, selectedMarkerScale.x, selectedMarkerScale.y, 0, 0, false, 0, xCenterPercent, yCenterPercent);
+ Transform::Matrix3x3 m = Transform::matTransformCanonical(0, 0, selectedMarkerScale, selectedMarkerScale, 0, 0, false, 0, xCenterPercent, yCenterPercent);
btmLeftTex = Transform::matApply(m, btmLeftTex);
topLeftTex = Transform::matApply(m, topLeftTex);
btmRightTex = Transform::matApply(m, btmRightTex);
diff --git a/Engine/TrackerNodeInteract.h b/Engine/TrackerNodeInteract.h
index c5eac580e..cbef0c1b9 100644
--- a/Engine/TrackerNodeInteract.h
+++ b/Engine/TrackerNodeInteract.h
@@ -375,7 +375,7 @@ GCC_DIAG_SUGGEST_OVERRIDE_ON
GLuint pboID;
TrackWatcherPtr imageGetterWatcher;
bool showMarkerTexture;
- RenderScale selectedMarkerScale;
+ double selectedMarkerScale;
ImageWPtr selectedMarkerImg;
bool isTracking;
diff --git a/Engine/ViewerInstance.cpp b/Engine/ViewerInstance.cpp
index d94895346..3296e1431 100644
--- a/Engine/ViewerInstance.cpp
+++ b/Engine/ViewerInstance.cpp
@@ -1158,8 +1158,6 @@ ViewerInstance::getRoDAndLookupCache(const bool useOnlyRoDCache,
// If it's eSupportsMaybe and mipMapLevel!=0, don't forget to update
// this after the first call to getRegionOfDefinition().
- const RenderScale scaleOne(1.);
-
// This may be eSupportsMaybe
EffectInstance::SupportsEnum supportsRS = outArgs->activeInputToRender->supportsRenderScaleMaybe();
@@ -1169,8 +1167,7 @@ ViewerInstance::getRoDAndLookupCache(const bool useOnlyRoDCache,
for (int lookup = 0; lookup < nLookups; ++lookup) {
const unsigned mipMapLevel = lookup == 0 ? outArgs->mipmapLevelWithoutDraft : outArgs->mipMapLevelWithDraft;
- RenderScale scale;
- scale.x = scale.y = Image::getScaleFromMipMapLevel(mipMapLevel);
+ RenderScale scale = RenderScale::fromMipmapLevel(mipMapLevel);
RectD rod;
@@ -1193,7 +1190,7 @@ ViewerInstance::getRoDAndLookupCache(const bool useOnlyRoDCache,
} else {
stat = outArgs->activeInputToRender->getRegionOfDefinition_public(outArgs->activeInputHash,
outArgs->params->time,
- supportsRS == eSupportsNo ? scaleOne : scale,
+ supportsRS == eSupportsNo ? RenderScale::identity : scale,
outArgs->params->view,
&rod,
0 /*isProjectFormat*/);
@@ -1517,7 +1514,7 @@ ViewerInstance::renderViewer_internal(ViewIdx view,
{
std::unique_ptr renderArgs;
renderArgs.reset( new EffectInstance::RenderRoIArgs(inArgs.params->time,
- Image::getScaleFromMipMapLevel(inArgs.params->mipMapLevel),
+ RenderScale::fromMipmapLevel(inArgs.params->mipMapLevel),
inArgs.params->mipMapLevel,
view,
inArgs.forceRender,
diff --git a/Global/GlobalDefines.h b/Global/GlobalDefines.h
index 1b5adc02a..3a41fc94c 100644
--- a/Global/GlobalDefines.h
+++ b/Global/GlobalDefines.h
@@ -75,18 +75,6 @@ typedef std::uint16_t U16;
NATRON_NAMESPACE_ENTER
typedef int SequenceTime;
-
-struct RenderScale
- : public OfxPointD
-{
- RenderScale() { x = y = 1.; }
-
- RenderScale(double scale) { x = y = scale; }
-
- RenderScale(double scaleX,
- double scaleY) { x = scaleX; y = scaleY; }
-};
-
typedef OfxPointD Point;
typedef OfxRGBAColourF RGBAColourF;
typedef OfxRGBAColourD RGBAColourD;
diff --git a/Gui/CurveWidget.cpp b/Gui/CurveWidget.cpp
index d1ea4db6a..a57ede41d 100644
--- a/Gui/CurveWidget.cpp
+++ b/Gui/CurveWidget.cpp
@@ -694,7 +694,7 @@ CurveWidget::paintGL()
//GLProtectAttrib a(GL_COLOR_BUFFER_BIT | GL_LINE_BIT | GL_CURRENT_BIT | GL_ENABLE_BIT);
GLProtectAttrib a(GL_LINE_BIT | GL_CURRENT_BIT | GL_ENABLE_BIT);
- RenderScale scale(1.);
+ const OfxPointD scale = {1., 1.};
customInteract->setCallingViewport(this);
customInteract->drawAction(0, scale, 0, customInteract->hasColorPicker() ? &customInteract->getLastColorPickerColor() : 0);
glCheckErrorIgnoreOSXBug();
diff --git a/Gui/ViewerGL.cpp b/Gui/ViewerGL.cpp
index 234906da8..a0b3dfd3b 100644
--- a/Gui/ViewerGL.cpp
+++ b/Gui/ViewerGL.cpp
@@ -603,7 +603,7 @@ ViewerGL::centerWipe()
}
void
-ViewerGL::drawOverlay(unsigned int mipMapLevel)
+ViewerGL::drawOverlay(unsigned int mipmapLevel)
{
// always running in the main thread
assert( qApp && qApp->thread() == QThread::currentThread() );
@@ -722,13 +722,12 @@ ViewerGL::drawOverlay(unsigned int mipMapLevel)
glCheckError();
glColor4f(1., 1., 1., 1.);
- double scale = 1. / (1 << mipMapLevel);
/*
Draw the overlays corresponding to the image displayed on the viewer, not the current timeline's time
*/
double time = getCurrentlyDisplayedTime();
- _imp->viewerTab->drawOverlays( time, RenderScale(scale) );
+ _imp->viewerTab->drawOverlays( time, RenderScale::fromMipmapLevel(mipmapLevel) );
glCheckErrorIgnoreOSXBug();
@@ -1881,9 +1880,7 @@ ViewerGL::mousePressEvent(QMouseEvent* e)
if (!overlaysCaught &&
(_imp->ms == eMouseStateUndefined) &&
_imp->overlay) {
- unsigned int mipMapLevel = getCurrentRenderScale();
- double scale = 1. / (1 << mipMapLevel);
- overlaysCaught = _imp->viewerTab->notifyOverlaysPenDown( RenderScale(scale), _imp->pointerTypeOnPress, QMouseEventLocalPos(e), zoomPos, _imp->pressureOnPress, currentTimeForEvent(e) );
+ overlaysCaught = _imp->viewerTab->notifyOverlaysPenDown( RenderScale::fromMipmapLevel(getCurrentRenderScale()), _imp->pointerTypeOnPress, QMouseEventLocalPos(e), zoomPos, _imp->pressureOnPress, currentTimeForEvent(e) );
if (overlaysCaught) {
mustRedraw = true;
}
@@ -2083,9 +2080,7 @@ ViewerGL::mouseReleaseEvent(QMouseEvent* e)
QMutexLocker l(&_imp->zoomCtxMutex);
zoomPos = _imp->zoomCtx.toZoomCoordinates( e->x(), e->y() );
}
- unsigned int mipMapLevel = getCurrentRenderScale();
- double scale = 1. / (1 << mipMapLevel);
- if ( _imp->viewerTab->notifyOverlaysPenUp(RenderScale(scale), QMouseEventLocalPos(e), zoomPos, currentTimeForEvent(e), _imp->pressureOnRelease) ) {
+ if ( _imp->viewerTab->notifyOverlaysPenUp(RenderScale::fromMipmapLevel(getCurrentRenderScale()), QMouseEventLocalPos(e), zoomPos, currentTimeForEvent(e), _imp->pressureOnRelease) ) {
mustRedraw = true;
}
if (mustRedraw) {
@@ -2508,10 +2503,8 @@ ViewerGL::penMotionInternal(int x,
}; break;
default: {
QPointF localPos(x, y);
- unsigned int mipMapLevel = getCurrentRenderScale();
- double scale = 1. / (1 << mipMapLevel);
if ( _imp->overlay &&
- _imp->viewerTab->notifyOverlaysPenMotion(RenderScale(scale), localPos, zoomPos, pressure, timestamp) ) {
+ _imp->viewerTab->notifyOverlaysPenMotion(RenderScale::fromMipmapLevel(getCurrentRenderScale()), localPos, zoomPos, pressure, timestamp) ) {
mustRedraw = true;
overlaysCaughtByPlugin = true;
}
@@ -2539,15 +2532,12 @@ ViewerGL::penMotionInternal(int x,
void
ViewerGL::mouseDoubleClickEvent(QMouseEvent* e)
{
- unsigned int mipMapLevel = getCurrentRenderScale();
QPointF pos_opengl;
{
QMutexLocker l(&_imp->zoomCtxMutex);
pos_opengl = _imp->zoomCtx.toZoomCoordinates( e->x(), e->y() );
}
- double scale = 1. / (1 << mipMapLevel);
-
- if ( _imp->viewerTab->notifyOverlaysPenDoubleClick(RenderScale(scale), QMouseEventLocalPos(e), pos_opengl) ) {
+ if ( _imp->viewerTab->notifyOverlaysPenDoubleClick(RenderScale::fromMipmapLevel(getCurrentRenderScale()), QMouseEventLocalPos(e), pos_opengl) ) {
update();
}
QOpenGLWidget::mouseDoubleClickEvent(e);
@@ -3139,8 +3129,7 @@ ViewerGL::focusInEvent(QFocusEvent* e)
if ( !_imp->viewerTab->getGui() ) {
return;
}
- double scale = 1. / ( 1 << getCurrentRenderScale() );
- if ( _imp->viewerTab->notifyOverlaysFocusGained( RenderScale(scale) ) ) {
+ if ( _imp->viewerTab->notifyOverlaysFocusGained( RenderScale::fromMipmapLevel(getCurrentRenderScale()) ) ) {
update();
}
QOpenGLWidget::focusInEvent(e);
@@ -3156,8 +3145,7 @@ ViewerGL::focusOutEvent(QFocusEvent* e)
return;
}
- double scale = 1. / ( 1 << getCurrentRenderScale() );
- if ( _imp->viewerTab->notifyOverlaysFocusLost( RenderScale(scale) ) ) {
+ if ( _imp->viewerTab->notifyOverlaysFocusLost( RenderScale::fromMipmapLevel(getCurrentRenderScale()) ) ) {
update();
}
QOpenGLWidget::focusOutEvent(e);
diff --git a/Gui/ViewerTab10.cpp b/Gui/ViewerTab10.cpp
index 6cf09378a..6139b3879 100644
--- a/Gui/ViewerTab10.cpp
+++ b/Gui/ViewerTab10.cpp
@@ -617,11 +617,11 @@ ViewerTab::keyPressEvent(QKeyEvent* e)
bool accept = true;
Qt::KeyboardModifiers modifiers = e->modifiers();
Qt::Key key = (Qt::Key)Gui::handleNativeKeys( e->key(), e->nativeScanCode(), e->nativeVirtualKey() );
- double scale = 1. / ( 1 << _imp->viewer->getCurrentRenderScale() );
- if ( e->isAutoRepeat() && notifyOverlaysKeyRepeat(RenderScale(scale), e) ) {
+ const unsigned int mipMapLevel = _imp->viewer->getCurrentRenderScale();
+ if ( e->isAutoRepeat() && notifyOverlaysKeyRepeat(RenderScale::fromMipmapLevel(mipMapLevel), e) ) {
update();
- } else if ( notifyOverlaysKeyDown(RenderScale(scale), e) ) {
+ } else if ( notifyOverlaysKeyDown(RenderScale::fromMipmapLevel(mipMapLevel), e) ) {
update();
} else if ( isKeybind(kShortcutGroupViewer, kShortcutIDActionLuminance, modifiers, key) ) {
int currentIndex = _imp->viewerChannels->activeIndex();
@@ -901,8 +901,8 @@ ViewerTab::keyReleaseEvent(QKeyEvent* e)
if ( !getGui() ) {
return QWidget::keyPressEvent(e);
}
- double scale = 1. / ( 1 << _imp->viewer->getCurrentRenderScale() );
- if ( notifyOverlaysKeyUp(RenderScale(scale), e) ) {
+ const unsigned int mipMapLevel = _imp->viewer->getCurrentRenderScale();
+ if ( notifyOverlaysKeyUp(RenderScale::fromMipmapLevel(mipMapLevel), e) ) {
_imp->viewer->redraw();
} else {
handleUnCaughtKeyUpEvent(e);
diff --git a/Gui/ViewerTabPrivate.cpp b/Gui/ViewerTabPrivate.cpp
index 8ee10c562..10e9e3570 100644
--- a/Gui/ViewerTabPrivate.cpp
+++ b/Gui/ViewerTabPrivate.cpp
@@ -174,7 +174,6 @@ ViewerTabPrivate::getOverlayTransform(double time,
if ( currentNode == targetNode ) {
return true;
}
- RenderScale s(1.);
EffectInstancePtr input;
StatusEnum stat = eStatusReplyDefault;
Transform::Matrix3x3 mat;
@@ -186,7 +185,7 @@ ViewerTabPrivate::getOverlayTransform(double time,
if ( !currentNode->getNode()->isNodeDisabled() /*&& currentNode->getNode()->getCurrentCanTransform()*/ ) {
// Always use draft mode to draw overlay (so that transforms are applied,
// even in case of motion blur, see Transform3x3Plugin::getTransform() )
- stat = currentNode->getTransform_public(time, s, /*draftRender=*/true, view, &input, &mat);
+ stat = currentNode->getTransform_public(time, RenderScale::identity, /*draftRender=*/true, view, &input, &mat);
}
if (stat == eStatusFailed) {
return false;
diff --git a/tools/MacPorts/multimedia/ffmpeg/Portfile b/tools/MacPorts/multimedia/ffmpeg/Portfile
index 005c82923..6270de8f0 100644
--- a/tools/MacPorts/multimedia/ffmpeg/Portfile
+++ b/tools/MacPorts/multimedia/ffmpeg/Portfile
@@ -310,10 +310,13 @@ platform darwin {
# Available on 10.6+
if {(${os.major} >= 10) && (${configure.build_arch} ne "ppc")} {
- configure.args-append \
+ # Only enable 'rav1e', for non-slim installation
+ if {![variant_isset slim]} {
+ configure.args-append \
--enable-librav1e
- depends_lib-append \
+ depends_lib-append \
port:rav1e
+ }
}
}
@@ -573,6 +576,8 @@ variant nonfree description {enable nonfree code, libraries and binaries will no
port:libfdk-aac
}
+variant slim description {Trim dependencies slightly, without significantly impacting overall feature set} {}
+
if {[variant_isset nonfree]} {
notes "
This build of ${name} includes nonfree code as follows:
diff --git a/tools/MacPorts/multimedia/ffmpeg/Portfile.orig b/tools/MacPorts/multimedia/ffmpeg/Portfile.orig
index 35b94554d..d2fbb4aae 100644
--- a/tools/MacPorts/multimedia/ffmpeg/Portfile.orig
+++ b/tools/MacPorts/multimedia/ffmpeg/Portfile.orig
@@ -298,10 +298,13 @@ platform darwin {
# Available on 10.6+
if {(${os.major} >= 10) && (${configure.build_arch} ne "ppc")} {
- configure.args-append \
+ # Only enable 'rav1e', for non-slim installation
+ if {![variant_isset slim]} {
+ configure.args-append \
--enable-librav1e
- depends_lib-append \
+ depends_lib-append \
port:rav1e
+ }
}
}
@@ -473,6 +476,8 @@ variant nonfree description {enable nonfree code, libraries and binaries will no
port:libfdk-aac
}
+variant slim description {Trim dependencies slightly, without significantly impacting overall feature set} {}
+
if {[variant_isset nonfree]} {
notes "
This build of ${name} includes nonfree code as follows: