Skip to content

Commit

Permalink
feat: add metal renderer for macOS
Browse files Browse the repository at this point in the history
  • Loading branch information
tishion committed Mar 2, 2025
1 parent 9e892cc commit dc87993
Show file tree
Hide file tree
Showing 14 changed files with 581 additions and 145 deletions.
14 changes: 7 additions & 7 deletions example/QCefViewTest/MainWindow.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "MainWindow.h"
#include "MainWindow.h"

#include <QCoreApplication>
#include <QDebug>
Expand Down Expand Up @@ -49,7 +49,7 @@ MainWindow::MainWindow(QWidget* parent)
// add a local folder to URL map (global)
QCefContext::instance()->addLocalFolderResource(webResourceDir, URL_ROOT);

// createLeftCefView();
createLeftCefView();
createRightCefView();
}

Expand All @@ -64,11 +64,11 @@ MainWindow::createLeftCefView()
}

QCefSetting setting;
setting.setWindowlessFrameRate(240);
setting.setHardwareAcceleration(true);
setting.setWindowlessFrameRate(1000);
setting.setHardwareAcceleration(false);
// setting.setBackgroundColor(Qt::magenta);

m_pLeftCefViewWidget = new CefViewWidget(LEFT_INDEX_URL, &setting, this);
m_pLeftCefViewWidget = new CefViewWidget("https://www.testufo.com/", &setting, this);
// connect the invokeMethod to the slot
connect(m_pLeftCefViewWidget, &QCefView::invokeMethod, this, &MainWindow::onInvokeMethod);

Expand Down Expand Up @@ -96,9 +96,9 @@ MainWindow::createRightCefView()
#if CEF_VERSION_MAJOR < 100
setting.setPlugins(false);
#endif
setting.setWindowlessFrameRate(240);
setting.setWindowlessFrameRate(1000);
setting.setHardwareAcceleration(true);
QColor background(18, 18, 20, 255);
QColor background(0, 255, 0, 255);
setting.setBackgroundColor(background);

// create the QCefView widget and add it to the layout container
Expand Down
10 changes: 9 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,14 @@ if(OS_MACOS)
${QCefView_INFO_PLIST_FILE}
)

find_library(METAL_FRAMEWORK Metal)
find_library(QUARTZCORE_FRAMEWORK QuartzCore)
target_link_libraries(QCefView
PRIVATE
${METAL_FRAMEWORK}
${QUARTZCORE_FRAMEWORK}
)

