Beispiel #1
0
/* MapLine::clearUnneededTextures
 * Clears any textures not needed on the line (eg. a front upper
 * texture that would be invisible)
 *******************************************************************/
void MapLine::clearUnneededTextures()
{
	// Check needed textures
	int tex = needsTexture();

	// Clear any unneeded textures
	if (side1)
	{
		if ((tex & TEX_FRONT_MIDDLE) == 0)
			setStringProperty("side1.texturemiddle", "-");
		if ((tex & TEX_FRONT_UPPER) == 0)
			setStringProperty("side1.texturetop", "-");
		if ((tex & TEX_FRONT_LOWER) == 0)
			setStringProperty("side1.texturebottom", "-");
	}
	if (side2)
	{
		if ((tex & TEX_BACK_MIDDLE) == 0)
			setStringProperty("side2.texturemiddle", "-");
		if ((tex & TEX_BACK_UPPER) == 0)
			setStringProperty("side2.texturetop", "-");
		if ((tex & TEX_BACK_LOWER) == 0)
			setStringProperty("side2.texturebottom", "-");
	}
}
Beispiel #2
0
int LayerAndroid::nbTexturedLayers()
{
    int nb = 0;
    int count = this->countChildren();
    for (int i = 0; i < count; i++)
        nb += this->getChild(i)->nbTexturedLayers();
    if (needsTexture())
        nb++;
    return nb;
}
Beispiel #3
0
void Surface::prepareGL(bool layerTilesDisabled, bool updateWithBlit)
{
    bool tilesDisabled = layerTilesDisabled && !isBase();
    if (!m_surfaceBacking) {
        ALOGV("prepareGL on Surf %p, no SurfBack, needsTexture? %d",
              this, m_surfaceBacking, needsTexture());

        if (needsTexture() || (isBase() && layerTilesDisabled))
            m_surfaceBacking = new SurfaceBacking(isBase());
        else
            return;
    }

    if (tilesDisabled) {
        m_surfaceBacking->discardTextures();
    } else {
        bool allowZoom = hasText(); // only allow for scale > 1 if painting vectors
        IntRect prepareArea = computePrepareArea();
        IntRect fullArea = fullContentArea();

        ALOGV("prepareGL on Surf %p with SurfBack %p, %d layers, first layer %s (%d) "
              "prepareArea(%d, %d - %d x %d) fullArea(%d, %d - %d x %d)",
              this, m_surfaceBacking, m_layers.size(),
              getFirstLayer()->subclassName().ascii().data(),
              getFirstLayer()->uniqueId(),
              prepareArea.x(), prepareArea.y(), prepareArea.width(), prepareArea.height(),
              fullArea.x(), fullArea.y(), fullArea.width(), fullArea.height());

        m_surfaceBacking->prepareGL(getFirstLayer()->state(), allowZoom,
                                    prepareArea, fullArea,
                                    this, useAggressiveRendering(), updateWithBlit);
    }
    for (size_t i = 0; i < m_layers.size(); i++) {
        LayerContent* content = m_layers[i]->content();
        if (content)
            content->clearPrerenders();
    }
}
Beispiel #4
0
bool Surface::canUpdateWithBlit()
{
    // If we don't have a texture, we have nothing to update and thus can take
    // the fast path
    if (!needsTexture())
        return true;
    // If we have a surface backing that isn't ready, we can't update with a blit
    // If it is ready, then check to see if it is dirty. We can only call isDirty()
    // if isReady() returns true
    if (!m_surfaceBacking)
        return false;
    if (!m_surfaceBacking->isReady())
        return false;
    if (!m_surfaceBacking->isDirty())
        return true;
    if (!singleLayer())
        return false;
    return getFirstLayer()->canUpdateWithBlit();
}
Beispiel #5
0
void LayerAndroid::showLayer(int indent)
{
    char spaces[256];
    memset(spaces, 0, 256);
    for (int i = 0; i < indent; i++)
        spaces[i] = ' ';

    if (!indent) {
        ALOGD("\n\n--- LAYERS TREE ---");
        IntRect contentViewport(TilesManager::instance()->shader()->contentViewport());
        ALOGD("contentViewport(%d, %d, %d, %d)",
              contentViewport.x(), contentViewport.y(),
              contentViewport.width(), contentViewport.height());
    }

    IntRect r(0, 0, getWidth(), getHeight());
    IntRect tr = m_drawTransform.mapRect(r);
    IntRect visible = visibleContentArea();
    IntRect clip(m_clippingRect.x(), m_clippingRect.y(),
                 m_clippingRect.width(), m_clippingRect.height());
    ALOGD("%s s:%x %s %s (%d) [%d:%x - 0x%x] - %s %s - area (%d, %d, %d, %d) - visible (%d, %d, %d, %d) "
          "clip (%d, %d, %d, %d) %s %s m_content(%x), pic w: %d h: %d originalLayer: %x %d",
          spaces, m_surface, m_haveClip ? "CLIP LAYER" : "", subclassName().ascii().data(),
          subclassType(), uniqueId(), this, m_owningLayer,
          needsTexture() ? "needsTexture" : "",
          m_imageCRC ? "hasImage" : "",
          tr.x(), tr.y(), tr.width(), tr.height(),
          visible.x(), visible.y(), visible.width(), visible.height(),
          clip.x(), clip.y(), clip.width(), clip.height(),
          contentIsScrollable() ? "SCROLLABLE" : "",
          isPositionFixed() ? "FIXED" : "",
          m_content,
          m_content ? m_content->width() : -1,
          m_content ? m_content->height() : -1,
          m_originalLayer, m_originalLayer ? m_originalLayer->uniqueId() : -1);

    int count = this->countChildren();
    for (int i = 0; i < count; i++)
        this->getChild(i)->showLayer(indent + 2);
}
Beispiel #6
0
bool Surface::tryUpdateSurface(Surface* oldSurface)
{
    if (!needsTexture() || !oldSurface->needsTexture())
        return false;

    // merge surfaces based on first layer ID
    if (getFirstLayer()->uniqueId() != oldSurface->getFirstLayer()->uniqueId())
        return false;

    m_surfaceBacking = oldSurface->m_surfaceBacking;
    SkSafeRef(m_surfaceBacking);

    ALOGV("%p taking old SurfBack %p from surface %p, nt %d",
          this, m_surfaceBacking, oldSurface, oldSurface->needsTexture());

    if (!m_surfaceBacking) {
        // no SurfBack to inval, so don't worry about it.
        return true;
    }

    SkRegion invalRegion;
    bool fullInval = false;
    if (singleLayer() && oldSurface->singleLayer()) {
        // both are single matching layers, simply apply inval
        SkRegion* layerInval = getFirstLayer()->getInvalRegion();
        invalRegion = *layerInval;

        if (isBase()) {
            // the base layer paints outside it's content area to ensure the
            // viewport is convered, so fully invalidate all tiles if its size
            // changes to ensure no stale content remains
            LayerContent* newContent = getFirstLayer()->content();
            LayerContent* oldContent = oldSurface->getFirstLayer()->content();
            fullInval = newContent->width() != oldContent->width()
                || newContent->height() != oldContent->height();
        }
    } else {
        fullInval = m_layers.size() != oldSurface->m_layers.size();
        if (!fullInval) {
            for (unsigned int i = 0; i < m_layers.size(); i++) {
                if ((m_layers[i]->uniqueId() != oldSurface->m_layers[i]->uniqueId())
                    || (m_layers[i]->fullContentAreaMapped() != oldSurface->m_layers[i]->fullContentAreaMapped())) {
                    // layer list has changed, fully invalidate
                    // TODO: partially invalidate based on layer size/position
                    fullInval = true;
                    break;
                } else if (!m_layers[i]->getInvalRegion()->isEmpty()) {
                    // merge layer inval - translate the layer's inval region into surface coordinates
                    // TODO: handle scale/3d transform mapping
                    FloatRect layerPos = m_layers[i]->fullContentAreaMapped();
                    m_layers[i]->getInvalRegion()->translate(layerPos.x(), layerPos.y());
                    invalRegion.op(*(m_layers[i]->getInvalRegion()), SkRegion::kUnion_Op);
                }
            }
        }
    }

    if (fullInval)
        invalRegion.setRect(-1e8, -1e8, 2e8, 2e8);

    m_surfaceBacking->markAsDirty(invalRegion);
    return true;
}
Beispiel #7
0
void LayerAndroid::assignSurfaces(LayerMergeState* mergeState)
{
    // recurse through layers in draw order, and merge layers when able

    bool needNewSurface = !mergeState->currentSurface
        || mergeState->nonMergeNestedLevel > 0
        || !canJoinSurface(mergeState->currentSurface);

    if (needNewSurface) {
        mergeState->currentSurface = new Surface();
        mergeState->surfaceList->append(mergeState->currentSurface);
    }

#ifdef LAYER_MERGING_DEBUG
    ALOGD("%*slayer %p(%d) rl %p %s surface %p lvl: %d, fixed %d, anim %d, intCom %d, haveClip %d scroll %d hasText (layer: %d surface: %d) hasContent %d size %.2f x %.2f",
          4*mergeState->depth, "", this, m_uniqueId, m_owningLayer,
          needNewSurface ? "NEW" : "joins", mergeState->currentSurface,
          mergeState->nonMergeNestedLevel,
          isPositionFixed(), m_animations.size() != 0,
          m_intrinsicallyComposited,
          m_haveClip,
          contentIsScrollable(), m_content ? m_content->hasText() : -1,
          mergeState->currentSurface ? mergeState->currentSurface->hasText() : -1,
          needsTexture(), getWidth(), getHeight());
#endif

    mergeState->currentSurface->addLayer(this, m_drawTransform);
    m_surface = mergeState->currentSurface;

    if (hasDynamicTransform()) {
        // disable layer merging within the children of these layer types
        mergeState->nonMergeNestedLevel++;
    }

    // pass the surface through children in drawing order, so that they may
    // attach themselves (and paint on it) if possible, or ignore it and create
    // a new one if not
    int count = this->countChildren();
    if (count > 0) {
        mergeState->depth++;
        Vector <LayerAndroid*> sublayers;
        for (int i = 0; i < count; i++)
            sublayers.append(getChild(i));

        // sort for the transparency
        std::stable_sort(sublayers.begin(), sublayers.end(), compareLayerZ);
        for (int i = 0; i < count; i++)
            sublayers[i]->assignSurfaces(mergeState);
        mergeState->depth--;
    }

    if (hasDynamicTransform()) {
        // re-enable joining
        mergeState->nonMergeNestedLevel--;

        // disallow layers painting after to join with this surface
        mergeState->currentSurface = 0;
    }

    if (needsIsolatedSurface())
        mergeState->currentSurface = 0;

}