diff options
Diffstat (limited to 'src/core/delegated_frame_node.cpp')
-rw-r--r-- | src/core/delegated_frame_node.cpp | 126 |
1 files changed, 48 insertions, 78 deletions
diff --git a/src/core/delegated_frame_node.cpp b/src/core/delegated_frame_node.cpp index 7f791df29..84fde7ca2 100644 --- a/src/core/delegated_frame_node.cpp +++ b/src/core/delegated_frame_node.cpp @@ -49,7 +49,7 @@ #include "delegated_frame_node.h" #include "chromium_gpu_helper.h" -#include "gl_surface_qt.h" +#include "ozone/gl_surface_qt.h" #include "stream_video_node.h" #include "type_conversion.h" #include "yuv_video_node.h" @@ -72,6 +72,7 @@ #include "components/viz/common/resources/transferable_resource.h" #include "components/viz/service/display/bsp_tree.h" #include "components/viz/service/display_embedder/server_shared_bitmap_manager.h" +#include "content/browser/browser_main_loop.h" #include "gpu/command_buffer/service/mailbox_manager.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_fence.h" @@ -140,7 +141,7 @@ private: QSize m_textureSize; bool m_hasAlpha; GLenum m_target; -#if defined(USE_X11) +#if defined(USE_OZONE) bool m_ownsTexture; #endif #ifdef Q_OS_QNX @@ -154,7 +155,6 @@ public: ResourceHolder(const viz::TransferableResource &resource); QSharedPointer<QSGTexture> initTexture(bool quadIsAllOpaque, RenderWidgetHostViewQtDelegate *apiDelegate = 0); QSGTexture *texture() const { return m_texture.data(); } - viz::TransferableResource &transferableResource() { return m_resource; } viz::ReturnedResource returnResource(); void incImportCount() { ++m_importCount; } bool needsToFetch() const { return !m_resource.is_software && m_texture && !m_texture.data()->textureId(); } @@ -183,13 +183,10 @@ public: virtual ~DelegatedNodeTreeHandler(){} - virtual void setupRenderPassNode(QSGTexture *, const QRect &, QSGNode *) = 0; + virtual void setupRenderPassNode(QSGTexture *, const QRect &, const QRectF &, QSGNode *) = 0; virtual void setupTextureContentNode(QSGTexture *, const QRect &, const QRectF &, - QSGTexture::Filtering, - QSGTextureNode::TextureCoordinatesTransformMode, + QSGImageNode::TextureCoordinatesTransformMode, QSGNode *) = 0; - virtual void setupTiledContentNode(QSGTexture *, const QRect &, const QRectF &, - QSGTexture::Filtering, QSGNode *) = 0; virtual void setupSolidColorNode(const QRect &, const QColor &, QSGNode *) = 0; #ifndef QT_NO_OPENGL @@ -216,28 +213,31 @@ public: { } - void setupRenderPassNode(QSGTexture *layer, const QRect &rect, QSGNode *) override + void setupRenderPassNode(QSGTexture *layer, const QRect &rect, const QRectF &sourceRect, QSGNode *) override { Q_ASSERT(layer); Q_ASSERT(m_nodeIterator != m_sceneGraphNodes->end()); QSGInternalImageNode *imageNode = static_cast<QSGInternalImageNode*>(*m_nodeIterator++); imageNode->setTargetRect(rect); imageNode->setInnerTargetRect(rect); + imageNode->setSubSourceRect(layer->convertToNormalizedSourceRect(sourceRect)); imageNode->setTexture(layer); imageNode->update(); } void setupTextureContentNode(QSGTexture *texture, const QRect &rect, const QRectF &sourceRect, - QSGTexture::Filtering filtering, - QSGTextureNode::TextureCoordinatesTransformMode texCoordTransForm, + QSGImageNode::TextureCoordinatesTransformMode texCoordTransForm, QSGNode *) override { Q_ASSERT(m_nodeIterator != m_sceneGraphNodes->end()); - QSGTextureNode *textureNode = static_cast<QSGTextureNode*>(*m_nodeIterator++); + QSGImageNode *textureNode = static_cast<QSGImageNode*>(*m_nodeIterator++); if (textureNode->texture() != texture) { + // Chromium sometimes uses textures that doesn't completely fit + // in which case the geometry needs to be recalculated even if + // rect and src-rect matches. + if (textureNode->texture()->textureSize() != texture->textureSize()) + textureNode->markDirty(QSGImageNode::DirtyGeometry); textureNode->setTexture(texture); - // @TODO: This is a workaround for funky rendering, figure out why this is needed. - textureNode->markDirty(QSGTextureNode::DirtyGeometry); } if (textureNode->textureCoordinatesTransform() != texCoordTransForm) textureNode->setTextureCoordinatesTransform(texCoordTransForm); @@ -245,25 +245,8 @@ public: textureNode->setRect(rect); if (textureNode->sourceRect() != sourceRect) textureNode->setSourceRect(sourceRect); - if (textureNode->filtering() != filtering) - textureNode->setFiltering(filtering); - } - void setupTiledContentNode(QSGTexture *texture, const QRect &rect, const QRectF &sourceRect, - QSGTexture::Filtering filtering, QSGNode *) override - { - Q_ASSERT(m_nodeIterator != m_sceneGraphNodes->end()); - QSGTextureNode *textureNode = static_cast<QSGTextureNode*>(*m_nodeIterator++); - if (textureNode->texture() != texture) { - textureNode->setTexture(texture); - // @TODO: This is a workaround for funky rendering, figure out why this is needed. - textureNode->markDirty(QSGTextureNode::DirtyGeometry); - } - if (textureNode->rect() != rect) - textureNode->setRect(rect); - if (textureNode->sourceRect() != sourceRect) - textureNode->setSourceRect(sourceRect); - if (textureNode->filtering() != filtering) - textureNode->setFiltering(filtering); + if (textureNode->filtering() != texture->filtering()) + textureNode->setFiltering(texture->filtering()); } void setupSolidColorNode(const QRect &rect, const QColor &color, QSGNode *) override { @@ -316,14 +299,15 @@ public: { } - void setupRenderPassNode(QSGTexture *layer, const QRect &rect, + void setupRenderPassNode(QSGTexture *layer, const QRect &rect, const QRectF &sourceRect, QSGNode *layerChain) override { Q_ASSERT(layer); // Only QSGInternalImageNode currently supports QSGLayer textures. - QSGInternalImageNode *imageNode = m_apiDelegate->createImageNode(); + QSGInternalImageNode *imageNode = m_apiDelegate->createInternalImageNode(); imageNode->setTargetRect(rect); imageNode->setInnerTargetRect(rect); + imageNode->setSubSourceRect(layer->convertToNormalizedSourceRect(sourceRect)); imageNode->setTexture(layer); imageNode->update(); @@ -332,30 +316,15 @@ public: } void setupTextureContentNode(QSGTexture *texture, const QRect &rect, const QRectF &sourceRect, - QSGTexture::Filtering filtering, - QSGTextureNode::TextureCoordinatesTransformMode texCoordTransForm, + QSGImageNode::TextureCoordinatesTransformMode texCoordTransForm, QSGNode *layerChain) override { - QSGTextureNode *textureNode = m_apiDelegate->createTextureNode(); + QSGImageNode *textureNode = m_apiDelegate->createImageNode(); textureNode->setTextureCoordinatesTransform(texCoordTransForm); textureNode->setRect(rect); textureNode->setSourceRect(sourceRect); textureNode->setTexture(texture); - textureNode->setFiltering(filtering); - - layerChain->appendChildNode(textureNode); - m_sceneGraphNodes->append(textureNode); - } - - void setupTiledContentNode(QSGTexture *texture, const QRect &rect, const QRectF &sourceRect, - QSGTexture::Filtering filtering, - QSGNode *layerChain) override - { - QSGTextureNode *textureNode = m_apiDelegate->createTextureNode(); - textureNode->setRect(rect); - textureNode->setSourceRect(sourceRect); - textureNode->setFiltering(filtering); - textureNode->setTexture(texture); + textureNode->setFiltering(texture->filtering()); layerChain->appendChildNode(textureNode); m_sceneGraphNodes->append(textureNode); @@ -431,7 +400,7 @@ private: static inline QSharedPointer<QSGLayer> findRenderPassLayer(const int &id, const QVector<QPair<int, QSharedPointer<QSGLayer> > > &list) { typedef QPair<int, QSharedPointer<QSGLayer> > Pair; - Q_FOREACH (const Pair &pair, list) + for (const Pair &pair : list) if (pair.first == id) return pair.second; return QSharedPointer<QSGLayer>(); @@ -571,7 +540,7 @@ MailboxTexture::MailboxTexture(const gpu::MailboxHolder &mailboxHolder, const QS , m_textureSize(textureSize) , m_hasAlpha(false) , m_target(GL_TEXTURE_2D) -#if defined(USE_X11) +#if defined(USE_OZONE) , m_ownsTexture(false) #endif { @@ -586,7 +555,7 @@ MailboxTexture::MailboxTexture(const gpu::MailboxHolder &mailboxHolder, const QS MailboxTexture::~MailboxTexture() { -#if defined(USE_X11) +#if defined(USE_OZONE) // This is rare case, where context is not shared // we created extra texture in current context, so // delete it now @@ -651,7 +620,9 @@ QSharedPointer<QSGTexture> ResourceHolder::initTexture(bool quadNeedsBlending, R if (!texture) { if (m_resource.is_software) { Q_ASSERT(apiDelegate); - std::unique_ptr<viz::SharedBitmap> sharedBitmap = viz::ServerSharedBitmapManager::current()->GetSharedBitmapFromId(m_resource.size, m_resource.mailbox_holder.mailbox); + std::unique_ptr<viz::SharedBitmap> sharedBitmap = + content::BrowserMainLoop::GetInstance()->GetServerSharedBitmapManager()->GetSharedBitmapFromId( + m_resource.size, viz::BGRA_8888, m_resource.mailbox_holder.mailbox); // QSG interprets QImage::hasAlphaChannel meaning that a node should enable blending // to draw it but Chromium keeps this information in the quads. // The input format is currently always Format_ARGB32_Premultiplied, so assume that all @@ -659,7 +630,9 @@ QSharedPointer<QSGTexture> ResourceHolder::initTexture(bool quadNeedsBlending, R // from Format_ARGB32_Premultiplied to Format_RGB32 just to get hasAlphaChannel to // return false. QImage::Format format = quadNeedsBlending ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; - QImage image(sharedBitmap->pixels(), m_resource.size.width(), m_resource.size.height(), format); + QImage image = sharedBitmap + ? QImage(sharedBitmap->pixels(), m_resource.size.width(), m_resource.size.height(), format) + : QImage(m_resource.size.width(), m_resource.size.height(), format); texture.reset(apiDelegate->createTextureFromImage(image.copy())); } else { #ifndef QT_NO_OPENGL @@ -669,6 +642,7 @@ QSharedPointer<QSGTexture> ResourceHolder::initTexture(bool quadNeedsBlending, R Q_UNREACHABLE(); #endif } + texture->setFiltering(m_resource.filter == GL_LINEAR ? QSGTexture::Linear : QSGTexture::Nearest); m_texture = texture; } // All quads using a resource should request the same blending state. @@ -703,12 +677,12 @@ RectClipNode::RectClipNode(const QRectF &rect) DelegatedFrameNode::DelegatedFrameNode() : m_numPendingSyncPoints(0) -#if defined(USE_X11) && !defined(QT_NO_OPENGL) +#if defined(USE_OZONE) && !defined(QT_NO_OPENGL) , m_contextShared(true) #endif { setFlag(UsePreprocess); -#if defined(USE_X11) && !defined(QT_NO_OPENGL) +#if defined(USE_OZONE) && !defined(QT_NO_OPENGL) QOpenGLContext *currentContext = QOpenGLContext::currentContext() ; QOpenGLContext *sharedContext = qt_gl_global_share_context(); if (currentContext && sharedContext && !QOpenGLContext::areSharing(currentContext, sharedContext)) { @@ -748,7 +722,7 @@ void DelegatedFrameNode::preprocess() // Then render any intermediate RenderPass in order. typedef QPair<int, QSharedPointer<QSGLayer> > Pair; - Q_FOREACH (const Pair &pair, m_sgObjects.renderPassLayers) { + for (const Pair &pair : qAsConst(m_sgObjects.renderPassLayers)) { // The layer is non-live, request a one-time update here. pair.second->scheduleUpdate(); // Proceed with the actual update. @@ -1100,13 +1074,14 @@ void DelegatedFrameNode::handleQuad( const viz::RenderPassDrawQuad *renderPassQuad = viz::RenderPassDrawQuad::MaterialCast(quad); if (!renderPassQuad->mask_texture_size.IsEmpty()) { ResourceHolder *resource = findAndHoldResource(renderPassQuad->mask_resource_id(), resourceCandidates); - Q_UNUSED(resource); // FIXME + Q_UNUSED(resource); // FIXME: QTBUG-67652 } - QSGTexture *layer = + QSGLayer *layer = findRenderPassLayer(renderPassQuad->render_pass_id, m_sgObjects.renderPassLayers).data(); if (layer) - nodeHandler->setupRenderPassNode(layer, toQt(quad->rect), currentLayerChain); + nodeHandler->setupRenderPassNode(layer, toQt(quad->rect), toQt(renderPassQuad->tex_coord_rect), currentLayerChain); + break; } case viz::DrawQuad::TEXTURE_CONTENT: { @@ -1123,9 +1098,7 @@ void DelegatedFrameNode::handleQuad( nodeHandler->setupTextureContentNode( texture, toQt(quad->rect), toQt(uv_rect), - resource->transferableResource().filter == GL_LINEAR ? QSGTexture::Linear - : QSGTexture::Nearest, - tquad->y_flipped ? QSGTextureNode::MirrorVertically : QSGTextureNode::NoTransform, + tquad->y_flipped ? QSGImageNode::MirrorVertically : QSGImageNode::NoTransform, currentLayerChain); break; } @@ -1165,12 +1138,10 @@ void DelegatedFrameNode::handleQuad( case viz::DrawQuad::TILED_CONTENT: { const viz::TileDrawQuad *tquad = viz::TileDrawQuad::MaterialCast(quad); ResourceHolder *resource = findAndHoldResource(tquad->resource_id(), resourceCandidates); - nodeHandler->setupTiledContentNode( + nodeHandler->setupTextureContentNode( initAndHoldTexture(resource, quad->ShouldDrawWithBlending(), apiDelegate), toQt(quad->rect), toQt(tquad->tex_coord_rect), - resource->transferableResource().filter == GL_LINEAR ? QSGTexture::Linear - : QSGTexture::Nearest, - currentLayerChain); + QSGImageNode::NoTransform, currentLayerChain); break; #ifndef QT_NO_OPENGL } @@ -1263,7 +1234,7 @@ void DelegatedFrameNode::fetchAndSyncMailboxes(QList<MailboxTexture *> &mailboxe mailboxesToPull.reserve(mailboxesToFetch.size()); gpu::SyncPointManager *syncPointManager = sync_point_manager(); - base::MessageLoop *gpuMessageLoop = gpu_message_loop(); + scoped_refptr<base::SingleThreadTaskRunner> gpuTaskRunner = gpu_task_runner(); Q_ASSERT(m_numPendingSyncPoints == 0); m_numPendingSyncPoints = mailboxesToFetch.count(); for (MailboxTexture *mailboxTexture : qAsConst(mailboxesToFetch)) { @@ -1274,14 +1245,14 @@ void DelegatedFrameNode::fetchAndSyncMailboxes(QList<MailboxTexture *> &mailboxe } if (!mailboxesToPull.isEmpty()) { auto task = base::BindOnce(&DelegatedFrameNode::pullTextures, this, std::move(mailboxesToPull)); - gpuMessageLoop->task_runner()->PostTask(FROM_HERE, std::move(task)); + gpuTaskRunner->PostTask(FROM_HERE, std::move(task)); } m_mailboxesFetchedWaitCond.wait(&m_mutex); m_textureFences.swap(transferredFences); } - Q_FOREACH (gl::TransferableFence sync, transferredFences) { + for (gl::TransferableFence sync : qAsConst(transferredFences)) { // We need to wait on the fences on the Qt current context, and // can therefore not use GLFence routines that uses a different // concept of current context. @@ -1289,7 +1260,7 @@ void DelegatedFrameNode::fetchAndSyncMailboxes(QList<MailboxTexture *> &mailboxe deleteChromiumSync(&sync); } -#if defined(USE_X11) +#if defined(USE_OZONE) // Workaround when context is not shared QTBUG-48969 // Make slow copy between two contexts. if (!m_contextShared) { @@ -1304,7 +1275,7 @@ void DelegatedFrameNode::fetchAndSyncMailboxes(QList<MailboxTexture *> &mailboxe GLuint fbo = 0; funcs->glGenFramebuffers(1, &fbo); - Q_FOREACH (MailboxTexture *mailboxTexture, mailboxesToFetch) { + for (MailboxTexture *mailboxTexture : qAsConst(mailboxesToFetch)) { // Read texture into QImage from shared context. // Switch to shared context. sharedContext->makeCurrent(m_offsurface.data()); @@ -1391,10 +1362,9 @@ void DelegatedFrameNode::fenceAndUnlockQt(DelegatedFrameNode *frameNode) #ifndef QT_NO_OPENGL if (!!gl::GLContext::GetCurrent() && gl::GLFence::IsSupported()) { // Create a fence on the Chromium GPU-thread and context - gl::GLFence *fence = gl::GLFence::Create(); + std::unique_ptr<gl::GLFence> fence = gl::GLFence::Create(); // But transfer it to something generic since we need to read it using Qt's OpenGL. frameNode->m_textureFences.append(fence->Transfer()); - delete fence; } if (frameNode->m_numPendingSyncPoints == 0) base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind(&DelegatedFrameNode::unlockQt, frameNode)); |