| 75 | //#define NATRON_ALWAYS_ALLOCATE_FULL_IMAGE_BOUNDS |
| 76 | |
| 77 | NATRON_NAMESPACE_ENTER |
| 78 | |
| 79 | /* |
| 80 | * @brief Split all rects to render in smaller rects and check if each one of them is identity. |
| 81 | * For identity rectangles, we just call renderRoI again on the identity input in the tiledRenderingFunctor. |
| 82 | * For non-identity rectangles, compute the bounding box of them and render it |
| 83 | */ |
| 84 | static void |
| 85 | optimizeRectsToRender(EffectInstance* self, |
| 86 | const RectI & inputsRoDIntersection, |
| 87 | const std::list<RectI> & rectsToRender, |
| 88 | const double time, |
| 89 | const ViewIdx view, |
| 90 | const RenderScale & renderMappedScale, |
| 91 | std::list<EffectInstance::RectToRender>* finalRectsToRender) |
| 92 | { |
| 93 | for (std::list<RectI>::const_iterator it = rectsToRender.begin(); it != rectsToRender.end(); ++it) { |
| 94 | std::vector<RectI> splits = it->splitIntoSmallerRects(0); |
| 95 | EffectInstance::RectToRender nonIdentityRect; |
| 96 | nonIdentityRect.isIdentity = false; |
| 97 | nonIdentityRect.identityTime = 0; |
| 98 | nonIdentityRect.rect.x1 = std::numeric_limits<int>::max(); |
| 99 | nonIdentityRect.rect.x2 = std::numeric_limits<int>::min(); |
| 100 | nonIdentityRect.rect.y1 = std::numeric_limits<int>::max(); |
| 101 | nonIdentityRect.rect.y2 = std::numeric_limits<int>::min(); |
| 102 | |
| 103 | bool nonIdentityRectSet = false; |
| 104 | for (std::size_t i = 0; i < splits.size(); ++i) { |
| 105 | double identityInputTime = 0.; |
| 106 | int identityInputNb = -1; |
| 107 | bool identity = false; |
| 108 | ViewIdx inputIdentityView(view); |
| 109 | if ( !splits[i].intersects(inputsRoDIntersection) ) { |
| 110 | identity = self->isIdentity_public(false, 0, time, renderMappedScale, splits[i], view, &identityInputTime, &inputIdentityView, &identityInputNb); |
| 111 | } else { |
| 112 | identity = false; |
| 113 | } |
| 114 | |
| 115 | if (identity) { |
| 116 | EffectInstance::RectToRender r; |
| 117 | r.isIdentity = true; |
| 118 | |
| 119 | // Walk along the identity branch until we find the non identity input, or NULL in we case we will |
| 120 | // just render black and transparent |
| 121 | EffectInstancePtr identityInput = self->getInput(identityInputNb); |
| 122 | if (identityInput) { |
| 123 | for (;; ) { |
| 124 | identity = identityInput->isIdentity_public(false, 0, time, renderMappedScale, splits[i], view, &identityInputTime, &inputIdentityView, &identityInputNb); |
| 125 | if ( !identity || (identityInputNb == -2) ) { |
| 126 | break; |
| 127 | } |
| 128 | EffectInstancePtr subIdentityInput = identityInput->getInput(identityInputNb); |
| 129 | if (subIdentityInput == identityInput) { |
| 130 | break; |
| 131 | } |
| 132 | |
| 133 | identityInput = subIdentityInput; |
| 134 | if (!subIdentityInput) { |
no test coverage detected