bool LayerAndroid::canJoinSurface(Surface* surface) { #ifdef DISABLE_LAYER_MERGE return false; #else // returns true if the layer can be merged onto the surface (group of layers) if (!surface) return false; LayerAndroid* lastLayer = surface->getFirstLayer(); // isolate intrinsically composited layers if (needsIsolatedSurface() || lastLayer->needsIsolatedSurface()) return false; // TODO: investigate potential for combining transformed layers if (!m_drawTransform.isIdentityOrTranslation() || !lastLayer->m_drawTransform.isIdentityOrTranslation()) return false; // TODO: compare other layer properties - fixed? overscroll? transformed? // SAMSUNG CHANGE ++ if(m_drawOpacity <= 0) // google handwriting icon('g') display error. opacity:0 layer is not updated properly due to MergedLayers logic. return false; // SAMSUNG CHANGE -- return true; #endif }
// This is called on the UI thread only. // The video layers are composited on the webkit thread and then copied over // to the UI thread with the same ID. For rendering, we are only using the // video layers on the UI thread. Therefore, on the UI thread, we have to use // the videoLayerId from Java side to find the exact video layer in the tree // to set the surface texture. // Every time a play call into Java side, the videoLayerId will be sent and // saved in Java side. Then every time setBaseLayer call, the saved // videoLayerId will be passed to this function to find the Video Layer. // Return value: true when the video layer is found. static bool SendSurfaceTexture(JNIEnv* env, jobject obj, jobject surfTex, int baseLayer, int videoLayerId, int textureName, int playerState) { if (!surfTex) return false; sp<SurfaceTexture> texture = android::SurfaceTexture_getSurfaceTexture(env, surfTex); if (!texture.get()) return false; BaseLayerAndroid* layerImpl = reinterpret_cast<BaseLayerAndroid*>(baseLayer); if (!layerImpl) return false; if (!layerImpl->countChildren()) return false; LayerAndroid* compositedRoot = static_cast<LayerAndroid*>(layerImpl->getChild(0)); if (!compositedRoot) return false; VideoLayerAndroid* videoLayer = static_cast<VideoLayerAndroid*>(compositedRoot->findById(videoLayerId)); if (!videoLayer) return false; // Set the SurfaceTexture to the layer we found videoLayer->setSurfaceTexture(texture, textureName, static_cast<PlayerState>(playerState)); return true; }
bool BaseLayerAndroid::drawGL(IntRect& viewRect, SkRect& visibleRect, float scale) { XLOG("drawing BLA %p", this); // TODO: consider moving drawBackground outside of prepare (into tree manager) m_state->drawBackground(m_color); drawBasePictureInGL(); bool needsRedraw = false; #if USE(ACCELERATED_COMPOSITING) LayerAndroid* compositedRoot = static_cast<LayerAndroid*>(getChild(0)); if (compositedRoot) { updateLayerPositions(visibleRect); // For now, we render layers only if the rendering mode // is kAllTextures or kClippedTextures if (compositedRoot->drawGL()) { if (TilesManager::instance()->layerTexturesRemain()) { // only try redrawing for layers if layer textures remain, // otherwise we'll repaint without getting anything done needsRedraw = true; } } } #endif // USE(ACCELERATED_COMPOSITING) #ifdef DEBUG ClassTracker::instance()->show(); #endif return needsRedraw; }
void PaintedSurface::prepare(GLWebViewState* state) { XLOG("PS %p has PL %p, DL %p", this, m_paintingLayer, m_drawingLayer); LayerAndroid* paintingLayer = m_paintingLayer; if (!paintingLayer) paintingLayer = m_drawingLayer; if (!paintingLayer) return; bool startFastSwap = false; if (state->isScrolling()) { // when scrolling, block updates and swap tiles as soon as they're ready startFastSwap = true; } XLOG("prepare layer %d %x at scale %.2f", paintingLayer->uniqueId(), paintingLayer, paintingLayer->getScale()); IntRect visibleArea = computeVisibleArea(paintingLayer); IntRect prepareArea = computePrepareArea(paintingLayer); // SAMSUNG CHANGE m_scale = state->scale(); // If we do not have text, we may as well limit ourselves to // a scale factor of one... this saves up textures. if (m_scale > 1 && !paintingLayer->hasText()) m_scale = 1; m_tiledTexture->prepare(state, m_scale, m_pictureUsed != paintingLayer->pictureUsed(), startFastSwap, visibleArea, prepareArea); // SAMSUNG CHANGE }
void TreeManager::updateScrollableLayerInTree(Layer* tree, int layerId, int x, int y) { LayerAndroid* layer; if (tree && tree->countChildren()) { layer = static_cast<LayerAndroid*>(tree->getChild(0))->findById(layerId); if (layer && layer->contentIsScrollable()) static_cast<ScrollableLayerAndroid*>(layer)->scrollTo(x, y); } }
void LayerAndroid::mergeInvalsInto(LayerAndroid* replacementTree) { int count = this->countChildren(); for (int i = 0; i < count; i++) this->getChild(i)->mergeInvalsInto(replacementTree); LayerAndroid* replacementLayer = replacementTree->findById(uniqueId()); if (replacementLayer) replacementLayer->markAsDirty(m_dirtyRegion); }
bool LayerAndroid::visible() { // TODO: avoid climbing tree each access LayerAndroid* current = this; while (current->getParent()) { if (!current->m_visible) return false; current = static_cast<LayerAndroid*>(current->getParent()); } return true; }
void ChromeClientAndroid::enterFullscreenForNode(Node* node) { if (!node->hasTagName(HTMLNames::videoTag)) return; HTMLMediaElement* videoElement = static_cast<HTMLMediaElement*>(node); String url = videoElement->currentSrc(); LayerAndroid* layer = videoElement->platformLayer(); if (!layer) return; FrameView* frameView = m_webFrame->page()->mainFrame()->view(); android::WebViewCore* core = android::WebViewCore::getWebViewCore(frameView); if (core) core->enterFullscreenForVideoLayer(layer->uniqueId(), url); }
void GraphicsLayerAndroid::syncChildren() { if (m_needsSyncChildren) { m_contentLayer->removeChildren(); LayerAndroid* layer = m_contentLayer; if (m_foregroundClipLayer) { m_contentLayer->addChild(m_foregroundClipLayer); // Use the scrollable content layer as the parent of the children so // that they move with the content. layer = m_foregroundLayer; layer->removeChildren(); } for (unsigned int i = 0; i < m_children.size(); i++) layer->addChild(m_children[i]->platformLayer()); m_needsSyncChildren = false; } }
bool BaseLayerAndroid::prepare(double currentTime, IntRect& viewRect, SkRect& visibleRect, float scale) { XLOG("preparing BLA %p", this); // base layer is simply drawn in prepare, since there is always a base layer it doesn't matter bool needsRedraw = prepareBasePictureInGL(visibleRect, scale, currentTime); LayerAndroid* compositedRoot = static_cast<LayerAndroid*>(getChild(0)); if (compositedRoot) { updateLayerPositions(visibleRect); XLOG("preparing BLA %p, root %p", this, compositedRoot); compositedRoot->prepare(); } return needsRedraw; }
bool LayerAndroid::drawChildrenCanvas(SkCanvas* canvas, PaintStyle style) { bool askScreenUpdate = false; int count = this->countChildren(); if (count > 0) { Vector <LayerAndroid*> sublayers; for (int i = 0; i < count; i++) sublayers.append(this->getChild(i)); // now we sort for the transparency std::stable_sort(sublayers.begin(), sublayers.end(), compareLayerZ); for (int i = 0; i < count; i++) { LayerAndroid* layer = sublayers[i]; askScreenUpdate |= layer->drawCanvas(canvas, true, style); } } return askScreenUpdate; }
LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer), m_isRootLayer(layer.m_isRootLayer), m_haveClip(layer.m_haveClip), m_extra(0), // deliberately not copied m_uniqueId(layer.m_uniqueId) { m_doRotation = layer.m_doRotation; m_isFixed = layer.m_isFixed; m_angleTransform = layer.m_angleTransform; m_translation = layer.m_translation; m_scale = layer.m_scale; m_backgroundColor = layer.m_backgroundColor; m_fixedLeft = layer.m_fixedLeft; m_fixedTop = layer.m_fixedTop; m_fixedRight = layer.m_fixedRight; m_fixedBottom = layer.m_fixedBottom; m_fixedMarginLeft = layer.m_fixedMarginLeft; m_fixedMarginTop = layer.m_fixedMarginTop; m_fixedMarginRight = layer.m_fixedMarginRight; m_fixedMarginBottom = layer.m_fixedMarginBottom; m_fixedOffset = layer.m_fixedOffset; m_fixedWidth = layer.m_fixedWidth; m_fixedHeight = layer.m_fixedHeight; m_recordingPicture = layer.m_recordingPicture; SkSafeRef(m_recordingPicture); #if ENABLE(WEBGL) m_context = layer.m_context; #endif for (int i = 0; i < layer.countChildren(); i++) addChild(new LayerAndroid(*layer.getChild(i)))->unref(); KeyframesMap::const_iterator end = layer.m_animations.end(); for (KeyframesMap::const_iterator it = layer.m_animations.begin(); it != end; ++it) m_animations.add((it->second)->name(), (it->second)->copy()); gDebugLayerAndroidInstances++; }
bool BaseLayerAndroid::isReady() { ZoomManager* zoomManager = m_state->zoomManager(); if (ZoomManager::kNoScaleRequest != zoomManager->scaleRequestState()) { XLOG("base layer not ready, still zooming"); return false; // still zooming } if (!m_state->frontPage()->isReady(m_state->preZoomBounds())) { XLOG("base layer not ready, front page not done painting"); return false; } LayerAndroid* compositedRoot = static_cast<LayerAndroid*>(getChild(0)); if (compositedRoot) { XLOG("base layer is ready, how about children?"); return compositedRoot->isReady(); } return true; }
void BaseLayerAndroid::updateLayerPositions(SkRect& visibleRect) { LayerAndroid* compositedRoot = static_cast<LayerAndroid*>(getChild(0)); TransformationMatrix ident; compositedRoot->updateFixedLayersPositions(visibleRect); FloatRect clip(0, 0, content()->width(), content()->height()); compositedRoot->updateGLPositionsAndScale( ident, clip, 1, m_state->zoomManager()->layersScale()); #ifdef DEBUG compositedRoot->showLayer(0); XLOG("We have %d layers, %d textured", compositedRoot->nbLayers(), compositedRoot->nbTexturedLayers()); #endif }
void PaintedSurface::computeTexturesAmount(TexturesResult* result) { if (!m_tiledTexture) return; // for now, always done on drawinglayer LayerAndroid* layer = m_drawingLayer; if (!layer) return; IntRect unclippedArea = layer->unclippedArea(); IntRect clippedVisibleArea = layer->visibleArea(); // get two numbers here: // - textures needed for a clipped area // - textures needed for an un-clipped area int nbTexturesUnclipped = m_tiledTexture->nbTextures(unclippedArea, m_scale); int nbTexturesClipped = m_tiledTexture->nbTextures(clippedVisibleArea, m_scale); // Set kFixedLayers level if (layer->isFixed()) result->fixed += nbTexturesClipped; // Set kScrollableAndFixedLayers level if (layer->contentIsScrollable() || layer->isFixed()) result->scrollable += nbTexturesClipped; // Set kClippedTextures level result->clipped += nbTexturesClipped; // Set kAllTextures level if (layer->contentIsScrollable()) result->full += nbTexturesClipped; else result->full += nbTexturesUnclipped; }
void SurfaceCollection::updateScrollableLayer(int layerId, int x, int y) { LayerAndroid* layer = m_compositedRoot->findById(layerId); if (layer && layer->contentIsScrollable()) static_cast<ScrollableLayerAndroid*>(layer)->scrollTo(x, y); }
LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer), m_uniqueId(layer.m_uniqueId), m_haveClip(layer.m_haveClip), m_backfaceVisibility(layer.m_backfaceVisibility), m_visible(layer.m_visible), m_backgroundColor(layer.m_backgroundColor), m_preserves3D(layer.m_preserves3D), m_anchorPointZ(layer.m_anchorPointZ), m_isPositionAbsolute(layer.m_isPositionAbsolute), m_fixedPosition(0), m_zValue(layer.m_zValue), m_content(layer.m_content), m_imageCRC(layer.m_imageCRC), m_scale(layer.m_scale), m_lastComputeTextureSize(0), m_owningLayer(layer.m_owningLayer), m_type(LayerAndroid::UILayer), m_intrinsicallyComposited(layer.m_intrinsicallyComposited), m_surface(0), m_replicatedLayer(0), m_originalLayer(0), m_maskLayer(0) { if (m_imageCRC) ImagesManager::instance()->retainImage(m_imageCRC); SkSafeRef(m_content); if (layer.m_fixedPosition) { m_fixedPosition = layer.m_fixedPosition->copy(this); Layer::setShouldInheritFromRootTransform(true); } m_transform = layer.m_transform; m_drawTransform = layer.m_drawTransform; m_drawTransformUnfudged = layer.m_drawTransformUnfudged; m_childrenTransform = layer.m_childrenTransform; m_dirtyRegion = layer.m_dirtyRegion; m_replicatedLayerPosition = layer.m_replicatedLayerPosition; #ifdef ABSOLUTE_POSITION // If we have absolute elements, we may need to reorder them if they // are followed by another layer that is not also absolutely positioned. // (as absolutely positioned elements are out of the normal flow) bool hasAbsoluteChildren = false; bool hasOnlyAbsoluteFollowers = true; for (int i = 0; i < layer.countChildren(); i++) { if (layer.getChild(i)->isPositionAbsolute()) { hasAbsoluteChildren = true; continue; } if (hasAbsoluteChildren && !layer.getChild(i)->isPositionAbsolute()) { hasOnlyAbsoluteFollowers = false; break; } } if (hasAbsoluteChildren && !hasOnlyAbsoluteFollowers) { Vector<LayerAndroid*> normalLayers; Vector<LayerAndroid*> absoluteLayers; for (int i = 0; i < layer.countChildren(); i++) { LayerAndroid* child = layer.getChild(i); if (child->isPositionAbsolute() || child->isPositionFixed()) absoluteLayers.append(child); else normalLayers.append(child); } for (unsigned int i = 0; i < normalLayers.size(); i++) addChild(normalLayers[i]->copy())->unref(); for (unsigned int i = 0; i < absoluteLayers.size(); i++) addChild(absoluteLayers[i]->copy())->unref(); } else { for (int i = 0; i < layer.countChildren(); i++) addChild(layer.getChild(i)->copy())->unref(); } #else for (int i = 0; i < layer.countChildren(); i++) addChild(layer.getChild(i)->copy())->unref(); #endif KeyframesMap::const_iterator end = layer.m_animations.end(); for (KeyframesMap::const_iterator it = layer.m_animations.begin(); it != end; ++it) { m_animations.add(it->first, it->second); } if (layer.m_replicatedLayer) { // The replicated layer is always the first child m_replicatedLayer = getChild(0); m_replicatedLayer->setOriginalLayer(this); } if (layer.m_maskLayer) m_maskLayer = layer.m_maskLayer->copy(); #ifdef DEBUG_COUNT ClassTracker::instance()->increment("LayerAndroid - recopy (UI)"); ClassTracker::instance()->add(this); #endif }
LayerAndroid* deserializeLayer(int version, SkStream* stream) { int type = stream->readU8(); if (type == LTNone) return 0; // Cast is to disambiguate between ctors. LayerAndroid *layer; if (type == LTLayerAndroid) layer = new LayerAndroid((RenderLayer*) 0); else if (type == LTScrollableLayerAndroid) layer = new ScrollableLayerAndroid((RenderLayer*) 0); else { ALOGV("Unexpected layer type: %d, aborting!", type); return 0; } // Layer fields layer->setShouldInheritFromRootTransform(stream->readBool()); layer->setOpacity(stream->readScalar()); layer->setSize(stream->readScalar(), stream->readScalar()); layer->setPosition(stream->readScalar(), stream->readScalar()); layer->setAnchorPoint(stream->readScalar(), stream->readScalar()); layer->setMatrix(readMatrix(stream)); layer->setChildrenMatrix(readMatrix(stream)); // LayerAndroid fields layer->m_haveClip = stream->readBool(); // Keep the legacy serialization/deserialization format... bool isFixed = stream->readBool(); layer->m_backgroundColorSet = stream->readBool(); bool isIframe = stream->readBool(); // If we are a scrollable layer android, we are an iframe content if (isIframe && type == LTScrollableLayerAndroid) { IFrameContentLayerAndroid* iframeContent = new IFrameContentLayerAndroid(*layer); layer->unref(); layer = iframeContent; } else if (isIframe) { // otherwise we are just the iframe (we use it to compute offset) IFrameLayerAndroid* iframe = new IFrameLayerAndroid(*layer); layer->unref(); layer = iframe; } if (isFixed) { FixedPositioning* fixedPosition = new FixedPositioning(layer); fixedPosition->m_fixedLeft = readSkLength(stream); fixedPosition->m_fixedTop = readSkLength(stream); fixedPosition->m_fixedRight = readSkLength(stream); fixedPosition->m_fixedBottom = readSkLength(stream); fixedPosition->m_fixedMarginLeft = readSkLength(stream); fixedPosition->m_fixedMarginTop = readSkLength(stream); fixedPosition->m_fixedMarginRight = readSkLength(stream); fixedPosition->m_fixedMarginBottom = readSkLength(stream); fixedPosition->m_fixedRect = readSkRect(stream); fixedPosition->m_renderLayerPos.setX(stream->readS32()); fixedPosition->m_renderLayerPos.setY(stream->readS32()); layer->setFixedPosition(fixedPosition); } else { // Not a fixed element, bypass the values in the stream readSkLength(stream); // fixedLeft readSkLength(stream); // fixedTop readSkLength(stream); // fixedRight readSkLength(stream); // fixedBottom readSkLength(stream); // fixedMarginLeft readSkLength(stream); // fixedMarginTop readSkLength(stream); // fixedMarginRight readSkLength(stream); // fixedMarginBottom readSkRect(stream); // fixedRect stream->readS32(); // renderLayerPos.x() stream->readS32(); // renderLayerPos.y() } layer->m_backfaceVisibility = stream->readBool(); layer->m_visible = stream->readBool(); layer->m_backgroundColor = stream->readU32(); layer->m_preserves3D = stream->readBool(); layer->m_anchorPointZ = stream->readScalar(); layer->m_drawOpacity = stream->readScalar(); bool hasContentsImage = stream->readBool(); if (hasContentsImage) { int size = stream->readU32(); SkAutoMalloc storage(size); stream->read(storage.get(), size); SkFlattenableReadBuffer buffer(storage.get(), size); SkBitmap contentsImage; contentsImage.unflatten(buffer); SkBitmapRef* imageRef = new SkBitmapRef(contentsImage); layer->setContentsImage(imageRef); delete imageRef; } bool hasRecordingPicture = stream->readBool(); if (hasRecordingPicture) { SkPicture* picture = new SkPicture(stream); PictureLayerContent* content = new PictureLayerContent(picture); layer->setContent(content); SkSafeUnref(content); SkSafeUnref(picture); } int animationCount = stream->readU32(); // TODO: Support (maybe?) readTransformationMatrix(stream, layer->m_transform); readTransformationMatrix(stream, layer->m_childrenTransform); if (type == LTScrollableLayerAndroid) { ScrollableLayerAndroid* scrollableLayer = static_cast<ScrollableLayerAndroid*>(layer); scrollableLayer->m_scrollLimits.set( stream->readScalar(), stream->readScalar(), stream->readScalar(), stream->readScalar()); } int childCount = stream->readU32(); for (int i = 0; i < childCount; i++) { LayerAndroid *childLayer = deserializeLayer(version, stream); if (childLayer) layer->addChild(childLayer); } ALOGV("Created layer with id %d", layer->uniqueId()); return layer; }
LayerAndroid* deserializeLayer(SkStream* stream) { int type = stream->readU8(); if (type == LTNone) return 0; // Cast is to disambiguate between ctors. LayerAndroid *layer; if (type == LTLayerAndroid) layer = new LayerAndroid((RenderLayer*) 0); else if (type == LTScrollableLayerAndroid) layer = new ScrollableLayerAndroid((RenderLayer*) 0); else { XLOG("Unexpected layer type: %d, aborting!", type); return 0; } // Layer fields layer->setShouldInheritFromRootTransform(stream->readBool()); layer->setOpacity(stream->readScalar()); layer->setSize(stream->readScalar(), stream->readScalar()); layer->setPosition(stream->readScalar(), stream->readScalar()); layer->setAnchorPoint(stream->readScalar(), stream->readScalar()); layer->setMatrix(readMatrix(stream)); layer->setChildrenMatrix(readMatrix(stream)); // LayerAndroid fields layer->m_haveClip = stream->readBool(); layer->m_isFixed = stream->readBool(); layer->m_backgroundColorSet = stream->readBool(); layer->m_isIframe = stream->readBool(); layer->m_fixedLeft = readSkLength(stream); layer->m_fixedTop = readSkLength(stream); layer->m_fixedRight = readSkLength(stream); layer->m_fixedBottom = readSkLength(stream); layer->m_fixedMarginLeft = readSkLength(stream); layer->m_fixedMarginTop = readSkLength(stream); layer->m_fixedMarginRight = readSkLength(stream); layer->m_fixedMarginBottom = readSkLength(stream); layer->m_fixedRect = readSkRect(stream); layer->m_renderLayerPos.setX(stream->readS32()); layer->m_renderLayerPos.setY(stream->readS32()); layer->m_backfaceVisibility = stream->readBool(); layer->m_visible = stream->readBool(); layer->m_backgroundColor = stream->readU32(); layer->m_preserves3D = stream->readBool(); layer->m_anchorPointZ = stream->readScalar(); layer->m_drawOpacity = stream->readScalar(); bool hasContentsImage = stream->readBool(); if (hasContentsImage) { int size = stream->readU32(); SkAutoMalloc storage(size); stream->read(storage.get(), size); SkFlattenableReadBuffer buffer(storage.get(), size); SkBitmap contentsImage; contentsImage.unflatten(buffer); SkBitmapRef* imageRef = new SkBitmapRef(contentsImage); layer->setContentsImage(imageRef); delete imageRef; } bool hasRecordingPicture = stream->readBool(); if (hasRecordingPicture) { layer->m_recordingPicture = new SkPicture(stream); } int animationCount = stream->readU32(); // TODO: Support (maybe?) readTransformationMatrix(stream, layer->m_transform); readTransformationMatrix(stream, layer->m_childrenTransform); if (type == LTScrollableLayerAndroid) { ScrollableLayerAndroid* scrollableLayer = static_cast<ScrollableLayerAndroid*>(layer); scrollableLayer->m_scrollLimits.set( stream->readScalar(), stream->readScalar(), stream->readScalar(), stream->readScalar()); } int childCount = stream->readU32(); for (int i = 0; i < childCount; i++) { LayerAndroid *childLayer = deserializeLayer(stream); if (childLayer) layer->addChild(childLayer); } layer->needsRepaint(); XLOG("Created layer with id %d", layer->uniqueId()); return layer; }
bool TreeManager::drawGL(double currentTime, IntRect& viewRect, SkRect& visibleRect, float scale, bool enterFastSwapMode, bool* treesSwappedPtr, bool* newTreeHasAnimPtr, TexturesResult* texturesResultPtr) { m_fastSwapMode |= enterFastSwapMode; XLOG("drawGL, D %p, P %p, Q %p, fastSwap %d", m_drawingTree, m_paintingTree, m_queuedTree, m_fastSwapMode); bool ret = false; bool didTreeSwap = false; if (m_paintingTree) { XLOG("preparing painting tree %p", m_paintingTree); LayerAndroid* laTree = 0; if (m_paintingTree->countChildren()) { laTree = static_cast<LayerAndroid*>(m_paintingTree->getChild(0)); ret |= laTree->evaluateAnimations(currentTime); } ret |= m_paintingTree->prepare(currentTime, viewRect, visibleRect, scale); if (laTree) laTree->computeTexturesAmount(texturesResultPtr); if (/*!m_fastSwapMode && */ m_paintingTree->isReady()) { XLOG("have painting tree %p ready, swapping!", m_paintingTree); didTreeSwap = true; swap(); if (treesSwappedPtr) *treesSwappedPtr = true; if (laTree && newTreeHasAnimPtr) *newTreeHasAnimPtr = laTree->hasAnimations(); } } else if (m_drawingTree) { XLOG("preparing drawing tree %p", m_drawingTree); ret |= m_drawingTree->prepare(currentTime, viewRect, visibleRect, scale); if (m_drawingTree->countChildren()) { LayerAndroid* laTree = static_cast<LayerAndroid*>(m_drawingTree->getChild(0)); laTree->computeTexturesAmount(texturesResultPtr); } } if (m_drawingTree) { bool drawingReady = didTreeSwap || m_drawingTree->isReady(); if (didTreeSwap || m_fastSwapMode || (drawingReady && !m_paintingTree)) m_drawingTree->swapTiles(); if (drawingReady) { // exit fast swap mode, as content is up to date m_fastSwapMode = false; } else { // drawing isn't ready, must redraw ret = true; } if (m_drawingTree->countChildren()) { LayerAndroid* laTree = static_cast<LayerAndroid*>(m_drawingTree->getChild(0)); ret |= laTree->evaluateAnimations(currentTime); } XLOG("drawing tree %p", m_drawingTree); ret |= m_drawingTree->drawGL(viewRect, visibleRect, scale); } else if (m_paintingTree && m_paintingTree->state()) { // Dont have a drawing tree, draw white background Color defaultBackground = Color::white; m_paintingTree->state()->drawBackground(defaultBackground); } if (m_paintingTree) { XLOG("still have painting tree %p", m_paintingTree); return true; } return ret; }