Esempio n. 1
0
double GLWebViewState::setupDrawing(const IntRect& invScreenRect,
                                    const SkRect& visibleContentRect,
                                    const IntRect& screenRect, int titleBarHeight,
                                    const IntRect& screenClip, float scale)
{
    TilesManager* tilesManager = TilesManager::instance();

    // Make sure GL resources are created on the UI thread.
    // They are created either for the first time, or after EGL context
    // recreation caused by onTrimMemory in the framework.
    ShaderProgram* shader = tilesManager->shader();
    if (shader->needsInit()) {
        ALOGD("Reinit shader");
        shader->initGLResources();
    }
    TransferQueue* transferQueue = tilesManager->transferQueue();
    if (transferQueue->needsInit()) {
        ALOGD("Reinit transferQueue");
        transferQueue->initGLResources(TilesManager::tileWidth(),
                                       TilesManager::tileHeight());
    }
    shader->setupDrawing(invScreenRect, visibleContentRect, screenRect,
                         titleBarHeight, screenClip, scale);

    double currentTime = WTF::currentTime();

    setVisibleContentRect(visibleContentRect, scale);

    return currentTime;
}
Esempio n. 2
0
void TileGrid::prepareTile(int x, int y, TilePainter* painter,
                           GLWebViewState* state, bool isLowResPrefetch,
                           bool isExpandPrefetch, bool shouldTryUpdateWithBlit)
{
    Tile* tile = getTile(x, y);
    if (!tile) {
        bool isLayerTile = !m_isBaseSurface;
        tile = new Tile(isLayerTile);
        m_tiles.append(tile);
    }

    ALOGV("preparing tile %p at %d, %d, painter is %p", tile, x, y, painter);

    tile->setContents(x, y, m_scale, isExpandPrefetch);

    if (shouldTryUpdateWithBlit && tryBlitFromContents(tile, painter))
        return;

    if (tile->isDirty() || !tile->frontTexture())
        tile->reserveTexture();

    if (tile->backTexture() && tile->isDirty()) {
        TilesManager* tilesManager = TilesManager::instance();

        // if a scheduled repaint is still outstanding, update it with the new painter
        if (tile->isRepaintPending() && tilesManager->tryUpdateOperationWithPainter(tile, painter))
            return;

        ALOGV("painting TG %p's tile %d %d for LG %p, scale %f", this, x, y, painter, m_scale);
        PaintTileOperation *operation = new PaintTileOperation(tile, painter,
                                                               state, isLowResPrefetch);
        tilesManager->scheduleOperation(operation);
    }
}
void PaintTileOperation::endTime() {
    if (m_startTimeMS == 0.0) return;
    double timeDelta = currentTimeMS() - m_startTimeMS;
    m_startTimeMS = 0.0;
#if ENABLE(IMPROVE_TEXTURES_GENERATOR_MULTI_CORE)
    TilesManager* tilesManager = TilesManager::instance();
    bool supportMultiCoreTextGen = (tilesManager && tilesManager->supportMultiCoreTexturesGen());
    XLOGD2("Support multi-thread texture generator = %d >> %f", supportMultiCoreTextGen, timeDelta);
#else
    XLOGD2("%f", timeDelta);
#endif
}
Esempio n. 4
0
void GLWebViewState::setVisibleContentRect(const SkRect& visibleContentRect, float scale)
{
    // allocate max possible number of tiles visible with this visibleContentRect / expandedTileBounds
    const float invTileContentWidth = scale / TilesManager::tileWidth();
    const float invTileContentHeight = scale / TilesManager::tileHeight();

    int viewMaxTileX =
        static_cast<int>(ceilf((visibleContentRect.width()-1) * invTileContentWidth)) + 1;
    int viewMaxTileY =
        static_cast<int>(ceilf((visibleContentRect.height()-1) * invTileContentHeight)) + 1;

    TilesManager* tilesManager = TilesManager::instance();
    int maxTextureCount = viewMaxTileX * viewMaxTileY * (tilesManager->highEndGfx() ? 4 : 2);

    tilesManager->setCurrentTextureCount(maxTextureCount);

    // TODO: investigate whether we can move this return earlier.
    if ((m_visibleContentRect == visibleContentRect)
        && (m_scale == scale)) {
        // everything below will stay the same, early return.
        m_isVisibleContentRectScrolling = false;
        return;
    }
    m_scale = scale;

    m_goingDown = m_visibleContentRect.fTop - visibleContentRect.fTop <= 0;
    m_goingLeft = m_visibleContentRect.fLeft - visibleContentRect.fLeft >= 0;

    // detect visibleContentRect scrolling from short programmatic scrolls/jumps
    m_isVisibleContentRectScrolling = m_visibleContentRect != visibleContentRect
        && SkRect::Intersects(m_visibleContentRect, visibleContentRect);
    m_visibleContentRect = visibleContentRect;

    ALOGV("New visibleContentRect %.2f - %.2f %.2f - %.2f (w: %2.f h: %.2f scale: %.2f )",
          m_visibleContentRect.fLeft, m_visibleContentRect.fTop,
          m_visibleContentRect.fRight, m_visibleContentRect.fBottom,
          m_visibleContentRect.width(), m_visibleContentRect.height(), scale);
}
Esempio n. 5
0
// -invScreenRect is the webView's rect with inverted Y screen coordinate.
// -visibleContentRect is the visible area in content coordinate.
// They are both based on  webView's rect and calculated in Java side.
//
// -screenClip is in screen coordinate, so we need to invert the Y axis before
// passing into GL functions. Clip can be smaller than the webView's rect.
//
// TODO: Try to decrease the number of parameters as some info is redundant.
int GLWebViewState::drawGL(IntRect& invScreenRect, SkRect& visibleContentRect,
                           IntRect* invalRect, IntRect& screenRect, int titleBarHeight,
                           IntRect& screenClip, float scale,
                           bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr,
                           bool shouldDraw)
{
    TilesManager* tilesManager = TilesManager::instance();
    if (shouldDraw)
        tilesManager->getProfiler()->nextFrame(visibleContentRect.fLeft,
                                               visibleContentRect.fTop,
                                               visibleContentRect.fRight,
                                               visibleContentRect.fBottom,
                                               scale);
    tilesManager->incDrawGLCount();

    ALOGV("drawGL, invScreenRect(%d, %d, %d, %d), visibleContentRect(%.2f, %.2f, %.2f, %.2f)",
          invScreenRect.x(), invScreenRect.y(), invScreenRect.width(), invScreenRect.height(),
          visibleContentRect.fLeft, visibleContentRect.fTop,
          visibleContentRect.fRight, visibleContentRect.fBottom);

    ALOGV("drawGL, invalRect(%d, %d, %d, %d), screenRect(%d, %d, %d, %d)"
          "screenClip (%d, %d, %d, %d), scale %f titleBarHeight %d",
          invalRect->x(), invalRect->y(), invalRect->width(), invalRect->height(),
          screenRect.x(), screenRect.y(), screenRect.width(), screenRect.height(),
          screenClip.x(), screenClip.y(), screenClip.width(), screenClip.height(), scale, titleBarHeight);

    m_inUnclippedDraw = shouldDraw && (screenRect == screenClip);

    resetLayersDirtyArea();

    if (scale < MIN_SCALE_WARNING || scale > MAX_SCALE_WARNING)
        ALOGW("WARNING, scale seems corrupted before update: %e", scale);

    tilesManager->updateTilesIfContextVerified();

    // gather the textures we can use, make sure this happens before any
    // texture preparation work.
    tilesManager->gatherTextures();

    // Upload any pending ImageTexture
    // Return true if we still have some images to upload.
    // TODO: upload as many textures as possible within a certain time limit
    int returnFlags = 0;
    if (ImagesManager::instance()->prepareTextures(this))
        returnFlags |= DrawGlInfo::kStatusDraw;

    // CAPP_REMOVE_SET_SCALE_AT_WARNING
    if (scale < MIN_SCALE_WARNING || scale > MAX_SCALE_WARNING) {
        ALOGW("WARNING, scale seems corrupted after update: %e", scale);
        //scale = 1.0f; // WORKAROUND for corrupted scale: use 1.0
    }
    // CAPP_REMOVE_SET_SCALE_AT_WARNING_END

    double currentTime = setupDrawing(invScreenRect, visibleContentRect, screenRect,
                                      titleBarHeight, screenClip, scale);

    TexturesResult nbTexturesNeeded;
    bool scrolling = isScrolling();
    bool singleSurfaceMode = m_layersRenderingMode == kSingleSurfaceRendering;
    m_glExtras.setVisibleContentRect(visibleContentRect);

    returnFlags |= m_surfaceCollectionManager.drawGL(currentTime, invScreenRect,
                                                     visibleContentRect,
                                                     scale, scrolling,
                                                     singleSurfaceMode,
                                                     collectionsSwappedPtr,
                                                     newCollectionHasAnimPtr,
                                                     &nbTexturesNeeded, shouldDraw);

    int nbTexturesForImages = ImagesManager::instance()->nbTextures();
    ALOGV("*** We have %d textures for images, %d full, %d clipped, total %d / %d",
          nbTexturesForImages, nbTexturesNeeded.full, nbTexturesNeeded.clipped,
          nbTexturesNeeded.full + nbTexturesForImages,
          nbTexturesNeeded.clipped + nbTexturesForImages);
    nbTexturesNeeded.full += nbTexturesForImages;
    nbTexturesNeeded.clipped += nbTexturesForImages;

    if (setLayersRenderingMode(nbTexturesNeeded)) {
        TilesManager::instance()->dirtyAllTiles();
        returnFlags |= DrawGlInfo::kStatusDraw | DrawGlInfo::kStatusInvoke;
    }

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    if (returnFlags & DrawGlInfo::kStatusDraw) {
        // returnFlags & kStatusDraw && empty inval region means we've inval'd everything,
        // but don't have new content. Keep redrawing full view (0,0,0,0)
        // until tile generation catches up and we swap pages.
        bool fullScreenInval = m_frameworkLayersInval.isEmpty() || m_doFrameworkFullInval;

        if (!fullScreenInval) {
            m_frameworkLayersInval.inflate(1);

            invalRect->setX(m_frameworkLayersInval.x());
            invalRect->setY(m_frameworkLayersInval.y());
            invalRect->setWidth(m_frameworkLayersInval.width());
            invalRect->setHeight(m_frameworkLayersInval.height());

            ALOGV("invalRect(%d, %d, %d, %d)", invalRect->x(),
                  invalRect->y(), invalRect->width(), invalRect->height());

            if (!invalRect->intersects(invScreenRect)) {
                // invalidate is occurring offscreen, do full inval to guarantee redraw
                fullScreenInval = true;
            }
        }

        if (fullScreenInval) {
            invalRect->setX(0);
            invalRect->setY(0);
            invalRect->setWidth(0);
            invalRect->setHeight(0);
        }
    }

    if (shouldDraw)
        showFrameInfo(invScreenRect, *collectionsSwappedPtr);

    return returnFlags;
}
Esempio n. 6
0
void TileGrid::prepareGL(GLWebViewState* state, float scale,
                         const IntRect& prepareArea, const IntRect& fullContentArea,
                         TilePainter* painter, int regionFlags, bool isLowResPrefetch,
                         bool updateWithBlit)
{
    // first, how many tiles do we need
    m_area = computeTilesArea(prepareArea, scale);
    if (m_area.isEmpty())
        return;

    ALOGV("prepare TileGrid %p with scale %.2f, prepareArea "
          " %d, %d - %d x %d, corresponding to %d, %d x - %d x %d tiles",
          this, scale,
          prepareArea.x(), prepareArea.y(),
          prepareArea.width(), prepareArea.height(),
          m_area.x(), m_area.y(),
          m_area.width(), m_area.height());

    bool goingDown = m_prevTileY < m_area.y();
    m_prevTileY = m_area.y();

    TilesManager* tilesManager = TilesManager::instance();
    if (scale != m_scale)
        tilesManager->removeOperationsForFilter(new ScaleFilter(painter, m_scale));

    m_scale = scale;

    // apply dirty region to affected tiles
    if (!m_dirtyRegion.isEmpty()) {
        for (unsigned int i = 0; i < m_tiles.size(); i++)
            m_tiles[i]->markAsDirty(m_dirtyRegion);

        // log inval region for the base surface
        if (m_isBaseSurface && tilesManager->getProfiler()->enabled()) {
            SkRegion::Iterator iterator(m_dirtyRegion);
            while (!iterator.done()) {
                SkIRect r = iterator.rect();
                tilesManager->getProfiler()->nextInval(r, scale);
                iterator.next();
            }
        }
        m_dirtyRegion.setEmpty();
    }

    if (regionFlags & StandardRegion) {
        for (int i = 0; i < m_area.width(); i++) {
            if (goingDown) {
                for (int j = 0; j < m_area.height(); j++)
                    prepareTile(m_area.x() + i, m_area.y() + j,
                                painter, state, isLowResPrefetch, false, updateWithBlit);
            } else {
                for (int j = m_area.height() - 1; j >= 0; j--)
                    prepareTile(m_area.x() + i, m_area.y() + j,
                                painter, state, isLowResPrefetch, false, updateWithBlit);
            }
        }
    }

    if (regionFlags & ExpandedRegion) {
        IntRect fullArea = computeTilesArea(fullContentArea, scale);
        IntRect expandedArea = m_area;

        // on systems reporting highEndGfx=true and useMinimalMemory not set, use expanded bounds
        if (tilesManager->highEndGfx() && !tilesManager->useMinimalMemory())
            expandedArea.inflate(EXPANDED_BOUNDS_INFLATE);

        if (isLowResPrefetch)
            expandedArea.inflateY(EXPANDED_PREFETCH_BOUNDS_Y_INFLATE);

        // clip painting area to content
        expandedArea.intersect(fullArea);

        for (int i = expandedArea.x(); i < expandedArea.maxX(); i++)
            for (int j = expandedArea.y(); j < expandedArea.maxY(); j++)
                if (!m_area.contains(i, j))
                    prepareTile(i, j, painter, state, isLowResPrefetch, true, updateWithBlit);
    }
}
/*
//Seems a SAMSUNG change BEGIN
bool VideoLayerAndroid::captureImage(PlatformWebGLVideoTexture* tex, VideoImageCallback callback)
{
    if (m_playerState == PLAYING && m_surfaceTexture.get()) {
		Locker<WTF::Mutex> lock(m_mutexRef->mutex);
		bool ret = (tex->*callback)(m_surfaceTexture);
		glFinish();
		return ret;
	}
	return false;
}
//Seems a SAMSUNG change END
*/
bool VideoLayerAndroid::drawGL(bool layerTilesDisabled)
{
    // Lazily allocated the textures.
    TilesManager* tilesManager = TilesManager::instance();
    VideoLayerManager* manager = tilesManager->videoLayerManager();
    manager->initGLResourcesIfNeeded();

    ShaderProgram* shader = tilesManager->shader();

    SkRect rect = SkRect::MakeSize(getSize());
    GLfloat surfaceMatrix[16];

    // Calculate the video rect based on the aspect ratio and the element rect.
    SkRect videoRect = calVideoRect(rect);
    PureColorQuadData pureColorQuadData(Color(0, 0, 0, 255), LayerQuad,
                                        &m_drawTransform, &rect);

    if (videoRect != rect) {
        // Paint the whole video element with black color when video content
        // can't cover the whole area.
        shader->drawQuad(&pureColorQuadData);
    }

    // Inner rect is for the progressing / play / pause animation.
    SkRect innerRect = SkRect::MakeWH(manager->getButtonSize(),
                                      manager->getButtonSize());
    if (innerRect.contains(videoRect))
        innerRect = videoRect;
    double buttonSize = manager->getButtonSize();
    innerRect.offset(videoRect.fLeft + (videoRect.width() - buttonSize) / 2,
                     videoRect.fTop + (videoRect.height() - buttonSize) / 2);

    // When we are drawing the animation of the play/pause button in the
    // middle of the video, we need to ask for redraw.
    bool needRedraw = false;
    TextureQuadData iconQuadData(0, GL_TEXTURE_2D, GL_LINEAR, LayerQuad,
                                 &m_drawTransform, &innerRect);
    // Draw the poster image, the progressing image or the Video depending
    // on the player's state.
    if (m_playerState == PREPARING) {
        // Show the progressing animation, with two rotating circles
        showPreparingAnimation(videoRect, innerRect);
        needRedraw = true;
    } else if (m_playerState == PLAYING && m_surfaceTexture.get()) {
        // Show the real video.
		Locker<WTF::Mutex> lock(m_mutexRef->mutex);//Seems a SAMSUNG change
        m_surfaceTexture->updateTexImage();
        m_surfaceTexture->getTransformMatrix(surfaceMatrix);
        GLuint textureId = manager->getTextureId(uniqueId());
        shader->drawVideoLayerQuad(m_drawTransform, surfaceMatrix,
                                   videoRect, textureId);
        manager->updateMatrix(uniqueId(), surfaceMatrix);

        // Use the scale to control the fading the sizing during animation
        double scale = manager->drawIcon(uniqueId(), PlayIcon);
        if (scale) {
            innerRect.inset(manager->getButtonSize() / 4 * scale,
                            manager->getButtonSize() / 4 * scale);
            iconQuadData.updateTextureId(manager->getPlayTextureId());
            iconQuadData.updateOpacity(scale);
            shader->drawQuad(&iconQuadData);
            needRedraw = true;
        }
		glFinish(); //we can look probably at using a fence here //Seems a SAMSUNG change
    } else {
        GLuint textureId = manager->getTextureId(uniqueId());
        GLfloat* matrix = manager->getMatrix(uniqueId());
        if (textureId && matrix) {
            // Show the screen shot for each video.
            shader->drawVideoLayerQuad(m_drawTransform, matrix,
                                       videoRect, textureId);
        } else {
            // Show the static poster b/c there is no screen shot available.
            pureColorQuadData.updateColor(Color(128, 128, 128, 255));
            shader->drawQuad(&pureColorQuadData);

            iconQuadData.updateTextureId(manager->getPosterTextureId());
            iconQuadData.updateOpacity(1.0);
            shader->drawQuad(&iconQuadData);
        }

        // Use the scale to control the fading and the sizing during animation.
        double scale = manager->drawIcon(uniqueId(), PauseIcon);
        if (scale) {
            innerRect.inset(manager->getButtonSize() / 4 * scale,
                            manager->getButtonSize() / 4 * scale);
            iconQuadData.updateTextureId(manager->getPauseTextureId());
            iconQuadData.updateOpacity(scale);
            shader->drawQuad(&iconQuadData);
            needRedraw = true;
        }

    }
    return needRedraw;
}