set_target_properties(QCefView
PROPERTIES
FRAMEWORK TRUE
Expand Down Expand Up @@ -211,7 +219,7 @@ endif() # OS_MACOS

target_compile_definitions(QCefView PRIVATE NOMINMAX)

target_include_directories(QCefView
target_include_directories(QCefView
PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}/../include"
PRIVATE
Expand Down
7 changes: 4 additions & 3 deletions src/QCefView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,11 @@ QCefView::QCefView(const QString& url,
// OSR mode
setBackgroundRole(QPalette::Window);
setAttribute(Qt::WA_OpaquePaintEvent);
#if defined(Q_OS_WINDOWS)
setAttribute(Qt::WA_PaintOnScreen);
#endif
setAttribute(Qt::WA_NoSystemBackground);
// import for hardware rendering
if (d_ptr->osr.pRenderer_ && d_ptr->osr.pRenderer_->isHardware()) {
setAttribute(Qt::WA_PaintOnScreen);
}
}

// track mouse
Expand Down
8 changes: 4 additions & 4 deletions src/details/QCefViewPrivate.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "QCefViewPrivate.h"
#include "QCefViewPrivate.h"

#pragma region stl_headers
#include <stdexcept>
Expand Down Expand Up @@ -88,12 +88,12 @@ QCefViewPrivate::createCefBrowser(QCefView* view, const QString& url, const QCef
q_ptr->setPalette(palette);

std::shared_ptr<ICefViewRenderer> renderer;
#if defined(OS_WINDOWS)
#if defined(OS_WINDOWS) || defined(OS_MACOS)
// if hardware is enabled
if (setting && setting->hardwareAcceleration_) {
#if CEF_VERSION_MAJOR >= 125
// create hardware renderer if enabled
if (renderer = CefViewRendererFactory::createRenderer(true)) {
if ((renderer = CefViewRendererFactory::createRenderer(true))) {
// get window native handle
auto wid = reinterpret_cast<void*>(view->winId());

Expand Down Expand Up @@ -126,7 +126,7 @@ QCefViewPrivate::createCefBrowser(QCefView* view, const QString& url, const QCef
// fallback to software renderer
if (!osr.pRenderer_) {
// create software renderer
if (renderer = CefViewRendererFactory::createRenderer(false)) {
if ((renderer = CefViewRendererFactory::createRenderer(false))) {
// initialize renderer
auto ws = q_ptr->size();
if (renderer->initialize(nullptr, //
Expand Down
14 changes: 8 additions & 6 deletions src/details/render/CefViewRendererFactory.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
#include "CefViewRendererFactory.h"
#include "CefViewRendererFactory.h"

#include "hardware/CefViewHardwareRenderer.h"
#include "software/CefViewSoftwareRenderer.h"
#include "software/QtSoftwareRenderer.h"

std::shared_ptr<ICefViewRenderer>
CefViewRendererFactory::createRenderer(bool hardware)
namespace CefViewRendererFactory {
CefViewRendererPtr
createRenderer(bool hardware)
{
if (hardware) {
return std::make_shared<CefViewHardwareRenderer>();
return createHardwareRenderer();
} else {
return std::make_shared<CefViewSoftwareRenderer>();
return std::make_shared<QtSoftwareRenderer>();
}
}
} // namespace CefViewRendererFactory
14 changes: 5 additions & 9 deletions src/details/render/CefViewRendererFactory.h
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
#ifndef CEFVIEWRENDERERFACTORY_H
#ifndef CEFVIEWRENDERERFACTORY_H
#define CEFVIEWRENDERERFACTORY_H

#pragma once

#include <memory>

#include "ICefViewRenderer.h"

class CefViewRendererFactory
{
public:
static std::shared_ptr<ICefViewRenderer> createRenderer(bool hardware);
};
namespace CefViewRendererFactory {

CefViewRendererPtr
createRenderer(bool hardware);
}
#endif
5 changes: 4 additions & 1 deletion src/details/render/ICefViewRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define ICEFVIEWRENDERER_H

#pragma once
#include <memory>

#include <include/cef_app.h>

Expand All @@ -16,7 +17,7 @@ class ICefViewRenderer
/// <summary>
///
/// </summary>
virtual ~ICefViewRenderer() {};
virtual ~ICefViewRenderer(){};

/// <summary>
///
Expand Down Expand Up @@ -108,4 +109,6 @@ class ICefViewRenderer
virtual void render(void* painter) = 0;
};

using CefViewRendererPtr = std::shared_ptr<ICefViewRenderer>;

#endif
64 changes: 8 additions & 56 deletions src/details/render/hardware/CefViewHardwareRenderer.cpp
Original file line number Diff line number Diff line change
@@ -1,71 +1,23 @@
#include "CefViewHardwareRenderer.h"
#include "CefViewHardwareRenderer.h"

#if defined(OS_WINDOWS)
#include "win/details/render/hardware/DX11RenderBackend.h"
#elif defined(OS_MACOS)
#include "mac/details/render/hardware/MetalRenderBackend.h"
#elif defined(OS_LINUX)
#else
#endif

CefViewHardwareRenderer::CefViewHardwareRenderer()
CefViewRendererPtr
createHardwareRenderer()
{
#if defined(OS_WINDOWS)
: pBackend_(std::make_unique<DX11RenderBackend>())
return std::make_shared<DX11RenderBackend>();
#elif defined(OS_MACOS)
: pBackend_(nullptr)
return std::make_shared<MetalRenderBackend>();
#elif defined(OS_LINUX)
: pBackend_(nullptr)
return null;
#else
#error "Unsupported platform"
#endif
{
}

CefViewHardwareRenderer::~CefViewHardwareRenderer()
{
pBackend_.reset();
}

bool
CefViewHardwareRenderer::initialize(void* wid, int width, int height, float scale, const CefColor& background)
{
return pBackend_->initialize(wid, width, height, scale, background);
}

void
CefViewHardwareRenderer::uninitialize()
{
pBackend_->uninitialize();
}

void
CefViewHardwareRenderer::resize(int width, int height, float scale)
{
pBackend_->resize(width, height, scale);
}

void
CefViewHardwareRenderer::updatePopupVisibility(bool visible)
{
pBackend_->updatePopupVisibility(visible);
}

void
CefViewHardwareRenderer::updatePopupRect(const CefRect& rect)
{
pBackend_->updatePopupRect(rect);
}

void
CefViewHardwareRenderer::updateFrameData(const CefRenderHandler::PaintElementType& type,
const CefRenderHandler::RectList& dirtyRects,
const FrameDataType& dataType,
const FrameData& data)
{
pBackend_->updateFrameData(type, dirtyRects, dataType, data);
}

void
CefViewHardwareRenderer::render(void* painter)
{
pBackend_->render(nullptr);
}
35 changes: 3 additions & 32 deletions src/details/render/hardware/CefViewHardwareRenderer.h
Original file line number Diff line number Diff line change
@@ -1,39 +1,10 @@
#ifndef CEFVIEWHARDWARERENDERER_H
#ifndef CEFVIEWHARDWARERENDERER_H
#define CEFVIEWHARDWARERENDERER_H

#pragma once

#include <memory>

#include "../ICefViewRenderer.h"

class CefViewHardwareRenderer : public ICefViewRenderer
{
private:
std::unique_ptr<ICefViewRenderer> pBackend_;

public:
CefViewHardwareRenderer();
~CefViewHardwareRenderer();

bool isHardware() override { return true; }

bool initialize(void* wid, int width, int height, float scale, const CefColor& background) override;

void uninitialize() override;

void resize(int width, int height, float scale) override;

void updatePopupVisibility(bool visible) override;

void updatePopupRect(const CefRect& rect) override;

void updateFrameData(const CefRenderHandler::PaintElementType& type,
const CefRenderHandler::RectList& dirtyRects,
const FrameDataType& dataType,
const FrameData& data) override;

void render(void* painter) override;
};
CefViewRendererPtr
createHardwareRenderer();

#endif
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
#include "CefViewSoftwareRenderer.h"
#include "QtSoftwareRenderer.h"

#include <QMutexLocker>
#include <QPainter>

CefViewSoftwareRenderer::CefViewSoftwareRenderer() {}
QtSoftwareRenderer::QtSoftwareRenderer() {}

CefViewSoftwareRenderer::~CefViewSoftwareRenderer() {}
QtSoftwareRenderer::~QtSoftwareRenderer() {}

bool
CefViewSoftwareRenderer::initialize(void* wid, int width, int height, float scale, const CefColor& background)
QtSoftwareRenderer::initialize(void* wid, int width, int height, float scale, const CefColor& background)
{
m_width = width;
m_height = height;
Expand All @@ -18,20 +18,20 @@ CefViewSoftwareRenderer::initialize(void* wid, int width, int height, float scal
}

void
CefViewSoftwareRenderer::uninitialize()
QtSoftwareRenderer::uninitialize()
{
}

void
CefViewSoftwareRenderer::resize(int width, int height, float scale)
QtSoftwareRenderer::resize(int width, int height, float scale)
{
QMutexLocker lock(&(m_qViewPaintLock));
m_width = width;
m_height = height;
}

void
CefViewSoftwareRenderer::updatePopupVisibility(bool visible)
QtSoftwareRenderer::updatePopupVisibility(bool visible)
{
m_showPopup = visible;

Expand All @@ -41,16 +41,16 @@ CefViewSoftwareRenderer::updatePopupVisibility(bool visible)
}

void
CefViewSoftwareRenderer::updatePopupRect(const CefRect& rect)
QtSoftwareRenderer::updatePopupRect(const CefRect& rect)
{
m_popupRect = rect;
}

void
CefViewSoftwareRenderer::updateFrameData(const CefRenderHandler::PaintElementType& type,
const CefRenderHandler::RectList& dirtyRects,
const FrameDataType& dataType,
const FrameData& data)
QtSoftwareRenderer::updateFrameData(const CefRenderHandler::PaintElementType& type,
const CefRenderHandler::RectList& dirtyRects,
const FrameDataType& dataType,
const FrameData& data)
{
// we only process Image data
if (dataType != FrameDataType::CpuImage) {
Expand Down Expand Up @@ -95,7 +95,7 @@ CefViewSoftwareRenderer::updateFrameData(const CefRenderHandler::PaintElementTyp
}

void
CefViewSoftwareRenderer::render(void* painter)
QtSoftwareRenderer::render(void* painter)
{
if (!painter) {
return;
Expand Down
Loading

0 comments on commit dc87993

Please sign in to comment.