android: extend secondary display presentation

This commit is contained in:
AverageConsumer
2026-08-16 22:57:10 +02:00
parent 46f73b7bb3
commit 1fc34da2a9
6 changed files with 308 additions and 28 deletions
@@ -0,0 +1,36 @@
local function read(path)
local file = assert(io.open(path, "rb"))
local source = file:read("*a")
file:close()
return source
end
local function check(value, message)
if not value then error(message, 2) end
end
local java = read(
"mobile/android/love/src/main/java/org/love2d/android/GameActivity.java")
local cpp = read("mobile/android/love/src/jni/love/src/common/android.cpp")
check(java:find("hasSecondaryDisplayCandidate", 1, true)
and java:find("findSecondaryDisplay(self, false)", 1, true)
and java:find("now %- secondaryDetectionAt < 500"),
"Android exposes cached physical detection before Presentation is ready")
check(java:find("presentSecondaryFrame", 1, true)
and java:find("secondaryFrame = new byte", 1, true)
and java:find("rgba.get(secondaryFrame", 1, true),
"extended presentation reuses a retained frame buffer")
check(java:find("java.nio.ByteBuffer.wrap(secondaryFrame)", 1, true),
"a recreated Presentation receives the retained frame")
check(java:find("0xFF000000 | (color & 0x00FFFFFF)", 1, true),
"RGB companion backgrounds become opaque Android colors")
check(java:find("Math.max((float) vw / fw, (float) vh / fh)", 1, true)
and java:find("Math.floor(fit)", 1, true),
"FrameView supports cover and pixel-friendly contain fits")
check(cpp:find("love_android_secondary_detected", 1, true)
and cpp:find("love_android_present_secondary", 1, true)
and cpp:find('"(Ljava/nio/ByteBuffer;IIIZ)Z"', 1, true),
"JNI exports the optional detected and presentation calls")
print("android secondary presentation: ok")
+64
View File
@@ -0,0 +1,64 @@
package.path = "./?.lua;./?/init.lua;" .. package.path
local T = require("tests.harness")
local name = "src.render.SecondScreen"
local oldModule = package.loaded[name]
local oldFfi = package.loaded.ffi
local oldPreload = package.preload.ffi
local calls = {}
local null = {}
local C = {
love_android_secondary_ready = function() return 0 end,
love_android_push_secondary = function(ptr, w, h)
calls.push = { ptr, w, h }
end,
love_android_secondary_enable = function(on) calls.enabled = on end,
love_android_secondary_detected = function() return 1 end,
love_android_present_secondary = function(ptr, w, h, background, cover)
calls.present = { ptr, w, h, background, cover }
return 1
end,
love_android_poll_secondary_touch = function() return null end,
}
local fakeFfi = {
C = C,
NULL = null,
cdef = function() end,
load = function() return C end,
string = function(value) return value end,
}
package.loaded[name] = nil
package.loaded.ffi = nil
package.preload.ffi = function() return fakeFfi end
local SecondScreen = require(name)
local image = { getFFIPointer = function() return "pixels" end }
T.eq(SecondScreen.available(), false,
"an unbound presentation is not render-ready")
T.eq(SecondScreen.detected(), true,
"physical display detection is independent of presentation readiness")
T.eq(SecondScreen.push(image, 160, 144, 0x112233, "secondary:cover"), true,
"extended Android presentation accepts frame metadata")
T.same(calls.present, { "pixels", 160, 144, 0x112233, 1 },
"cover and RGB background reach the native bridge")
T.eq(SecondScreen.push(image, 160, 144, 0x112233, "secondary"), true,
"contain presentation remains available")
T.same(calls.present, { "pixels", 160, 144, 0x112233, 0 },
"contain is the default native fit")
T.eq(SecondScreen.push(image, 160, 144, nil, "secondary:cover"), true,
"a fit preference can request extended presentation by itself")
T.same(calls.present, { "pixels", 160, 144, 0, 1 },
"preference-only presentation defaults to a black background")
T.eq(SecondScreen.push(image, 160, 144), true,
"the original push ABI remains available")
T.same(calls.push, { "pixels", 160, 144 },
"legacy callers retain the original frame path")
package.loaded[name] = oldModule
package.loaded.ffi = oldFfi
package.preload.ffi = oldPreload
T.finish("Android secondary presentation facade")