Skip to content

Commit cb34500

Browse files
committed
feat: accelerated paint
1 parent ca49ada commit cb34500

15 files changed

+267
-1
lines changed

java/org/cef/CefBrowserSettings.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
package org.cef;
66

7+
import org.cef.handler.CefOsrRendererSettings;
8+
79
/**
810
* Browser initialization settings. Specify NULL or 0 to get the recommended
911
* default values. The consequences of using custom values may not be well
@@ -20,12 +22,29 @@ public class CefBrowserSettings {
2022
*/
2123
public int windowless_frame_rate = 0;
2224

25+
/**
26+
* Set to true to enable shared texture rendering. When enabled, the browser
27+
* will render to a shared texture that can be accessed by the host application
28+
* for hardware-accelerated compositing. This is supported on Windows via D3D11,
29+
* macOS via Metal/OpenGL, and Linux via native buffers.
30+
*/
31+
public boolean shared_texture_enabled = false;
32+
33+
/**
34+
* Set to true to enable external begin frame scheduling. When enabled, the
35+
* client must call CefBrowserHost::SendExternalBeginFrame to trigger frame
36+
* rendering at the specified frame rate.
37+
*/
38+
public boolean external_begin_frame_enabled = false;
39+
2340
public CefBrowserSettings() {}
2441

2542
@Override
2643
public CefBrowserSettings clone() {
2744
CefBrowserSettings tmp = new CefBrowserSettings();
2845
tmp.windowless_frame_rate = windowless_frame_rate;
46+
tmp.shared_texture_enabled = shared_texture_enabled;
47+
tmp.external_begin_frame_enabled = external_begin_frame_enabled;
2948
return tmp;
3049
}
3150
}

java/org/cef/CefClient.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import org.cef.callback.CefMenuModel;
1818
import org.cef.callback.CefPrintDialogCallback;
1919
import org.cef.callback.CefPrintJobCallback;
20+
import org.cef.handler.CefAcceleratedPaintInfo;
2021
import org.cef.handler.CefClientHandler;
2122
import org.cef.handler.CefContextMenuHandler;
2223
import org.cef.handler.CefDialogHandler;
@@ -768,6 +769,15 @@ public void onPaint(CefBrowser browser, boolean popup, Rectangle[] dirtyRects,
768769
realHandler.onPaint(browser, popup, dirtyRects, buffer, width, height);
769770
}
770771

772+
@Override
773+
public void onAcceleratedPaint(CefBrowser browser, boolean popup, Rectangle[] dirtyRects, CefAcceleratedPaintInfo info) {
774+
if (browser == null) return;
775+
776+
CefRenderHandler realHandler = browser.getRenderHandler();
777+
if (realHandler != null)
778+
realHandler.onAcceleratedPaint(browser, popup, dirtyRects, info);
779+
}
780+
771781
@Override
772782
public void addOnPaintListener(Consumer<CefPaintEvent> listener) {}
773783

