Fix T52927: Compositor wrong scale when scale size input is connected to complex node

The issue here is that we can not read scale from socket when determining
dependent area of interest. This area will depend on current pixel. Now fall
back to more stupid but reliable thing: if scale size input is connected to some
nodes, we use the whole frame as area of interest.
This commit is contained in:
Sergey Sharybin 2017-10-02 15:54:08 +05:00
parent b2a10fa615
commit 64c1a48c50
3 changed files with 61 additions and 28 deletions

View File

@ -52,6 +52,9 @@ void ScaleNode::convertToOperations(NodeConverter &converter, const CompositorCo
converter.mapInputSocket(inputXSocket, operation->getInputSocket(1));
converter.mapInputSocket(inputYSocket, operation->getInputSocket(2));
converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
operation->setVariableSize(inputXSocket->isLinked() ||
inputYSocket->isLinked());
break;
}
case CMP_SCALE_SCENEPERCENT:
@ -67,6 +70,10 @@ void ScaleNode::convertToOperations(NodeConverter &converter, const CompositorCo
converter.addLink(scaleFactorOperation->getOutputSocket(), operation->getInputSocket(1));
converter.addLink(scaleFactorOperation->getOutputSocket(), operation->getInputSocket(2));
converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
operation->setVariableSize(inputXSocket->isLinked() ||
inputYSocket->isLinked());
break;
}
case CMP_SCALE_RENDERPERCENT:
@ -81,9 +88,13 @@ void ScaleNode::convertToOperations(NodeConverter &converter, const CompositorCo
operation->setNewHeight(rd->ysch * rd->size / 100.0f);
operation->getInputSocket(0)->setResizeMode(COM_SC_NO_RESIZE);
converter.addOperation(operation);
converter.mapInputSocket(inputSocket, operation->getInputSocket(0));
converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
operation->setVariableSize(inputXSocket->isLinked() ||
inputYSocket->isLinked());
break;
}
case CMP_SCALE_ABSOLUTE:
@ -91,11 +102,15 @@ void ScaleNode::convertToOperations(NodeConverter &converter, const CompositorCo
/* TODO: what is the use of this one.... perhaps some issues when the ui was updated... */
ScaleAbsoluteOperation *operation = new ScaleAbsoluteOperation();
converter.addOperation(operation);
converter.mapInputSocket(inputSocket, operation->getInputSocket(0));
converter.mapInputSocket(inputXSocket, operation->getInputSocket(1));
converter.mapInputSocket(inputYSocket, operation->getInputSocket(2));
converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
operation->setVariableSize(inputXSocket->isLinked() ||
inputYSocket->isLinked());
break;
}
}

View File

@ -36,6 +36,7 @@ BaseScaleOperation::BaseScaleOperation()
#else
m_sampler = -1;
#endif
m_variable_size = false;
}
ScaleOperation::ScaleOperation() : BaseScaleOperation()
@ -87,20 +88,27 @@ void ScaleOperation::executePixelSampled(float output[4], float x, float y, Pixe
bool ScaleOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
{
rcti newInput;
float scaleX[4];
float scaleY[4];
if (!m_variable_size) {
float scaleX[4];
float scaleY[4];
this->m_inputXOperation->readSampled(scaleX, 0, 0, COM_PS_NEAREST);
this->m_inputYOperation->readSampled(scaleY, 0, 0, COM_PS_NEAREST);
this->m_inputXOperation->readSampled(scaleX, 0, 0, COM_PS_NEAREST);
this->m_inputYOperation->readSampled(scaleY, 0, 0, COM_PS_NEAREST);
const float scx = scaleX[0];
const float scy = scaleY[0];
newInput.xmax = this->m_centerX + (input->xmax - this->m_centerX) / scx;
newInput.xmin = this->m_centerX + (input->xmin - this->m_centerX) / scx;
newInput.ymax = this->m_centerY + (input->ymax - this->m_centerY) / scy;
newInput.ymin = this->m_centerY + (input->ymin - this->m_centerY) / scy;
const float scx = scaleX[0];
const float scy = scaleY[0];
newInput.xmax = this->m_centerX + (input->xmax - this->m_centerX) / scx;
newInput.xmin = this->m_centerX + (input->xmin - this->m_centerX) / scx;
newInput.ymax = this->m_centerY + (input->ymax - this->m_centerY) / scy;
newInput.ymin = this->m_centerY + (input->ymin - this->m_centerY) / scy;
}
else {
newInput.xmax = this->getWidth();
newInput.xmin = 0;
newInput.ymax = this->getHeight();
newInput.ymin = 0;
}
return BaseScaleOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}
@ -162,24 +170,32 @@ void ScaleAbsoluteOperation::executePixelSampled(float output[4], float x, float
bool ScaleAbsoluteOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
{
rcti newInput;
float scaleX[4];
float scaleY[4];
if (!m_variable_size) {
float scaleX[4];
float scaleY[4];
this->m_inputXOperation->readSampled(scaleX, 0, 0, COM_PS_NEAREST);
this->m_inputYOperation->readSampled(scaleY, 0, 0, COM_PS_NEAREST);
this->m_inputXOperation->readSampled(scaleX, 0, 0, COM_PS_NEAREST);
this->m_inputYOperation->readSampled(scaleY, 0, 0, COM_PS_NEAREST);
const float scx = scaleX[0];
const float scy = scaleY[0];
const float width = this->getWidth();
const float height = this->getHeight();
//div
float relateveXScale = scx / width;
float relateveYScale = scy / height;
const float scx = scaleX[0];
const float scy = scaleY[0];
const float width = this->getWidth();
const float height = this->getHeight();
//div
float relateveXScale = scx / width;
float relateveYScale = scy / height;
newInput.xmax = this->m_centerX + (input->xmax - this->m_centerX) / relateveXScale;
newInput.xmin = this->m_centerX + (input->xmin - this->m_centerX) / relateveXScale;
newInput.ymax = this->m_centerY + (input->ymax - this->m_centerY) / relateveYScale;
newInput.ymin = this->m_centerY + (input->ymin - this->m_centerY) / relateveYScale;
newInput.xmax = this->m_centerX + (input->xmax - this->m_centerX) / relateveXScale;
newInput.xmin = this->m_centerX + (input->xmin - this->m_centerX) / relateveXScale;
newInput.ymax = this->m_centerY + (input->ymax - this->m_centerY) / relateveYScale;
newInput.ymin = this->m_centerY + (input->ymin - this->m_centerY) / relateveYScale;
}
else {
newInput.xmax = this->getWidth();
newInput.xmin = 0;
newInput.ymax = this->getHeight();
newInput.ymin = 0;
}
return BaseScaleOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}

View File

@ -28,6 +28,7 @@
class BaseScaleOperation : public NodeOperation {
public:
void setSampler(PixelSampler sampler) { this->m_sampler = (int) sampler; }
void setVariableSize(bool variable_size) { m_variable_size = variable_size; };
protected:
BaseScaleOperation();
@ -35,6 +36,7 @@ protected:
PixelSampler getEffectiveSampler(PixelSampler sampler) { return (m_sampler == -1) ? sampler : (PixelSampler) m_sampler; }
int m_sampler;
bool m_variable_size;
};
class ScaleOperation : public BaseScaleOperation {