Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions java/org/cef/CefBrowserSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,29 @@ public class CefBrowserSettings {
*/
public int windowless_frame_rate = 0;

/**
* Set to true to enable shared texture rendering. When enabled, the browser
* will render to a shared texture that can be accessed by the host application
* for hardware-accelerated compositing. This is supported on Windows via D3D11,
* macOS via Metal/OpenGL, and Linux via native buffers.
*/
public boolean shared_texture_enabled = false;

/**
* Set to true to enable external begin frame scheduling. When enabled, the
* client must call CefBrowserHost::SendExternalBeginFrame to trigger frame
* rendering at the specified frame rate.
*/
public boolean external_begin_frame_enabled = false;

public CefBrowserSettings() {}

@Override
public CefBrowserSettings clone() {
CefBrowserSettings tmp = new CefBrowserSettings();
tmp.windowless_frame_rate = windowless_frame_rate;
tmp.shared_texture_enabled = shared_texture_enabled;
tmp.external_begin_frame_enabled = external_begin_frame_enabled;
return tmp;
}
}
19 changes: 19 additions & 0 deletions java/org/cef/CefClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.cef.callback.CefMenuModel;
import org.cef.callback.CefPrintDialogCallback;
import org.cef.callback.CefPrintJobCallback;
import org.cef.handler.CefAcceleratedPaintInfo;
import org.cef.handler.CefClientHandler;
import org.cef.handler.CefContextMenuHandler;
import org.cef.handler.CefDialogHandler;
Expand Down Expand Up @@ -768,6 +769,15 @@ public void onPaint(CefBrowser browser, boolean popup, Rectangle[] dirtyRects,
realHandler.onPaint(browser, popup, dirtyRects, buffer, width, height);
}

@Override
public void onAcceleratedPaint(CefBrowser browser, boolean popup, Rectangle[] dirtyRects, CefAcceleratedPaintInfo info) {
if (browser == null) return;

CefRenderHandler realHandler = browser.getRenderHandler();
if (realHandler != null)
realHandler.onAcceleratedPaint(browser, popup, dirtyRects, info);
}

@Override
public void addOnPaintListener(Consumer<CefPaintEvent> listener) {}

Expand All @@ -777,6 +787,15 @@ public void setOnPaintListener(Consumer<CefPaintEvent> listener) {}
@Override
public void removeOnPaintListener(Consumer<CefPaintEvent> listener) {}

@Override
public void addOnAcceleratedPaintListener(Consumer<CefAcceleratedPaintEvent> listener) {}

@Override
public void setOnAcceleratedPaintListener(Consumer<CefAcceleratedPaintEvent> listener) {}

@Override
public void removeOnAcceleratedPaintListener(Consumer<CefAcceleratedPaintEvent> listener) {}

