void RenderLayerModelObject::willBeDestroyed() { if (isPositioned()) { // Don't use this->view() because the document's renderView has been set to 0 during destruction. if (LocalFrame* frame = this->frame()) { if (FrameView* frameView = frame->view()) { if (style()->hasViewportConstrainedPosition()) frameView->removeViewportConstrainedObject(this); } } } RenderObject::willBeDestroyed(); destroyLayer(); }
void RenderNode::destroyHardwareResources(TreeObserver* observer, TreeInfo* info) { if (mLayer) { destroyLayer(mLayer); mLayer = nullptr; } if (mDisplayList) { for (auto&& child : mDisplayList->getChildren()) { child->renderNode->destroyHardwareResources(observer, info); } if (mNeedsDisplayListSync) { // Next prepare tree we are going to push a new display list, so we can // drop our current one now deleteDisplayList(observer, info); } } }
void RenderWidget::destroy() { // We can't call the base class's destroy because we don't // want to unconditionally delete ourselves (we're ref-counted). // So the code below includes copied and pasted contents of // both RenderBox::destroy() and RenderObject::destroy(). // Fix originally made for <rdar://problem/4228818>. animation()->cancelAnimations(this); if (RenderView* v = view()) v->removeWidget(this); if (AXObjectCache::accessibilityEnabled()) { document()->axObjectCache()->childrenChanged(this->parent()); document()->axObjectCache()->remove(this); } remove(); if (m_widget) { if (m_frameView) m_frameView->removeChild(m_widget.get()); widgetRendererMap().remove(m_widget.get()); } // removes from override size map if (hasOverrideSize()) setOverrideSize(-1); if (style() && (style()->height().isPercent() || style()->minHeight().isPercent() || style()->maxHeight().isPercent())) RenderBlock::removePercentHeightDescendant(this); if (hasLayer()) { layer()->clearClipRects(); setHasLayer(false); destroyLayer(); } // Grab the arena from node()->document()->renderArena() before clearing the node pointer. // Clear the node before deref-ing, as this may be deleted when deref is called. RenderArena* arena = renderArena(); setNode(0); deref(arena); }
bool isJokey(refObject type) { bool found; struct { refFrame link; int count; refObject labeler; } f; // JOKING. Traverse OBJECT and set FOUND to TRUE if we visit a joker. We use a // layer LABELER to avoid being trapped inside circular structures. void joking(refObject term) { if (term != nil && isPair(term) && ! gotKey(toss, toss, f.labeler, term)) { setKey(f.labeler, term, nil, nil); switch (toHook(car(term))) { case arraysHook: case jokerHook: case tuplesHook: { found = true; break; } case referHook: case rowHook: { if (! isForwarded(term)) { joking(cadr(term)); } break; } default: { while (! found && term != nil) { joking(car(term)); term = cdr(term); } break; }}}} // Assume TYPE has no jokers, then try to falsify this assumption. push(f, 1); found = false; f.labeler = pushLayer(nil, plainInfo); joking(type); pop(); destroyLayer(f.labeler); return found; }
// An old map may be passed in to avoid reloading the images for the tilesets. struct Map *loadMap(const char *path, SDL_Renderer *renderer, struct Map *reuse_images){ // Load the int size; struct Turbo_Value mapValue; struct Map *map = NULL; char *const data = BufferFile(path, &size); if(!data){ fprintf(stderr, "Could not open map file %s\n", path); return NULL; } assert(path); Turbo_Parse(&mapValue, data, data + size); if(mapValue.type == TJ_Error){ Turbo_WriteError(&mapValue, stderr, 0); goto ending; } if(mapValue.type != TJ_Object){ fprintf(stderr, "Invalid map object\n"); goto ending; } // Load the tilesets first. { unsigned i; const struct Turbo_Value *const tilesetArray = jsonFindObjectValue(&mapValue, "tilesets"); if(!tilesetArray){ fprintf(stderr, "Invalid map object: no tilesets\n"); goto ending; } else if(tilesetArray->type == TJ_Error){ Turbo_WriteError(&mapValue, stderr, 0); goto ending; } else if(tilesetArray->type != TJ_Array){ fprintf(stderr, "Invalid tileset array\n"); goto ending; } map = malloc(sizeof(struct Map)); map->numTilesets = tilesetArray->length; map->tilesets = calloc(map->numTilesets, sizeof(struct Tileset)); // Load all tilesets. for(i = 0; i < map->numTilesets; i++){ if(!loadTileset(map->tilesets + i, renderer, tilesetArray->value.array + i, reuse_images)){ // Free what we've loaded so far. unsigned e; for(e = 0; e != i; e++){ unsigned j; // If we reused an existing image, don't touch it. for(j = 0; j < reuse_images->numTilesets; j++){ if(reuse_images->tilesets[j].image == map->tilesets[e].image){ map->tilesets[e].image = NULL; map->tilesets[e].imagePath[0] = '\0'; break; } } destroyTileset(map->tilesets + e); } fprintf(stderr, "Error loading tileset %i\n", i); goto error_free_tilesets_only; } } // Change all reused surfaces to avoid any double-frees or use-after-frees. if(reuse_images){ for(i = 0; i < map->numTilesets; i++){ unsigned e; for(e = 0; e < reuse_images->numTilesets; e++){ if(reuse_images->tilesets[e].image == map->tilesets[i].image){ reuse_images->tilesets[e].image = NULL; reuse_images->tilesets[e].imagePath[0] = '\0'; } } } } } // Load layers { const struct Turbo_Value *const layers = jsonFindObjectValue(&mapValue, "layers"); if(!layers || layers->type != TJ_Array){ // Huh. This is at least a warning. fprintf(stderr, "Warning: No layers in map."); map->numLayers = 0; map->layers = NULL; } else{ unsigned i; map->numLayers = layers->length; map->layers = calloc(layers->length, sizeof(struct Layer)); for(i = 0; i < map->numLayers; i++){ if(!loadLayer(map->layers + i, layers->value.array + i)){ unsigned e; for(e = 0; e < i; e++){ destroyLayer(map->layers + e); } free(map->layers); goto error_free_tilesets; } } } } // All OK! goto ending; error_free_tilesets: { unsigned i; for(i = 0; i < map->numTilesets; i++) destroyTileset(map->tilesets + i); } error_free_tilesets_only: free(map->tilesets); error_free_map: free(map); map = NULL; ending: Turbo_FreeParse(&mapValue); FreeBufferFile(data, size); return map; }
refObject skolemize(refObject layer, refObject type) { struct { refFrame link; int count; refObject first; refObject labeler; refObject last; refObject layer; refObject next; refObject type; } f0; // IS SKOLEMIZABLE. Test if TYPE, which is ground in LAYER, can be the base of // a Skolem type. It can be, if it has a subtype that's different from itself. // For example, OBJ has an infinite number of such subtypes but INT0 has none. // The WHILE loop helps simulate tail recursions. bool isSkolemizable(refObject layer, refObject type) { while (true) { if (isName(type)) { getKey(r(layer), r(type), layer, type); } else // Visit a type. If LABELER says we've been here before, then return false. If // we haven't, then record TYPE in LABELER so we won't come here again. if (isPair(type)) { if (gotKey(toss, toss, f0.labeler, type)) { return false; } else { refObject pars; setKey(f0.labeler, type, nil, nil); switch (toHook(car(type))) // Visit a trivially Skolemizable type. An ALTS, FORM, or GEN type can have an // ALTS type as a subtype. A REF or ROW type can have NULL as a subtype. { case altsHook: case arraysHook: case formHook: case genHook: case jokerHook: case referHook: case rowHook: case skoHook: case tuplesHook: { return true; } // Visit a type that is trivially not Skolemizable. case cellHook: case char0Hook: case char1Hook: case int0Hook: case int1Hook: case int2Hook: case listHook: case nullHook: case real0Hook: case real1Hook: case strTypeHook: case symHook: case voidHook: { return false; } // Visit an ARRAY type. It's Skolemizable if its base type is. case arrayHook: { type = caddr(type); break; } // Visit a PROC type. It's Skolemizable if (1) it has a Skolemizable parameter // type, (2) it has the missing name NO NAME as a parameter name, (3) it has a // Skolemizable yield type. case procHook: { type = cdr(type); pars = car(type); while (pars != nil) { pars = cdr(pars); if (car(pars) == noName) { return true; } else { pars = cdr(pars); }} pars = car(type); while (pars != nil) { if (isSkolemizable(layer, car(pars))) { return true; } else { pars = cddr(pars); }} type = cadr(type); break; } // Visit a TUPLE type. It's Skolemizable if it has a Skolemizable slot type or // if it has the missing name NO NAME as a slot name. case tupleHook: { pars = cdr(type); while (pars != nil) { pars = cdr(pars); if (car(pars) == noName) { return true; } else { pars = cdr(pars); }} pars = cdr(type); while (pars != nil) { if (isSkolemizable(layer, car(pars))) { return true; } else { pars = cddr(pars); }} return false; } // Visit a prefix type. It's Skolemizable if its base type is. case typeHook: case varHook: { type = cadr(type); break; } // Visit an illegal type. We should never get here. default: { fail("Got ?%s(...) in isSkolemizable!", hookTo(car(type))); }}}} // Visit an illegal object. We should never get here either. else { fail("Got bad type in isSkolemizable!"); }}} // Lost? This is SKOLEMIZE's body. These identities show what's going on. // // S(type T B) => T S(B) // S(U) => ?sko(U) // S(V) => V // // Here S(X) is the Skolem type for type X. T is a series of zero or more TYPE // prefixes. B is a type, U is a type with at least one subtype different from // itself, and V is a type with no subtypes different from itself. push(f0, 6); f0.labeler = pushLayer(nil, plainInfo); f0.layer = layer; f0.type = type; while (isName(f0.type)) { getKey(r(f0.layer), r(f0.type), f0.layer, f0.type); } if (isCar(f0.type, typeHook)) { f0.type = cadr(f0.type); if (isSkolemizable(f0.layer, f0.type)) { if (isCar(f0.type, typeHook)) { f0.first = f0.last = makePair(hooks[typeHook], nil); f0.type = cadr(f0.type); while (isCar(f0.type, typeHook)) { f0.next = makePair(hooks[typeHook], nil); cdr(f0.last) = makePair(f0.next, nil); f0.last = f0.next; f0.type = cadr(f0.type); } f0.next = makePrefix(skoHook, f0.type); cdr(f0.last) = makePair(f0.next, nil); } else { f0.first = makePrefix(skoHook, f0.type); }} else { f0.first = makePair(car(f0.type), cdr(f0.type)); }} else { fail("Type type expected in skolemize!"); } pop(); destroyLayer(f0.labeler); return f0.first; }
void RenderLayerModelObject::willBeDestroyed() { RenderObject::willBeDestroyed(); destroyLayer(); }
void RenderNode::pushLayerUpdate(TreeInfo& info) { LayerType layerType = properties().effectiveLayerType(); // If we are not a layer OR we cannot be rendered (eg, view was detached) // we need to destroy any Layers we may have had previously if (CC_LIKELY(layerType != LayerType::RenderLayer) || CC_UNLIKELY(!isRenderable())) { if (CC_UNLIKELY(mLayer)) { destroyLayer(mLayer); mLayer = nullptr; } return; } bool transformUpdateNeeded = false; if (!mLayer) { mLayer = createLayer(info.canvasContext.getRenderState(), getWidth(), getHeight()); #if !HWUI_NEW_OPS applyLayerPropertiesToLayer(info); #endif damageSelf(info); transformUpdateNeeded = true; } else if (!layerMatchesWidthAndHeight(mLayer, getWidth(), getHeight())) { #if HWUI_NEW_OPS // TODO: remove now irrelevant, currently enqueued damage (respecting damage ordering) // Or, ideally, maintain damage between frames on node/layer so ordering is always correct RenderState& renderState = mLayer->renderState; if (properties().fitsOnLayer()) { mLayer = renderState.layerPool().resize(mLayer, getWidth(), getHeight()); } else { #else if (!LayerRenderer::resizeLayer(mLayer, getWidth(), getHeight())) { #endif destroyLayer(mLayer); mLayer = nullptr; } damageSelf(info); transformUpdateNeeded = true; } SkRect dirty; info.damageAccumulator->peekAtDirty(&dirty); if (!mLayer) { Caches::getInstance().dumpMemoryUsage(); if (info.errorHandler) { std::ostringstream err; err << "Unable to create layer for " << getName(); const int maxTextureSize = Caches::getInstance().maxTextureSize; if (getWidth() > maxTextureSize || getHeight() > maxTextureSize) { err << ", size " << getWidth() << "x" << getHeight() << " exceeds max size " << maxTextureSize; } else { err << ", see logcat for more info"; } info.errorHandler->onError(err.str()); } return; } if (transformUpdateNeeded && mLayer) { // update the transform in window of the layer to reset its origin wrt light source position Matrix4 windowTransform; info.damageAccumulator->computeCurrentTransform(&windowTransform); mLayer->setWindowTransform(windowTransform); } #if HWUI_NEW_OPS info.layerUpdateQueue->enqueueLayerWithDamage(this, dirty); #else if (dirty.intersect(0, 0, getWidth(), getHeight())) { dirty.roundOut(&dirty); mLayer->updateDeferred(this, dirty.fLeft, dirty.fTop, dirty.fRight, dirty.fBottom); } // This is not inside the above if because we may have called // updateDeferred on a previous prepare pass that didn't have a renderer if (info.renderer && mLayer->deferredUpdateScheduled) { info.renderer->pushLayerUpdate(mLayer); } #endif // There might be prefetched layers that need to be accounted for. // That might be us, so tell CanvasContext that this layer is in the // tree and should not be destroyed. info.canvasContext.markLayerInUse(this); } /** * Traverse down the the draw tree to prepare for a frame. * * MODE_FULL = UI Thread-driven (thus properties must be synced), otherwise RT driven * * While traversing down the tree, functorsNeedLayer flag is set to true if anything that uses the * stencil buffer may be needed. Views that use a functor to draw will be forced onto a layer. */ void RenderNode::prepareTreeImpl(TreeInfo& info, bool functorsNeedLayer) { info.damageAccumulator->pushTransform(this); if (info.mode == TreeInfo::MODE_FULL) { pushStagingPropertiesChanges(info); } uint32_t animatorDirtyMask = 0; if (CC_LIKELY(info.runAnimations)) { animatorDirtyMask = mAnimatorManager.animate(info); } bool willHaveFunctor = false; if (info.mode == TreeInfo::MODE_FULL && mStagingDisplayList) { willHaveFunctor = !mStagingDisplayList->getFunctors().empty(); } else if (mDisplayList) { willHaveFunctor = !mDisplayList->getFunctors().empty(); } bool childFunctorsNeedLayer = mProperties.prepareForFunctorPresence( willHaveFunctor, functorsNeedLayer); if (CC_UNLIKELY(mPositionListener.get())) { mPositionListener->onPositionUpdated(*this, info); } prepareLayer(info, animatorDirtyMask); if (info.mode == TreeInfo::MODE_FULL) { pushStagingDisplayListChanges(info); } prepareSubTree(info, childFunctorsNeedLayer, mDisplayList); pushLayerUpdate(info); info.damageAccumulator->popTransform(); }
int main2(int argc, char **arg){ char* error; int n = 3; /*start OpenGL*/ initOpenGL(); /*testing system compatibility*/ if ((error = test()) != 0){ printf("Error: %s\n", error); return -1; } /*initializing system.*/ if (!init()){ printf("Init not successful..."); return -1; } /*create layers using the sigmoid_sum fragment program.*/ A = generateLayer("sigmoid_sum_masked.fp", 4, 40, 0); B = generateLayer("sigmoid_sum_masked.fp", 40, 16, 0); C = generateLayer("sigmoid_sum_masked.fp", 40, 22, 16); D = generateLayer("sigmoid_sum_masked.fp", 38, 5, 0); E = generateLayer(0, 5, 0, 0); setOutput(A, B); setInput(C, A); setOutput(B, D); setOutput(C, D); setOutput(D, E); /*dummy values.*/ /*fill vectors with values.*/ fillWeights(A); copyWeightsToTexture(weight_matrix, A); copyMaskToTexture(mask_matrix, A); free(weight_matrix); free(mask_matrix); fillWeights(B); copyWeightsToTexture(weight_matrix, B); copyMaskToTexture(mask_matrix, B); free(weight_matrix); free(mask_matrix); fillWeights(C); copyWeightsToTexture(weight_matrix, C); copyMaskToTexture(mask_matrix, C); free(weight_matrix); free(mask_matrix); fillWeights(D); copyWeightsToTexture(weight_matrix, D); copyMaskToTexture(mask_matrix, D); free(mask_matrix); free(weight_matrix); /*Execute the network N times.*/ while (n-->0){ fillVector(A); /*glFinish(); //finish all operations before starting the clock*/ #ifdef WIN32 QueryPerformanceCounter(&start); #else start = clock(); #endif copyVectorToTexture(input, A); run(A); run(B); run(C); run(D); printLayer(E); /*glFinish(); //finish all operations before stopping the clock*/ #ifdef WIN32 QueryPerformanceCounter(&end); QueryPerformanceFrequency( &freq ); printf("Time in s:%f\n", ((double)(end.QuadPart - start.QuadPart))/(double)freq.QuadPart); #else end = clock(); run_time = (end-start)/CLOCKS_PER_SEC*1000; printf("Time in ms: %d\n", (int)run_time); #endif free(input); } /*clean up*/ destroyLayer(A); destroyLayer(B); destroyLayer(C); destroyLayer(D); destroyLayer(E); return 0; }