diff --git a/.github/workflows/build-jcef.yml b/.github/workflows/build-jcef.yml index e0df7752..6c4c9ef2 100644 --- a/.github/workflows/build-jcef.yml +++ b/.github/workflows/build-jcef.yml @@ -26,7 +26,6 @@ jobs: tar -czf linux_${{ matrix.platform }}.tar.gz linux_${{ matrix.platform }} .hash sha256sum linux_${{ matrix.platform }}.tar.gz > linux_${{ matrix.platform }}.tar.gz.sha256 - uses: actions/upload-artifact@v4 - if: ${{ github.ref == 'refs/heads/main' }} with: name: 'linux_${{ matrix.platform }}' path: | @@ -56,7 +55,6 @@ jobs: tar -czf windows_${{ matrix.platform }}.tar.gz windows_${{ matrix.platform }} .hash Get-FileHash -Algorithm SHA256 -Path "windows_${{ matrix.platform }}.tar.gz" | Out-File "windows_${{ matrix.platform }}.tar.gz.sha256" - uses: actions/upload-artifact@v4 - if: ${{ github.ref == 'refs/heads/main' }} with: name: 'windows_${{ matrix.platform }}' path: | @@ -65,10 +63,14 @@ jobs: if-no-files-found: error java-cef-macos: - runs-on: [macos-13] + runs-on: ${{ matrix.runner }} strategy: matrix: - platform: [amd64, arm64] + include: + - platform: amd64 + runner: macos-15-intel + - platform: arm64 + runner: macos-latest steps: - uses: actions/checkout@v4 - name: Set up Python 3.9 @@ -88,7 +90,6 @@ jobs: tar -czf macos_${{ matrix.platform }}.tar.gz macos_${{ matrix.platform }} .hash sha256sum macos_${{ matrix.platform }}.tar.gz > macos_${{ matrix.platform }}.tar.gz.sha256 - uses: actions/upload-artifact@v4 - if: ${{ github.ref == 'refs/heads/main' }} with: name: 'macos_${{ matrix.platform }}' path: | diff --git a/java/org/cef/handler/CefAcceleratedPaintInfo.java b/java/org/cef/handler/CefAcceleratedPaintInfo.java index bd8aeedc..505a8921 100644 --- a/java/org/cef/handler/CefAcceleratedPaintInfo.java +++ b/java/org/cef/handler/CefAcceleratedPaintInfo.java @@ -5,39 +5,31 @@ package org.cef.handler; /** - * Structure representing shared texture info for accelerated painting. + * Base structure representing accelerated paint info. Platform-specific + * details are provided by subclasses. */ -public class CefAcceleratedPaintInfo { - /** - * Shared texture handle. The meaning depends on the platform: - * - Windows: HANDLE to a texture that can be opened with D3D11 OpenSharedResource - * - macOS: IOSurface pointer that can be opened with Metal or OpenGL - * - Linux: Contains several planes, each with an fd to the underlying system native buffer - */ - public long shared_texture_handle = 0; - +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() {} - - public CefAcceleratedPaintInfo(long shared_texture_handle, int format, int width, int height) { - this.shared_texture_handle = shared_texture_handle; + + protected CefAcceleratedPaintInfo(int format, int width, int height) { this.format = format; this.width = width; this.height = height; } - + @Override public CefAcceleratedPaintInfo clone() { - return new CefAcceleratedPaintInfo(shared_texture_handle, format, width, height); + return new CefAcceleratedPaintInfo(format, width, height); } } diff --git a/java/org/cef/handler/CefAcceleratedPaintInfoLinux.java b/java/org/cef/handler/CefAcceleratedPaintInfoLinux.java new file mode 100644 index 00000000..9c4d7d70 --- /dev/null +++ b/java/org/cef/handler/CefAcceleratedPaintInfoLinux.java @@ -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; + } +} diff --git a/java/org/cef/handler/CefAcceleratedPaintInfoMac.java b/java/org/cef/handler/CefAcceleratedPaintInfoMac.java new file mode 100644 index 00000000..738924a9 --- /dev/null +++ b/java/org/cef/handler/CefAcceleratedPaintInfoMac.java @@ -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); + } +} diff --git a/java/org/cef/handler/CefAcceleratedPaintInfoWin.java b/java/org/cef/handler/CefAcceleratedPaintInfoWin.java new file mode 100644 index 00000000..f87bbc91 --- /dev/null +++ b/java/org/cef/handler/CefAcceleratedPaintInfoWin.java @@ -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); + } +} diff --git a/java/org/cef/handler/CefRenderHandler.java b/java/org/cef/handler/CefRenderHandler.java index 47754504..bbe529c7 100644 --- a/java/org/cef/handler/CefRenderHandler.java +++ b/java/org/cef/handler/CefRenderHandler.java @@ -74,7 +74,11 @@ public void onPaint(CefBrowser browser, boolean popup, Rectangle[] dirtyRects, * @param browser The browser generating the event. * @param popup True if painting a popup window. * @param dirtyRects Array of dirty regions. - * @param info Contains the shared handle and texture information. + * @param info Platform-specific info instance. Expect one of + * {@link CefAcceleratedPaintInfoWin}, + * {@link CefAcceleratedPaintInfoMac}, + * {@link CefAcceleratedPaintInfoLinux}, or a base + * {@link CefAcceleratedPaintInfo} on unsupported platforms. */ public void onAcceleratedPaint(CefBrowser browser, boolean popup, Rectangle[] dirtyRects, CefAcceleratedPaintInfo info); diff --git a/native/render_handler.cpp b/native/render_handler.cpp index cedb72ef..d1c6a363 100644 --- a/native/render_handler.cpp +++ b/native/render_handler.cpp @@ -4,6 +4,8 @@ #include "render_handler.h" +#include + #include "client_handler.h" #include "jni_util.h" @@ -282,8 +284,16 @@ void RenderHandler::OnAcceleratedPaint(CefRefPtr browser, jboolean jtype = type == PET_VIEW ? JNI_FALSE : JNI_TRUE; ScopedJNIObjectLocal jrectArray(env, NewJNIRectArray(env, dirtyRects)); - // Create CefAcceleratedPaintInfo Java object + // Create platform-specific CefAcceleratedPaintInfo Java object +#if defined(OS_WIN) + ScopedJNIClass cls(env, "org/cef/handler/CefAcceleratedPaintInfoWin"); +#elif defined(OS_MACOSX) + ScopedJNIClass cls(env, "org/cef/handler/CefAcceleratedPaintInfoMac"); +#elif defined(OS_LINUX) + ScopedJNIClass cls(env, "org/cef/handler/CefAcceleratedPaintInfoLinux"); +#else ScopedJNIClass cls(env, "org/cef/handler/CefAcceleratedPaintInfo"); +#endif if (!cls) return; ScopedJNIObjectLocal jpaintInfo(env, NewJNIObject(env, cls)); @@ -297,14 +307,60 @@ void RenderHandler::OnAcceleratedPaint(CefRefPtr browser, #if defined(OS_WIN) SetJNIFieldLong(env, cls, jpaintInfo, "shared_texture_handle", reinterpret_cast(info.shared_texture_handle)); -#else - // On non-Windows platforms, shared_texture_handle is not available - SetJNIFieldLong(env, cls, jpaintInfo, "shared_texture_handle", 0); +#elif defined(OS_MACOSX) + SetJNIFieldLong(env, cls, jpaintInfo, "shared_texture_io_surface", + reinterpret_cast(info.shared_texture_io_surface)); #endif SetJNIFieldInt(env, cls, jpaintInfo, "format", info.format); SetJNIFieldInt(env, cls, jpaintInfo, "width", viewRect.width); SetJNIFieldInt(env, cls, jpaintInfo, "height", viewRect.height); +#if defined(OS_LINUX) + SetJNIFieldInt(env, cls, jpaintInfo, "plane_count", info.plane_count); + SetJNIFieldLong(env, cls, jpaintInfo, "modifier", + static_cast(info.modifier)); + + const int plane_count = info.plane_count; + if (plane_count > 0) { + std::vector fds(plane_count); + std::vector strides(plane_count); + std::vector offsets(plane_count); + std::vector sizes(plane_count); + + for (int i = 0; i < plane_count; ++i) { + fds[i] = info.planes[i].fd; + strides[i] = static_cast(info.planes[i].stride); + offsets[i] = static_cast(info.planes[i].offset); + sizes[i] = static_cast(info.planes[i].size); + } + + jclass paintInfoClass = cls.get(); + jfieldID fdsField = env->GetFieldID(paintInfoClass, "plane_fds", "[I"); + jfieldID stridesField = env->GetFieldID(paintInfoClass, "plane_strides", "[I"); + jfieldID offsetsField = env->GetFieldID(paintInfoClass, "plane_offsets", "[J"); + jfieldID sizesField = env->GetFieldID(paintInfoClass, "plane_sizes", "[J"); + + if (fdsField && stridesField && offsetsField && sizesField) { + jintArray fdsArray = env->NewIntArray(plane_count); + jintArray stridesArray = env->NewIntArray(plane_count); + jlongArray offsetsArray = env->NewLongArray(plane_count); + jlongArray sizesArray = env->NewLongArray(plane_count); + + if (fdsArray && stridesArray && offsetsArray && sizesArray) { + env->SetIntArrayRegion(fdsArray, 0, plane_count, fds.data()); + env->SetIntArrayRegion(stridesArray, 0, plane_count, strides.data()); + env->SetLongArrayRegion(offsetsArray, 0, plane_count, offsets.data()); + env->SetLongArrayRegion(sizesArray, 0, plane_count, sizes.data()); + + env->SetObjectField(jpaintInfo.get(), fdsField, fdsArray); + env->SetObjectField(jpaintInfo.get(), stridesField, stridesArray); + env->SetObjectField(jpaintInfo.get(), offsetsField, offsetsArray); + env->SetObjectField(jpaintInfo.get(), sizesField, sizesArray); + } + } + } +#endif + JNI_CALL_VOID_METHOD(env, handle_, "onAcceleratedPaint", "(Lorg/cef/browser/CefBrowser;Z[Ljava/awt/" "Rectangle;Lorg/cef/handler/CefAcceleratedPaintInfo;)V",