@Override
public boolean startDragging(CefBrowser browser, CefDragData dragData, int mask, int x, int y) {
if (browser == null) return false;
Expand Down
48 changes: 48 additions & 0 deletions java/org/cef/browser/CefAcceleratedPaintEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

package org.cef.browser;

import org.cef.handler.CefAcceleratedPaintInfo;

import java.awt.*;

public class CefAcceleratedPaintEvent {
private final CefBrowser browser;
private final boolean popup;
private final Rectangle[] dirtyRects;
private final CefAcceleratedPaintInfo acceleratedPaintInfo;

public CefAcceleratedPaintEvent(CefBrowser browser, boolean popup, Rectangle[] dirtyRects,
CefAcceleratedPaintInfo acceleratedPaintInfo) {
this.browser = browser;
this.popup = popup;
this.dirtyRects = dirtyRects;
this.acceleratedPaintInfo = acceleratedPaintInfo;
}

public CefBrowser getBrowser() {
return browser;
}

public boolean getPopup() {
return popup;
}

public Rectangle[] getDirtyRects() {
return dirtyRects;
}

public CefAcceleratedPaintInfo getAcceleratedPaintInfo() {
return acceleratedPaintInfo;
}

public int getWidth() {
return acceleratedPaintInfo.width;
}

public int getHeight() {
return acceleratedPaintInfo.height;
}
}
9 changes: 9 additions & 0 deletions java/org/cef/browser/CefBrowser.java
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,15 @@ public void runFileDialog(FileDialogMode mode, String title, String defaultFileP
*/
public void setWindowlessFrameRate(int frameRate);

/**
* Send an external begin frame to trigger frame rendering when external begin frame
* scheduling is enabled. This method should be called at the desired frame rate when
* CefBrowserSettings.external_begin_frame_enabled is set to true.
*
* @throws UnsupportedOperationException if not supported
*/
public void sendExternalBeginFrame();

/**
* Returns the maximum rate in frames per second (fps) that {@code CefRenderHandler::onPaint}
* will be called for a windowless browser. The actual fps may be lower if the browser cannot
Expand Down
54 changes: 54 additions & 0 deletions java/org/cef/browser/CefBrowserOsr.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.cef.CefClient;
import org.cef.OS;
import org.cef.callback.CefDragData;
import org.cef.handler.CefAcceleratedPaintInfo;
import org.cef.handler.CefRenderHandler;
import org.cef.handler.CefScreenInfo;

Expand Down Expand Up @@ -90,6 +91,9 @@ class CefBrowserOsr extends CefBrowser_N implements CefRenderHandler {
private CopyOnWriteArrayList<Consumer<CefPaintEvent>> onPaintListeners =
new CopyOnWriteArrayList<>();

private CopyOnWriteArrayList<Consumer<CefAcceleratedPaintEvent>> onAcceleratedPaintListeners =
new CopyOnWriteArrayList<>();

CefBrowserOsr(CefClient client, String url, boolean transparent, CefRequestContext context,
CefBrowserSettings settings) {
this(client, url, transparent, context, null, null, settings);
Expand Down Expand Up @@ -378,6 +382,22 @@ public void removeOnPaintListener(Consumer<CefPaintEvent> listener) {
onPaintListeners.remove(listener);
}

@Override
public void addOnAcceleratedPaintListener(Consumer<CefAcceleratedPaintEvent> listener) {
onAcceleratedPaintListeners.add(listener);
}

@Override
public void setOnAcceleratedPaintListener(Consumer<CefAcceleratedPaintEvent> listener) {
onAcceleratedPaintListeners.clear();
onAcceleratedPaintListeners.add(listener);
}

@Override
public void removeOnAcceleratedPaintListener(Consumer<CefAcceleratedPaintEvent> listener) {
onAcceleratedPaintListeners.remove(listener);
}

@Override
public void onPaint(CefBrowser browser, boolean popup, Rectangle[] dirtyRects,
ByteBuffer buffer, int width, int height) {
Expand Down Expand Up @@ -409,6 +429,40 @@ public void run() {
}
}

@Override
public void onAcceleratedPaint(CefBrowser browser, boolean popup, Rectangle[] dirtyRects, CefAcceleratedPaintInfo info) {
// If window is closing, canvas_ or opengl context could be null
final GLContext context = canvas_ != null ? canvas_.getContext() : null;

if (context == null) {
return;
}

// This result can occur due to GLContext re-initialization when changing displays.
if (context.makeCurrent() == GLContext.CONTEXT_NOT_CURRENT) {
return;
}

// TODO: Implement renderer handling for accelerated paint
// On Windows, convert the D3D11 shared texture handle using ImportMemoryWin32HandleEXT
// through OpenGL's EXT_external_objects_win32. LWJGL supports it, but I am not familiar with JOGL's API.
// renderer_.onAcceleratedPaint(canvas_.getGL().getGL2(), popup, dirtyRects, info);

context.release();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
canvas_.display();
}
});
if (!onAcceleratedPaintListeners.isEmpty()) {
CefAcceleratedPaintEvent paintEvent =
new CefAcceleratedPaintEvent(browser, popup, dirtyRects, info);
for (Consumer<CefAcceleratedPaintEvent> l : onAcceleratedPaintListeners) {
l.accept(paintEvent);
}
}
}

@Override
public boolean onCursorChange(CefBrowser browser, final int cursorType) {
SwingUtilities.invokeLater(new Runnable() {
Expand Down
9 changes: 9 additions & 0 deletions java/org/cef/browser/CefBrowser_N.java
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,14 @@ public void setWindowlessFrameRate(int frameRate) {
}
}

public void sendExternalBeginFrame() {
try {
N_SendExternalBeginFrame();
} catch (UnsatisfiedLinkError ule) {
ule.printStackTrace();
}
}

public CompletableFuture<Integer> getWindowlessFrameRate() {
final CompletableFuture<Integer> future = new CompletableFuture<>();
try {
Expand Down Expand Up @@ -883,5 +891,6 @@ private final native void N_DragTargetDragEnter(
private final native void N_SetParent(long windowHandle, Component canvas);
private final native void N_NotifyMoveOrResizeStarted();
private final native void N_SetWindowlessFrameRate(int frameRate);
private final native void N_SendExternalBeginFrame();
private final native void N_GetWindowlessFrameRate(IntCallback frameRateCallback);
}
35 changes: 35 additions & 0 deletions java/org/cef/handler/CefAcceleratedPaintInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

package org.cef.handler;

/**
* Base structure representing accelerated paint info. Platform-specific
* details are provided by subclasses.
*/
public class CefAcceleratedPaintInfo implements Cloneable {
/**
* Format of the shared texture.
*/
public int format = 0;

/**
* Size information for the shared texture.
*/
public int width = 0;
public int height = 0;

public CefAcceleratedPaintInfo() {}

protected CefAcceleratedPaintInfo(int format, int width, int height) {
this.format = format;
this.width = width;
this.height = height;
}

@Override
public CefAcceleratedPaintInfo clone() {
return new CefAcceleratedPaintInfo(format, width, height);
}
}
62 changes: 62 additions & 0 deletions java/org/cef/handler/CefAcceleratedPaintInfoLinux.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

package org.cef.handler;

/**
* Linux-specific accelerated paint info (dmabuf planes).
*/
public class CefAcceleratedPaintInfoLinux extends CefAcceleratedPaintInfo {
/**
* dmabuf plane count.
*/
public int plane_count = 0;

/**
* dmabuf plane file descriptors.
*/
public int[] plane_fds = null;

/**
* dmabuf plane strides (bytes per row).
*/
public int[] plane_strides = null;

/**
* dmabuf plane offsets.
*/
public long[] plane_offsets = null;

/**
* dmabuf plane sizes.
*/
public long[] plane_sizes = null;

/**
* dmabuf modifier.
*/
public long modifier = 0;

public CefAcceleratedPaintInfoLinux() {}

public CefAcceleratedPaintInfoLinux(int format, int width, int height) {
super(format, width, height);
}

public boolean hasDmaBufPlanes() {
return plane_count > 0 && plane_fds != null && plane_strides != null && plane_offsets != null;
}

@Override
public CefAcceleratedPaintInfoLinux clone() {
CefAcceleratedPaintInfoLinux clone = new CefAcceleratedPaintInfoLinux(format, width, height);
clone.plane_count = plane_count;
clone.modifier = modifier;
clone.plane_fds = plane_fds != null ? plane_fds.clone() : null;
clone.plane_strides = plane_strides != null ? plane_strides.clone() : null;
clone.plane_offsets = plane_offsets != null ? plane_offsets.clone() : null;
clone.plane_sizes = plane_sizes != null ? plane_sizes.clone() : null;
return clone;
}
}
27 changes: 27 additions & 0 deletions java/org/cef/handler/CefAcceleratedPaintInfoMac.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

package org.cef.handler;

/**
* macOS-specific accelerated paint info.
*/
public class CefAcceleratedPaintInfoMac extends CefAcceleratedPaintInfo {
/**
* IOSurface handle that can be opened with Metal or OpenGL.
*/
public long shared_texture_io_surface = 0;

public CefAcceleratedPaintInfoMac() {}

public CefAcceleratedPaintInfoMac(long shared_texture_io_surface, int format, int width, int height) {
super(format, width, height);
this.shared_texture_io_surface = shared_texture_io_surface;
}

@Override
public CefAcceleratedPaintInfoMac clone() {
return new CefAcceleratedPaintInfoMac(shared_texture_io_surface, format, width, height);
}
}
27 changes: 27 additions & 0 deletions java/org/cef/handler/CefAcceleratedPaintInfoWin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

package org.cef.handler;

/**
* Windows-specific accelerated paint info.
*/
public class CefAcceleratedPaintInfoWin extends CefAcceleratedPaintInfo {
/**
* HANDLE to a texture that can be opened with D3D11 OpenSharedResource.
*/
public long shared_texture_handle = 0;

public CefAcceleratedPaintInfoWin() {}

public CefAcceleratedPaintInfoWin(long shared_texture_handle, int format, int width, int height) {
super(format, width, height);
this.shared_texture_handle = shared_texture_handle;
}

@Override
public CefAcceleratedPaintInfoWin clone() {
return new CefAcceleratedPaintInfoWin(shared_texture_handle, format, width, height);
}
}
Loading