Esempio n. 1
0
IntRect Surface::computePrepareArea()
{
    IntRect area;

    if (!getFirstLayer()->contentIsScrollable()
        && !isBase()
        && getFirstLayer()->state()->layersRenderingMode() == GLWebViewState::kAllTextures) {

        area = fullContentArea();

        double total = ((double) area.width()) * ((double) area.height());
        if (total > MAX_FULL_CONTENT_AREA)
            area = visibleContentArea();
        /// M: Willy, limit the max number of tile is 64. @{
        else {
            float scale = getFirstLayer()->state()->scale();
            int x = ((double)area.width() * scale) / TilesManager::tileWidth();
            int y = ((double)area.height() * scale) / TilesManager::tileHeight();
            if ((x * y) > 64) {
                IntRect a = visibleContentArea();
                IntRect tmpArea = a;
                tmpArea.inflateX(TilesManager::tileWidth() << 1);
                tmpArea.inflateY(TilesManager::tileHeight() << 1);
                tmpArea.intersect(area);
                area = tmpArea;
            }
        }
        /// @}
    } else
        area = visibleContentArea();

    return area;
}
Esempio n. 2
0
bool Surface::paint(SkCanvas* canvas)
{
    if (singleLayer()) {
        getFirstLayer()->contentDraw(canvas, Layer::UnmergedLayers);

        // TODO: double buffer by disabling SurfaceCollection swaps and position
        // updates until painting complete

        // In single surface mode, draw layer content onto the base layer
        if (isBase()
            && getFirstLayer()->countChildren()
            && getFirstLayer()->state()->isSingleSurfaceRenderingMode()) {
            for (int i = 0; i < getFirstLayer()->countChildren(); i++)
                getFirstLayer()->getChild(i)->drawCanvas(canvas, true, Layer::FlattenedLayers);
        }
    } else {
        SkAutoCanvasRestore acr(canvas, true);
        SkMatrix matrix;
        GLUtils::toSkMatrix(matrix, m_drawTransform);

        SkMatrix inverse;
        inverse.reset();
        matrix.invert(&inverse);

        SkMatrix canvasMatrix = canvas->getTotalMatrix();
        inverse.postConcat(canvasMatrix);
        canvas->setMatrix(inverse);

        for (unsigned int i=0; i<m_layers.size(); i++)
            m_layers[i]->drawCanvas(canvas, false, Layer::MergedLayers);
    }
    return true;
}
Esempio n. 3
0
bool Surface::blitFromContents(Tile* tile)
{
    if (!singleLayer() || !tile || !getFirstLayer() || !getFirstLayer()->content())
        return false;
    LayerContent* content = getFirstLayer()->content();
    // Extract the dirty rect from the region. Note that this is *NOT* constrained
    // to this tile
    IntRect dirtyRect = tile->dirtyArea().getBounds();
    IntRect tileRect = IntRect(tile->x() * TilesManager::tileWidth(),
                               tile->y() * TilesManager::tileHeight(),
                               TilesManager::tileWidth(),
                               TilesManager::tileHeight());
    FloatRect tileRectInDoc = tileRect;
    tileRectInDoc.scale(1 / tile->scale());
    dirtyRect.intersect(enclosingIntRect(tileRectInDoc));
    PrerenderedInval* prerenderedInval = content->prerenderForRect(dirtyRect);
    if (!prerenderedInval || prerenderedInval->bitmap.isNull())
        return false;
    SkBitmap sourceBitmap = prerenderedInval->bitmap;
    // Calculate the screen rect that is dirty, then intersect it with the
    // tile's screen rect so that we end up with the pixels we need to blit
    FloatRect screenDirty = dirtyRect;
    screenDirty.scale(tile->scale());
    IntRect enclosingScreenDirty = enclosingIntRect(screenDirty);
    enclosingScreenDirty.intersect(tileRect);
    if (enclosingScreenDirty.isEmpty())
        return false;
    // Make sure the screen area we want to blit is contained by the
    // prerendered screen area
    if (!prerenderedInval->screenArea.contains(enclosingScreenDirty)) {
        ALOGD("prerendered->screenArea " INT_RECT_FORMAT " doesn't contain "
              "enclosingScreenDirty " INT_RECT_FORMAT,
              INT_RECT_ARGS(prerenderedInval->screenArea),
              INT_RECT_ARGS(enclosingScreenDirty));
        return false;
    }
    IntPoint origin = prerenderedInval->screenArea.location();
    SkBitmap subset;
    subset.setConfig(sourceBitmap.config(), enclosingScreenDirty.width(),
                     enclosingScreenDirty.height());
    subset.allocPixels();

    int topOffset = enclosingScreenDirty.y() - prerenderedInval->screenArea.y();
    int leftOffset = enclosingScreenDirty.x() - prerenderedInval->screenArea.x();
    if (!GLUtils::deepCopyBitmapSubset(sourceBitmap, subset, leftOffset, topOffset))
        return false;
    // Now upload
    SkIRect textureInval = SkIRect::MakeXYWH(enclosingScreenDirty.x() - tileRect.x(),
                           enclosingScreenDirty.y() - tileRect.y(),
                           enclosingScreenDirty.width(),
                           enclosingScreenDirty.height());
    GLUtils::updateTextureWithBitmap(tile->frontTexture()->m_ownTextureId,
                                     subset, textureInval);
    tile->onBlitUpdate();
    return true;
}
Esempio n. 4
0
Cluster * Track::getExtrapolatedClusterAt(Float_t mmBeforeDetector) {
   Int_t    firstLayer = getFirstLayer();
   Int_t    firstIdx = getClusterFromLayer(firstLayer);
   Int_t    nextIdx = 0;
   Float_t  diffx, diffy, diffz;
   Float_t  extra_mm = getLayermm(firstLayer);

   for (Int_t i=firstIdx+1; i<GetEntriesFast(); i++) {
      if (!At(i)) continue;

      nextIdx = i;
      break;
   }
   
   Cluster *first = At(firstIdx);
   Cluster *next = At(nextIdx);

   diffz = (next->getLayermm() - first->getLayermm());
   diffx = (first->getX() - next->getX()) / diffz;
   diffy = (first->getY() - next->getY()) / diffz;

   Float_t new_x = first->getX() + diffx * (mmBeforeDetector + extra_mm);
   Float_t new_y = first->getY() + diffy * (mmBeforeDetector + extra_mm);

   Cluster *extrapolated = new Cluster(new_x, new_y); 
   
   return extrapolated;
}
Esempio n. 5
0
bool Surface::isBase()
{
    // base layer surface
    // - doesn't use layer tiles (disables blending, doesn't compute textures amount)
    // - ignores clip rects
    // - only prepares clippedArea
    return getFirstLayer()->subclassType() == LayerAndroid::BaseLayer;
}
Esempio n. 6
0
IntRect Surface::computePrepareArea()
{
    IntRect area;

    if (!getFirstLayer()->contentIsScrollable()
        && !isBase()
        && getFirstLayer()->state()->layersRenderingMode() == GLWebViewState::kAllTextures) {

        area = fullContentArea();

        double total = ((double) area.width()) * ((double) area.height());
        if (total > MAX_FULL_CONTENT_AREA)
            area = visibleContentArea();
    } else
        area = visibleContentArea();

    return area;
}
Esempio n. 7
0
IntRect Surface::computePrepareArea()
{
    IntRect area;

    if (!getFirstLayer()->contentIsScrollable()
        && !isBase()
        && getFirstLayer()->state()->layersRenderingMode() == GLWebViewState::kAllTextures) {

        area = fullContentArea();

        double total = ((double) area.width()) * ((double) area.height());
        // CAPP_WEB_PREPARE_VISIBLE_AREA
        if (total > MAX_FULL_CONTENT_AREA|| m_drawTransform.isIdentityOrTranslation())
            area = visibleContentArea();
    } else
        area = visibleContentArea();

    return area;
}
Esempio n. 8
0
const TransformationMatrix* Surface::drawTransform()
{
    // single layer surfaces query the layer's draw transform, while multi-layer
    // surfaces copy the draw transform once, during initialization
    // TODO: support fixed multi-layer surfaces by querying the changing drawTransform
    if (singleLayer())
        return getFirstLayer()->drawTransform();

    return &m_drawTransform;
}
Esempio n. 9
0
bool Surface::drawGL(bool layerTilesDisabled)
{
    bool tilesDisabled = layerTilesDisabled && !isBase();
    // SAMSUNG CHANGE ++ : google handwriting 'g' icon display issue, Youtube.com 356x2 height line display issue
	// This patch should be applied with DEV CL 56175
	// WAS:if (singleLayer() && !getFirstLayer()->visible())
	if (singleLayer() && (!getFirstLayer()->visible() || getFirstLayer()->drawOpacity() <= 0.0f))
        return false;
	//SAMSUNG CHANGE --

    if (!isBase()) {
        FloatRect drawClip = getFirstLayer()->drawClip();
        if (!singleLayer()) {
            for (unsigned int i = 1; i < m_layers.size(); i++)
                drawClip.unite(m_layers[i]->drawClip());
        }
        FloatRect clippingRect = TilesManager::instance()->shader()->rectInInvViewCoord(drawClip);
        TilesManager::instance()->shader()->clip(clippingRect);
    }

    bool askRedraw = false;
    if (m_surfaceBacking && !tilesDisabled) {
        ALOGV("drawGL on Surf %p with SurfBack %p, first layer %s (%d)", this, m_surfaceBacking,
              getFirstLayer()->subclassName().ascii().data(), getFirstLayer()->uniqueId());

        bool force3dContentVisible = true;
        IntRect drawArea = visibleContentArea(force3dContentVisible);
        m_surfaceBacking->drawGL(drawArea, opacity(), drawTransform(),
                                 useAggressiveRendering(), background());
    }

    // draw member layers (draws image textures, glextras)
    for (unsigned int i = 0; i < m_layers.size(); i++) {
        if (m_layers[i]->drawGL(tilesDisabled)) {
           m_layers[i]->addDirtyArea();
           askRedraw = true;
        }
    }

    return askRedraw;
}
Esempio n. 10
0
void Surface::computeTexturesAmount(TexturesResult* result)
{
    if (!m_surfaceBacking || isBase())
        return;


    LayerAndroid* layer = 0;
    if (singleLayer())
        layer = getFirstLayer();

    m_surfaceBacking->computeTexturesAmount(result, visibleContentArea(),
                                            fullContentArea(), layer);
}
Esempio n. 11
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();
    }
}
Esempio n. 12
0
bool Surface::drawGL(bool layerTilesDisabled)
{
    bool tilesDisabled = layerTilesDisabled && !isBase();
    if (singleLayer() && !getFirstLayer()->visible())
        return false;

    if (!isBase()) {
        FloatRect drawClip = getFirstLayer()->drawClip();
        if (!singleLayer()) {
            for (unsigned int i = 1; i < m_layers.size(); i++)
                drawClip.unite(m_layers[i]->drawClip());
        }
        FloatRect clippingRect = TilesManager::instance()->shader()->rectInInvViewCoord(drawClip);
        TilesManager::instance()->shader()->clip(clippingRect);
    }

    bool askRedraw = false;
    if (m_surfaceBacking && !tilesDisabled) {
        ALOGV("drawGL on Surf %p with SurfBack %p, first layer %s (%d)", this, m_surfaceBacking,
              getFirstLayer()->subclassName(), getFirstLayer()->uniqueId());

        bool force3dContentVisible = true;
        IntRect drawArea = visibleContentArea(force3dContentVisible);
        m_surfaceBacking->drawGL(drawArea, opacity(), drawTransform(),
                                 useAggressiveRendering(), background());
    }

    // draw member layers (draws image textures, glextras)
    for (unsigned int i = 0; i < m_layers.size(); i++) {
        if (m_layers[i]->drawGL(tilesDisabled)) {
           m_layers[i]->addDirtyArea();
           askRedraw = true;
        }
    }

    return askRedraw;
}
Esempio n. 13
0
IntRect Surface::visibleContentArea(bool force3dContentVisible) const
{
    if (singleLayer())
        return getFirstLayer()->visibleContentArea(force3dContentVisible);

    IntRect rect = m_fullContentArea;

    // clip with the viewport in content coordinate
    IntRect contentViewport(TilesManager::instance()->shader()->contentViewport());
    rect.intersect(contentViewport);

    // TODO: handle recursive layer clip

    return rect;
}
Esempio n. 14
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();
}
Esempio n. 15
0
Cluster * Track::getInterpolatedClusterAt(Int_t layer) {
   Cluster   * pre = 0;
   Cluster   * post = 0;
   Int_t       lastIdx = 0;
   Int_t       firstLayer = getFirstLayer();
   Int_t       lastLayer = getLastLayer();
   Int_t       firstIdx = getClusterFromLayer(firstLayer);
   Float_t     x, y;
   
   if (firstLayer == layer) return 0;
   if (lastLayer <= layer) return 0;
   
   for (Int_t i=firstIdx; i<GetEntriesFast(); i++) {
      if (!At(i)) continue;

      if (getLayer(i) > layer) {
         post = At(i);
         lastIdx = i;
         break;
      }
   }

   for (Int_t i=lastIdx; i>=firstIdx; i--) {
      if (!At(i)) continue;

      if (getLayer(i) < layer) {
         pre = At(i);
         break;
      }
   }

   x = ( pre->getX() + post->getX() ) / 2.;
   y = ( pre->getY() + post->getY() ) / 2.;

   return new Cluster(x, y, layer);
}
Esempio n. 16
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;
}
Esempio n. 17
0
float Surface::opacity()
{
    if (singleLayer())
        return getFirstLayer()->drawOpacity();
    return 1.0;
}
Esempio n. 18
0
bool Surface::blitFromContents(Tile* tile)
{
    if (!singleLayer() || !tile || !getFirstLayer() || !getFirstLayer()->content())
        return false;

    if (tile->frontTexture() != tile->lastDrawnTexture()) {
        // CAPPFIX_FLICKERING: fix flickering issue at floating browser mode
        return false;
        // CAPPFIX_FLICKERING_END

        // the below works around an issue where glTexSubImage2d can't update a
        // texture that hasn't drawn yet by drawing it off screen.
        // glFlush() and glFinish() work also, but are likely more wasteful.
        SkRect rect = SkRect::MakeXYWH(-100, -100, 0, 0);
        FloatRect fillPortion(0, 0, 0, 0);
        tile->frontTexture()->drawGL(false, rect, 1.0f, 0, false, true, fillPortion);
    }
    LayerContent* content = getFirstLayer()->content();
    // Extract the dirty rect from the region. Note that this is *NOT* constrained
    // to this tile
    IntRect dirtyRect = tile->dirtyArea().getBounds();
    IntRect tileRect = IntRect(tile->x() * TilesManager::tileWidth(),
                               tile->y() * TilesManager::tileHeight(),
                               TilesManager::tileWidth(),
                               TilesManager::tileHeight());
    FloatRect tileRectInDoc = tileRect;
    tileRectInDoc.scale(1 / tile->scale());
    dirtyRect.intersect(enclosingIntRect(tileRectInDoc));
    PrerenderedInval* prerenderedInval = content->prerenderForRect(dirtyRect);
    if (!prerenderedInval || prerenderedInval->bitmap.isNull())
        return false;
    SkBitmap sourceBitmap = prerenderedInval->bitmap;
    // Calculate the screen rect that is dirty, then intersect it with the
    // tile's screen rect so that we end up with the pixels we need to blit
    FloatRect screenDirty = dirtyRect;
    screenDirty.scale(tile->scale());
    IntRect enclosingScreenDirty = enclosingIntRect(screenDirty);
    enclosingScreenDirty.intersect(tileRect);
    if (enclosingScreenDirty.isEmpty())
        return false;
    // Make sure the screen area we want to blit is contained by the
    // prerendered screen area
    if (!prerenderedInval->screenArea.contains(enclosingScreenDirty)) {
        ALOGD("prerendered->screenArea " INT_RECT_FORMAT " doesn't contain "
                "enclosingScreenDirty " INT_RECT_FORMAT,
                INT_RECT_ARGS(prerenderedInval->screenArea),
                INT_RECT_ARGS(enclosingScreenDirty));
        return false;
    }
    IntPoint origin = prerenderedInval->screenArea.location();
    SkBitmap subset;
    subset.setConfig(sourceBitmap.config(), enclosingScreenDirty.width(),
            enclosingScreenDirty.height());
    subset.allocPixels();

    int topOffset = enclosingScreenDirty.y() - prerenderedInval->screenArea.y();
    int leftOffset = enclosingScreenDirty.x() - prerenderedInval->screenArea.x();
    if (!GLUtils::deepCopyBitmapSubset(sourceBitmap, subset, leftOffset, topOffset))
        return false;
    // Now upload
    SkIRect textureInval = SkIRect::MakeXYWH(enclosingScreenDirty.x() - tileRect.x(),
                                             enclosingScreenDirty.y() - tileRect.y(),
                                             enclosingScreenDirty.width(),
                                             enclosingScreenDirty.height());
    GLUtils::updateTextureWithBitmap(tile->frontTexture()->m_ownTextureId,
                                     subset, textureInval);
    tile->onBlitUpdate();
    return true;
}
Esempio n. 19
0
IntRect Surface::fullContentArea()
{
    if (singleLayer())
        return getFirstLayer()->fullContentArea();
    return m_fullContentArea;
}