void LayerTextureSubImage::uploadWithMapTexSubImage(const uint8_t* image, const IntRect& imageRect, const IntRect& sourceRect, const IntRect& destRect, GC3Denum format, GraphicsContext3D* context) { TRACE_EVENT("LayerTextureSubImage::uploadWithMapTexSubImage", this, 0); // Offset from image-rect to source-rect. IntPoint offset(sourceRect.x() - imageRect.x(), sourceRect.y() - imageRect.y()); // Upload tile data via a mapped transfer buffer Extensions3DChromium* extensions = static_cast<Extensions3DChromium*>(context->getExtensions()); uint8_t* pixelDest = static_cast<uint8_t*>(extensions->mapTexSubImage2DCHROMIUM(GraphicsContext3D::TEXTURE_2D, 0, destRect.x(), destRect.y(), destRect.width(), destRect.height(), format, GraphicsContext3D::UNSIGNED_BYTE, Extensions3DChromium::WRITE_ONLY)); if (!pixelDest) { uploadWithTexSubImage(image, imageRect, sourceRect, destRect, format, context); return; } if (imageRect.width() == sourceRect.width() && !offset.x()) memcpy(pixelDest, &image[4 * offset.y() * imageRect.width()], imageRect.width() * destRect.height() * 4); else { // Strides not equal, so do a row-by-row memcpy from the // paint results into the pixelDest for (int row = 0; row < destRect.height(); ++row) memcpy(&pixelDest[destRect.width() * 4 * row], &image[4 * (offset.x() + (offset.y() + row) * imageRect.width())], destRect.width() * 4); } extensions->unmapTexSubImage2DCHROMIUM(pixelDest); }
void CCHeadsUpDisplay::draw() { GraphicsContext3D* context = m_layerRenderer->context(); if (!m_hudTexture) m_hudTexture = ManagedTexture::create(m_layerRenderer->renderSurfaceTextureManager()); // Use a fullscreen texture only if we need to... IntSize hudSize; if (settings().showPlatformLayerTree) { hudSize.setWidth(min(2048, m_layerRenderer->viewportWidth())); hudSize.setHeight(min(2048, m_layerRenderer->viewportHeight())); } else { hudSize.setWidth(512); hudSize.setHeight(128); } if (!m_hudTexture->reserve(hudSize, GraphicsContext3D::RGBA)) return; // Render pixels into the texture. PlatformCanvas canvas; canvas.resize(hudSize); { PlatformCanvas::Painter painter(&canvas, PlatformCanvas::Painter::GrayscaleText); drawHudContents(painter.context(), hudSize); } // Upload to GL. { PlatformCanvas::AutoLocker locker(&canvas); m_hudTexture->bindTexture(context, m_layerRenderer->renderSurfaceTextureAllocator()); bool uploadedViaMap = false; if (m_useMapSubForUploads) { Extensions3DChromium* extensions = static_cast<Extensions3DChromium*>(context->getExtensions()); uint8_t* pixelDest = static_cast<uint8_t*>(extensions->mapTexSubImage2DCHROMIUM(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, hudSize.width(), hudSize.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, Extensions3DChromium::WRITE_ONLY)); if (pixelDest) { uploadedViaMap = true; memcpy(pixelDest, locker.pixels(), hudSize.width() * hudSize.height() * 4); extensions->unmapTexSubImage2DCHROMIUM(pixelDest); } } if (!uploadedViaMap) { GLC(context, context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, canvas.size().width(), canvas.size().height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, locker.pixels())); } } // Draw the HUD onto the default render surface. const Program* program = m_layerRenderer->headsUpDisplayProgram(); ASSERT(program && program->initialized()); GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); m_hudTexture->bindTexture(context, m_layerRenderer->renderSurfaceTextureAllocator()); GLC(context, context->useProgram(program->program())); GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0)); TransformationMatrix matrix; matrix.translate3d(hudSize.width() * 0.5, hudSize.height() * 0.5, 0); m_layerRenderer->drawTexturedQuad(matrix, hudSize.width(), hudSize.height(), 1.0f, m_layerRenderer->sharedGeometryQuad(), program->vertexShader().matrixLocation(), program->fragmentShader().alphaLocation(), -1); m_hudTexture->unreserve(); }