| 2899 | } // tiledRenderingFunctor |
| 2900 | |
| 2901 | ImagePtr |
| 2902 | EffectInstance::allocateImagePlaneAndSetInThreadLocalStorage(const ImagePlaneDesc & plane) |
| 2903 | { |
| 2904 | /* |
| 2905 | * The idea here is that we may have asked the plug-in to render say motion.forward, but it can only render both fotward |
| 2906 | * and backward at a time. |
| 2907 | * So it needs to allocate motion.backward and store it in the cache for efficiency. |
| 2908 | * Note that when calling this, the plug-in is already in the render action, hence in case of Host frame threading, |
| 2909 | * this function will be called as many times as there were thread used by the host frame threading. |
| 2910 | * For all other planes, there was a local temporary image, shared among all threads for the calls to render. |
| 2911 | * Since we may be in a thread of the host frame threading, only allocate a temporary image of the size of the rectangle |
| 2912 | * to render and mark that we're a plane allocated on the fly so that the tiledRenderingFunctor can know this is a plane |
| 2913 | * to handle specifically. |
| 2914 | */ |
| 2915 | EffectDataTLSPtr tls = _imp->tlsData->getTLSData(); |
| 2916 | |
| 2917 | if (!tls || !tls->currentRenderArgs.validArgs) { |
| 2918 | return ImagePtr(); |
| 2919 | } |
| 2920 | |
| 2921 | assert( !tls->currentRenderArgs.outputPlanes.empty() ); |
| 2922 | |
| 2923 | const EffectInstance::PlaneToRender & firstPlane = tls->currentRenderArgs.outputPlanes.begin()->second; |
| 2924 | bool useCache = firstPlane.fullscaleImage->usesBitMap() || firstPlane.downscaleImage->usesBitMap(); |
| 2925 | if ( boost::starts_with(getNode()->getPluginID(), "uk.co.thefoundry.furnace") ) { |
| 2926 | //Furnace plug-ins are bugged and do not render properly both planes, just wipe the image. |
| 2927 | useCache = false; |
| 2928 | } |
| 2929 | const ImagePtr & img = firstPlane.fullscaleImage->usesBitMap() ? firstPlane.fullscaleImage : firstPlane.downscaleImage; |
| 2930 | boost::shared_ptr<ImageParams> params = img->getParams(); |
| 2931 | EffectInstance::PlaneToRender p; |
| 2932 | bool ok = allocateImagePlane(img->getKey(), |
| 2933 | tls->currentRenderArgs.rod, |
| 2934 | tls->currentRenderArgs.renderWindowPixel, |
| 2935 | tls->currentRenderArgs.renderWindowPixel, |
| 2936 | false /*isProjectFormat*/, |
| 2937 | plane, |
| 2938 | img->getBitDepth(), |
| 2939 | img->getPremultiplication(), |
| 2940 | img->getFieldingOrder(), |
| 2941 | img->getPixelAspectRatio(), |
| 2942 | img->getMipMapLevel(), |
| 2943 | false, |
| 2944 | img->getParams()->getStorageInfo().mode, |
| 2945 | useCache, |
| 2946 | &p.fullscaleImage, |
| 2947 | &p.downscaleImage); |
| 2948 | if (!ok) { |
| 2949 | return ImagePtr(); |
| 2950 | } else { |
| 2951 | p.renderMappedImage = p.downscaleImage; |
| 2952 | p.isAllocatedOnTheFly = true; |
| 2953 | |
| 2954 | /* |
| 2955 | * Allocate a temporary image for rendering only if using cache |
| 2956 | */ |
| 2957 | if (useCache) { |
| 2958 | p.tmpImage.reset( new Image(p.renderMappedImage->getComponents(), |
no test coverage detected