java/org/cef/browser/CefBrowser.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,15 @@ public void runFileDialog(FileDialogMode mode, String title, String defaultFileP
405405
*/
406406
public void setWindowlessFrameRate(int frameRate);
407407

408+
/**
409+
* Send an external begin frame to trigger frame rendering when external begin frame
410+
* scheduling is enabled. This method should be called at the desired frame rate when
411+
* CefBrowserSettings.external_begin_frame_enabled is set to true.
412+
*
413+
* @throws UnsupportedOperationException if not supported
414+
*/
415+
public void sendExternalBeginFrame();
416+
408417
/**
409418
* Returns the maximum rate in frames per second (fps) that {@code CefRenderHandler::onPaint}
410419
* will be called for a windowless browser. The actual fps may be lower if the browser cannot

java/org/cef/browser/CefBrowserOsr.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.cef.CefClient;
2020
import org.cef.OS;
2121
import org.cef.callback.CefDragData;
22+
import org.cef.handler.CefAcceleratedPaintInfo;
2223
import org.cef.handler.CefRenderHandler;
2324
import org.cef.handler.CefScreenInfo;
2425

@@ -409,6 +410,11 @@ public void run() {
409410
}
410411
}
411412

413+
@Override
414+
public void onAcceleratedPaint(CefBrowser browser, boolean popup, Rectangle[] dirtyRects, CefAcceleratedPaintInfo info) {
415+
// TODO: Implement example for accelerated paint
416+
}
417+
412418
@Override
413419
public boolean onCursorChange(CefBrowser browser, final int cursorType) {
414420
SwingUtilities.invokeLater(new Runnable() {

java/org/cef/browser/CefBrowser_N.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,14 @@ public void setWindowlessFrameRate(int frameRate) {
799799
}
800800
}
801801

802+
public void sendExternalBeginFrame() {
803+
try {
804+
N_SendExternalBeginFrame();
805+
} catch (UnsatisfiedLinkError ule) {
806+
ule.printStackTrace();
807+
}
808+
}
809+
802810
public CompletableFuture<Integer> getWindowlessFrameRate() {
803811
final CompletableFuture<Integer> future = new CompletableFuture<>();
804812
try {
@@ -882,5 +890,6 @@ private final native void N_DragTargetDragEnter(
882890
private final native void N_SetParent(long windowHandle, Component canvas);
883891
private final native void N_NotifyMoveOrResizeStarted();
884892
private final native void N_SetWindowlessFrameRate(int frameRate);
893+
private final native void N_SendExternalBeginFrame();
885894
private final native void N_GetWindowlessFrameRate(IntCallback frameRateCallback);
886895
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights
2+
// reserved. Use of this source code is governed by a BSD-style license that
3+
// can be found in the LICENSE file.
4+
5+
package org.cef.handler;
6+
7+
/**
8+
* Structure representing shared texture info for accelerated painting.
9+
*/
10+
public class CefAcceleratedPaintInfo {
11+
/**
12+
* Shared texture handle. The meaning depends on the platform:
13+
* - Windows: HANDLE to a texture that can be opened with D3D11 OpenSharedResource
14+
* - macOS: IOSurface pointer that can be opened with Metal or OpenGL
15+
* - Linux: Contains several planes, each with an fd to the underlying system native buffer
16+
*/
17+
public long shared_texture_handle = 0;
18+
19+
/**
20+
* Format of the shared texture.
21+
*/
22+
public int format = 0;
23+
24+
/**
25+
* Size information for the shared texture.
26+
*/
27+
public int width = 0;
28+
public int height = 0;
29+
30+
public CefAcceleratedPaintInfo() {}
31+
32+
public CefAcceleratedPaintInfo(long shared_texture_handle, int format, int width, int height) {
33+
this.shared_texture_handle = shared_texture_handle;
34+
this.format = format;
35+
this.width = width;
36+
this.height = height;
37+
}
38+
39+
@Override
40+
public CefAcceleratedPaintInfo clone() {
41+
return new CefAcceleratedPaintInfo(shared_texture_handle, format, width, height);
42+
}
43+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights
2+
// reserved. Use of this source code is governed by a BSD-style license that
3+
// can be found in the LICENSE file.
4+
5+
package org.cef.handler;
6+
7+
/**
8+
* Settings for off-screen rendering (OSR) configuration.
9+
* Based on CEF's OsrRendererSettings structure.
10+
*/
11+
public class CefOsrRendererSettings {
12+
13+
/**
14+
* If true draw a border around update rectangles.
15+
*/
16+
public boolean show_update_rect = false;
17+
18+
/**
19+
* If true return real screen bounds from GetRootScreenRect/GetScreenInfo.
20+
* - Allows window.outerWidth/Height and window.screenX/Y to return correct values.
21+
* - Allows JavaScript window.moveTo/By() and window.resizeTo/By() to provide
22+
* bounds that include the window frame.
23+
* - Causes HTML select popups to be cropped (limitation of implementation).
24+
*/
25+
public boolean real_screen_bounds = true;
26+
27+
/**
28+
* Background color. Enables transparency if the alpha component is 0.
29+
* 32-bit ARGB color value, not premultiplied.
30+
*/
31+
public int background_color = 0;
32+
33+
/**
34+
* Render using shared textures. Supported on Windows only via D3D11.
35+
* When enabled, the browser will render to a shared texture that can be
36+
* accessed by the host application for hardware-accelerated compositing.
37+
*/
38+
public boolean shared_texture_enabled = false;
39+
40+
/**
41+
* Client implements a BeginFrame timer by calling
42+
* CefBrowserHost::SendExternalBeginFrame at the specified frame rate.
43+
*/
44+
public boolean external_begin_frame_enabled = false;
45+
46+
/**
47+
* Frame rate for external begin frame when external_begin_frame_enabled is true.
48+
*/
49+
public int begin_frame_rate = 0;
50+
51+
public CefOsrRendererSettings() {}
52+
53+
/**
54+
* Copy constructor.
55+
*/
56+
public CefOsrRendererSettings(CefOsrRendererSettings other) {
57+
this.show_update_rect = other.show_update_rect;
58+
this.real_screen_bounds = other.real_screen_bounds;
59+
this.background_color = other.background_color;
60+
this.shared_texture_enabled = other.shared_texture_enabled;
61+
this.external_begin_frame_enabled = other.external_begin_frame_enabled;
62+
this.begin_frame_rate = other.begin_frame_rate;
63+
}
64+
65+
@Override
66+
public CefOsrRendererSettings clone() {
67+
return new CefOsrRendererSettings(this);
68+
}
69+
}

java/org/cef/handler/CefRenderHandler.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,17 @@ public interface CefRenderHandler {
6767
public void onPaint(CefBrowser browser, boolean popup, Rectangle[] dirtyRects,
6868
ByteBuffer buffer, int width, int height);
6969

70+
/**
71+
* Called when an element has been rendered to the shared texture handle.
72+
* This method is only called when CefWindowInfo::shared_texture_enabled is set to true.
73+
* @param browser The browser generating the event.
74+
* @param popup True if painting a popup window.
75+
* @param dirtyRects Array of dirty regions.
76+
* @param info Contains the shared handle and texture information.
77+
*/
78+
public void onAcceleratedPaint(CefBrowser browser, boolean popup, Rectangle[] dirtyRects,
79+
CefAcceleratedPaintInfo info);
80+
7081
/**
7182
* Add provided listener.
7283
* @param listener Code that gets executed after a frame was rendered.

java/org/cef/handler/CefRenderHandlerAdapter.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ public void onPopupSize(CefBrowser browser, Rectangle size) {}
4242
public void onPaint(CefBrowser browser, boolean popup, Rectangle[] dirtyRects,
4343
ByteBuffer buffer, int width, int height) {}
4444

45+
@Override
46+
public void onAcceleratedPaint(CefBrowser browser, boolean popup, Rectangle[] dirtyRects,
47+
CefAcceleratedPaintInfo info) {}
48+
4549
@Override
4650
public boolean onCursorChange(CefBrowser browser, int cursorType) {
4751
return false;

native/CefBrowser_N.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ KeyboardCode KeyboardCodeFromXKeysym(unsigned int keysym) {
505505
return VKEY_OEM_7;
506506
case XK_ISO_Level5_Shift:
507507
return VKEY_OEM_8;
508-
case XK_Shift_L:
508+
case XK_Shift_L:
509509
case XK_Shift_R:
510510
return VKEY_SHIFT;
511511
case XK_Control_L:
@@ -1010,6 +1010,10 @@ void create(std::shared_ptr<JNIObjectsForCreate> objs,
10101010
objs->jbrowserSettings != nullptr) { // Dev-tools settings are null
10111011
GetJNIFieldInt(env, cefBrowserSettings, objs->jbrowserSettings,
10121012
"windowless_frame_rate", &settings.windowless_frame_rate);
1013+
GetJNIFieldBoolean(env, cefBrowserSettings, objs->jbrowserSettings,
1014+
"shared_texture_enabled", &windowInfo.shared_texture_enabled);
1015+
GetJNIFieldBoolean(env, cefBrowserSettings, objs->jbrowserSettings,
1016+
"external_begin_frame_enabled", &windowInfo.external_begin_frame_enabled);
10131017
}
10141018

10151019
CefRefPtr<CefBrowser> browserObj;
@@ -2170,6 +2174,14 @@ Java_org_cef_browser_CefBrowser_1N_N_1SetWindowlessFrameRate(JNIEnv* env,
21702174
host->SetWindowlessFrameRate(frameRate);
21712175
}
21722176

2177+
JNIEXPORT void JNICALL
2178+
Java_org_cef_browser_CefBrowser_1N_N_1SendExternalBeginFrame(JNIEnv* env,
2179+
jobject jbrowser) {
2180+
CefRefPtr<CefBrowser> browser = JNI_GET_BROWSER_OR_RETURN(env, jbrowser);
2181+
CefRefPtr<CefBrowserHost> host = browser->GetHost();
2182+
host->SendExternalBeginFrame();
2183+
}
2184+
21732185
void getWindowlessFrameRate(CefRefPtr<CefBrowserHost> host,
21742186
CefRefPtr<IntCallback> callback) {
21752187
callback->onComplete((jint)host->GetWindowlessFrameRate());

0 commit comments

Comments
 (0)