TEST(ImageKeyTest, Difference) { srand(2000); // coverity[dont_call] int randomHashKey1 = rand() % 100; ImageCacheKey key1(randomHashKey1, 0, RenderScale(1.), std::string()); U64 keyHash1 = key1.getHash(); ///make a second ImageKey different to the first // coverity[dont_call] int randomHashKey2 = rand() % 1000 + 150; ImageCacheKey key2(randomHashKey2, 0, RenderScale(1.), std::string()); U64 keyHash2 = key2.getHash(); ASSERT_TRUE(keyHash1 != keyHash2); }
std::pair<ImagePtr, RectD> TrackMarker::getMarkerImage(TimeValue time, const RectD& roi) const { assert( !roi.isNull() ); NodePtr node = getModel()->getNode(); NodePtr input = node->getInput(0); if (!input) { return std::make_pair(ImagePtr(), roi); } TreeRender::CtorArgsPtr args(new TreeRender::CtorArgs); { args->treeRootEffect = input->getEffectInstance(); args->time = time; args->view = ViewIdx(0); // Render default plane args->plane = 0; args->mipMapLevel = 0; args->proxyScale = RenderScale(1.); args->canonicalRoI = &roi; args->draftMode = false; args->playback = false; args->byPassCache = false; } TreeRenderPtr render = TreeRender::create(args); FrameViewRequestPtr outputRequest; ActionRetCodeEnum stat = render->launchRender(&outputRequest); if (isFailureRetCode(stat)) { return std::make_pair(ImagePtr(), roi); } ImagePtr sourceImage = outputRequest->getRequestedScaleImagePlane(); // Make sure the Natron image rendered is RGBA full rect and on CPU, we don't support other formats if (sourceImage->getStorageMode() != eStorageModeRAM) { Image::InitStorageArgs initArgs; initArgs.bounds = sourceImage->getBounds(); initArgs.plane = sourceImage->getLayer(); initArgs.bufferFormat = eImageBufferLayoutRGBAPackedFullRect; initArgs.storage = eStorageModeRAM; initArgs.bitdepth = sourceImage->getBitDepth(); ImagePtr tmpImage = Image::create(initArgs); if (!tmpImage) { return std::make_pair(ImagePtr(), roi); } Image::CopyPixelsArgs cpyArgs; cpyArgs.roi = initArgs.bounds; tmpImage->copyPixels(*sourceImage, cpyArgs); sourceImage = tmpImage; } return std::make_pair(sourceImage, roi); } // TrackMarker::getMarkerImage
NATRON_NAMESPACE_USING TEST(ImageKeyTest, Equality) { srand(2000); // coverity[dont_call] int randomHashKey1 = rand(); ImageCacheKey key1(randomHashKey1, 0, RenderScale(1.), std::string()); U64 keyHash1 = key1.getHash(); ///make a second ImageKey equal to the first int randomHashKey2 = randomHashKey1; ImageCacheKey key2(randomHashKey2, 0, RenderScale(1.), std::string()); U64 keyHash2 = key2.getHash(); ASSERT_TRUE(keyHash1 == keyHash2); }
ActionRetCodeEnum RotoShapeRenderNode::getLayersProducedAndNeeded(TimeValue time, ViewIdx view, std::map<int, std::list<ImagePlaneDesc> >* inputLayersNeeded, std::list<ImagePlaneDesc>* layersProduced, TimeValue* passThroughTime, ViewIdx* passThroughView, int* passThroughInputNb) { int renderType_i = _imp->renderType.lock()->getValue(); if (renderType_i == 1) { // Smear return EffectInstance::getLayersProducedAndNeeded(time, view, inputLayersNeeded, layersProduced, passThroughTime, passThroughView, passThroughInputNb); } else { // Solid ImagePlaneDesc inputPlane, pairedInputPlane; getMetadataComponents(0, &inputPlane, &pairedInputPlane); (*inputLayersNeeded)[0].push_back(inputPlane); // If we are identity, we do not produce the RotoMask plane IsIdentityResultsPtr identityResults; int identityInputNb = -1; RectI identityWindow; identityWindow.x1 = INT_MIN; identityWindow.y1 = INT_MIN; identityWindow.x2 = INT_MAX; identityWindow.y2 = INT_MAX; ActionRetCodeEnum stat = isIdentity_public(true, time, RenderScale(1.), identityWindow, view, 0, &identityResults); if (!isFailureRetCode(stat)) { identityResults->getIdentityData(&identityInputNb, 0, 0, 0); } if (identityInputNb == -1) { std::vector<std::string> channels(1); channels[0] = "A"; ImagePlaneDesc rotoMaskPlane("RotoMask", "", "Alpha", channels); layersProduced->push_back(rotoMaskPlane); } *passThroughTime = time; *passThroughView = view; *passThroughInputNb = 0; return eActionStatusOK; } } // getLayersProducedAndNeeded
void ViewerTab::keyReleaseEvent(QKeyEvent* e) { // always running in the main thread assert( qApp && qApp->thread() == QThread::currentThread() ); Gui* gui = getGui(); if (!gui) { return QWidget::keyPressEvent(e); } double scale = 1. / ( 1 << _imp->viewer->getCurrentRenderScale() ); if ( notifyOverlaysKeyUp(RenderScale(scale), e) ) { _imp->viewer->redraw(); } else { handleUnCaughtKeyUpEvent(e); QWidget::keyReleaseEvent(e); } }
void ViewerNode::updateViewer(const UpdateViewerArgs& args) { OpenGLViewerI* uiContext = getUiContext(); assert(uiContext); uiContext->clearPartialUpdateTextures(); for (int i = 0; i < 2; ++i) { RectD rod; NodePtr viewerProcessNode = _imp->internalViewerProcessNode[i].lock(); GetRegionOfDefinitionResultsPtr actionResults; ActionRetCodeEnum stat = viewerProcessNode->getEffectInstance()->getRegionOfDefinition_public(args.time, RenderScale(1.), args.view, &actionResults); if (!isFailureRetCode(stat)) { rod = actionResults->getRoD(); } for (std::list<UpdateViewerArgs::TextureUpload>::const_iterator it = args.viewerUploads[i].begin(); it!= args.viewerUploads[i].end(); ++it) { OpenGLViewerI::TextureTransferArgs transferArgs; transferArgs.image = it->image; transferArgs.colorPickerImage = it->colorPickerImage; transferArgs.colorPickerInputImage = it->colorPickerInputImage; transferArgs.textureIndex = i; transferArgs.time = args.time; transferArgs.view = args.view; transferArgs.rod = rod; transferArgs.recenterViewer = args.recenterViewer; transferArgs.viewportCenter = args.viewerCenter; transferArgs.viewerProcessNodeKey = it->viewerProcessImageKey; transferArgs.type = args.type; uiContext->transferBufferFromRAMtoGPU(transferArgs); } } }
void ViewerTab::keyPressEvent(QKeyEvent* e) { ViewerNodePtr internalNode = getInternalNode(); if (!internalNode || !internalNode->getNode()) { return; } //qDebug() << "ViewerTab::keyPressed:" << e->text() << "modifiers:" << e->modifiers(); Gui* gui = getGui(); if (gui) { gui->setActiveViewer(this); } 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) ) { update(); } else if ( notifyOverlaysKeyDown(RenderScale(scale), e) ) { update(); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerToInput1, modifiers, key) ) { connectToAInput(0); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerToInput2, modifiers, key) ) { connectToAInput(1); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerToInput3, modifiers, key) ) { connectToAInput(2); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerToInput4, modifiers, key) ) { connectToAInput(3); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerToInput5, modifiers, key) ) { connectToAInput(4); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerToInput6, modifiers, key) ) { connectToAInput(5); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerToInput7, modifiers, key) ) { connectToAInput(6); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerToInput8, modifiers, key) ) { connectToAInput(7); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerToInput9, modifiers, key) ) { connectToAInput(8); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerToInput10, modifiers, key) ) { connectToAInput(9); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerBToInput1, modifiers, key) ) { connectToBInput(0); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerBToInput2, modifiers, key) ) { connectToBInput(1); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerBToInput3, modifiers, key) ) { connectToBInput(2); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerBToInput4, modifiers, key) ) { connectToBInput(3); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerBToInput5, modifiers, key) ) { connectToBInput(4); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerBToInput6, modifiers, key) ) { connectToBInput(5); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerBToInput7, modifiers, key) ) { connectToBInput(6); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerBToInput8, modifiers, key) ) { connectToBInput(7); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerBToInput9, modifiers, key) ) { connectToBInput(8); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerBToInput10, modifiers, key) ) { connectToBInput(9); } else if (key == Qt::Key_Escape) { _imp->viewer->s_selectionCleared(); update(); } else { accept = false; } if (accept) { takeClickFocus(); e->accept(); } else { handleUnCaughtKeyPressEvent(e); QWidget::keyPressEvent(e); } } // keyPressEvent
ActionRetCodeEnum RotoShapeRenderNode::getRegionOfDefinition(TimeValue time, const RenderScale& scale, ViewIdx view, RectD* rod) { RotoDrawableItemPtr item = getAttachedRotoItem(); assert(item); assert((isRenderClone() && item->isRenderClone()) || (!isRenderClone() && !item->isRenderClone())); const bool isPainting = isDuringPaintStrokeCreation(); RectD shapeRoD; getRoDFromItem(item, time, view, isPainting, &shapeRoD); bool clipToFormat = _imp->clipToFormatKnob.lock()->getValue(); RotoShapeRenderTypeEnum type = (RotoShapeRenderTypeEnum)_imp->renderType.lock()->getValue(); switch (type) { case eRotoShapeRenderTypeSmear: { RectD defaultRod; ActionRetCodeEnum stat = EffectInstance::getRegionOfDefinition(time, scale, view, &defaultRod); if (isFailureRetCode(stat)) { return stat; } if (!defaultRod.isNull()) { *rod = shapeRoD; rod->merge(defaultRod); } } break; case eRotoShapeRenderTypeSolid: { RotoPaintOutputRoDTypeEnum rodType = (RotoPaintOutputRoDTypeEnum)_imp->outputRoDTypeKnob.lock()->getValue(); switch (rodType) { case eRotoPaintOutputRoDTypeDefault: { *rod = shapeRoD; // No format is set, use the format from the input if (clipToFormat) { EffectInstancePtr inputEffect = getInputRenderEffectAtAnyTimeView(0); if (inputEffect) { RectI outputFormat = inputEffect->getOutputFormat(); RectD outputFormatCanonical; outputFormat.toCanonical_noClipping(scale, inputEffect->getAspectRatio(-1), &outputFormatCanonical); rod->intersect(outputFormatCanonical, rod); } } } break; case eRotoPaintOutputRoDTypeFormat: { KnobIntPtr sizeKnob = _imp->outputFormatSizeKnob.lock(); int w = sizeKnob->getValue(DimIdx(0)); int h = _imp->outputFormatSizeKnob.lock()->getValue(DimIdx(1)); double par = _imp->outputFormatParKnob.lock()->getValue(); RectI pixelFormat; pixelFormat.x1 = pixelFormat.y1 = 0; pixelFormat.x2 = w; pixelFormat.y2 = h; RenderScale renderScale(1.); pixelFormat.toCanonical_noClipping(renderScale, par, rod); if (!clipToFormat) { rod->merge(shapeRoD); } } break; case eRotoPaintOutputRoDTypeProject: { Format f; getApp()->getProject()->getProjectDefaultFormat(&f); f.toCanonical_noClipping(RenderScale(1.), f.getPixelAspectRatio(), rod); if (!clipToFormat) { rod->merge(shapeRoD); } } break; } } break; } return eActionStatusOK; }
static ActionRetCodeEnum createFrameRenderResultsForView(const ViewerNodePtr& viewer, const TreeRenderQueueProviderPtr& provider, const ViewerRenderFrameResultsContainerPtr& results, ViewIdx view, const RenderStatsPtr& stats, bool isPlayback, const RectD* partialUpdateRoIParam, unsigned int mipMapLevel, ViewerCompositingOperatorEnum viewerBlend, bool byPassCache, bool draftModeEnabled, bool fullFrameProcessing, bool viewerBEqualsViewerA, const RotoStrokeItemPtr& activeDrawingStroke) { // Initialize for each view a sub-result. // Each view has 2 renders: the A and B viewerprocess ViewerRenderFrameSubResultPtr subResult(new ViewerRenderFrameSubResult); results->frames.push_back(subResult); subResult->view = view; subResult->stats = stats; if (partialUpdateRoIParam) { subResult->textureTransferType = OpenGLViewerI::TextureTransferArgs::eTextureTransferTypeOverlay; } else if (activeDrawingStroke && activeDrawingStroke->getRenderCloneCurrentStrokeStartPointIndex() > 0) { // Upon painting ticks, we just have to update the viewer for the area that was painted subResult->textureTransferType = OpenGLViewerI::TextureTransferArgs::eTextureTransferTypeModify; } else { subResult->textureTransferType = OpenGLViewerI::TextureTransferArgs::eTextureTransferTypeReplace; } for (int viewerInputIndex = 0; viewerInputIndex < 2; ++viewerInputIndex) { subResult->perInputsData[viewerInputIndex].retCode = eActionStatusFailed; if (viewerInputIndex == 1 && (viewerBEqualsViewerA || viewerBlend == eViewerCompositingOperatorNone)) { if (viewerBEqualsViewerA && viewerBlend != eViewerCompositingOperatorNone) { subResult->copyInputBFromA = true; } continue; } if (viewer->isViewerPaused(viewerInputIndex)) { subResult->perInputsData[viewerInputIndex].retCode = eActionStatusAborted; continue; } ViewerInstancePtr viewerProcess = viewer->getViewerProcessNode(viewerInputIndex); subResult->perInputsData[viewerInputIndex].viewerProcessNode = viewerProcess->getNode(); TreeRender::CtorArgsPtr initArgs(new TreeRender::CtorArgs); initArgs->treeRootEffect = viewerProcess; initArgs->provider = provider; initArgs->time = results->time; initArgs->view = subResult->view; // Render by default on disk is always using a mipmap level of 0 but using the proxy scale of the project initArgs->mipMapLevel = mipMapLevel; #pragma message WARN("Todo: set proxy scale here") initArgs->proxyScale = RenderScale(1.); // Render the RoD if fullframe processing if (partialUpdateRoIParam) { initArgs->canonicalRoI = *partialUpdateRoIParam; } else { RectD roi; if (!fullFrameProcessing) { roi = viewerProcess->getViewerRoI(); } initArgs->canonicalRoI = roi; } initArgs->stats = stats; initArgs->activeRotoDrawableItem = activeDrawingStroke; initArgs->draftMode = draftModeEnabled; initArgs->playback = isPlayback; initArgs->byPassCache = byPassCache; initArgs->preventConcurrentTreeRenders = (activeDrawingStroke || partialUpdateRoIParam); if (!isPlayback && subResult->textureTransferType == OpenGLViewerI::TextureTransferArgs::eTextureTransferTypeReplace && !activeDrawingStroke) { subResult->perInputsData[viewerInputIndex].colorPickerNode = viewerInputIndex == 0 ? viewer->getCurrentAInput() : viewer->getCurrentBInput(); if (subResult->perInputsData[viewerInputIndex].colorPickerNode) { // Also sample the "main" input of the color picker node, this is useful for keyers. int mainInput = subResult->perInputsData[viewerInputIndex].colorPickerNode->getPreferredInput(); subResult->perInputsData[viewerInputIndex].colorPickerInputNode = subResult->perInputsData[viewerInputIndex].colorPickerNode->getInput(mainInput); } } if (subResult->perInputsData[viewerInputIndex].colorPickerNode) { initArgs->extraNodesToSample.push_back(subResult->perInputsData[viewerInputIndex].colorPickerNode); } if (subResult->perInputsData[viewerInputIndex].colorPickerInputImage) { initArgs->extraNodesToSample.push_back(subResult->perInputsData[viewerInputIndex].colorPickerInputNode); } subResult->perInputsData[viewerInputIndex].render = TreeRender::create(initArgs); if (!subResult->perInputsData[viewerInputIndex].render) { return eActionStatusFailed; } } // for each viewer input return eActionStatusOK; } // createFrameRenderResultsForView
void CImg::RenderColor(SDL_Rect *fdst, int x, int y,int alpha, int r, int g, int b) { // SDL_SetTextureBlendMode(texture_id,SDL_TEXTUREBLENDMODE_ADD); //hmm // SDL_SetTextureColorMod(texture_id,r,g,b); RenderScale(fdst, x,y,alpha,0); }