mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-02-04 15:04:28 +01:00
internal/ui: move impls for device scale to internal/ui for mobiles
This commit is contained in:
parent
b243dc0649
commit
458a415131
@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
//go:build !js
|
//go:build !android && !ios && !js
|
||||||
|
|
||||||
package devicescale
|
package devicescale
|
||||||
|
|
||||||
|
@ -1,105 +0,0 @@
|
|||||||
// Copyright 2016 Hajime Hoshi
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package devicescale
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
#include <jni.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
// Basically same as:
|
|
||||||
//
|
|
||||||
// WindowService windowService = context.getSystemService(Context.WINDOW_SERVICE);
|
|
||||||
// Display display = windowManager.getDefaultDisplay();
|
|
||||||
// DisplayMetrics displayMetrics = new DisplayMetrics();
|
|
||||||
// display.getRealMetrics(displayMetrics);
|
|
||||||
// this.deviceScale = displayMetrics.density;
|
|
||||||
//
|
|
||||||
static float deviceScale(uintptr_t java_vm, uintptr_t jni_env, uintptr_t ctx) {
|
|
||||||
JavaVM* vm = (JavaVM*)java_vm;
|
|
||||||
JNIEnv* env = (JNIEnv*)jni_env;
|
|
||||||
jobject context = (jobject)ctx;
|
|
||||||
|
|
||||||
const char* kWindowService = "window";
|
|
||||||
|
|
||||||
const jclass android_content_Context =
|
|
||||||
(*env)->FindClass(env, "android/content/Context");
|
|
||||||
const jclass android_view_WindowManager =
|
|
||||||
(*env)->FindClass(env, "android/view/WindowManager");
|
|
||||||
const jclass android_view_Display =
|
|
||||||
(*env)->FindClass(env, "android/view/Display");
|
|
||||||
const jclass android_util_DisplayMetrics =
|
|
||||||
(*env)->FindClass(env, "android/util/DisplayMetrics");
|
|
||||||
|
|
||||||
const jobject android_context_Context_WINDOW_SERVICE =
|
|
||||||
(*env)->GetStaticObjectField(
|
|
||||||
env, android_content_Context,
|
|
||||||
(*env)->GetStaticFieldID(env, android_content_Context, "WINDOW_SERVICE", "Ljava/lang/String;"));
|
|
||||||
|
|
||||||
const jobject windowManager =
|
|
||||||
(*env)->CallObjectMethod(
|
|
||||||
env, context,
|
|
||||||
(*env)->GetMethodID(env, android_content_Context, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;"),
|
|
||||||
android_context_Context_WINDOW_SERVICE);
|
|
||||||
const jobject display =
|
|
||||||
(*env)->CallObjectMethod(
|
|
||||||
env, windowManager,
|
|
||||||
(*env)->GetMethodID(env, android_view_WindowManager, "getDefaultDisplay", "()Landroid/view/Display;"));
|
|
||||||
const jobject displayMetrics =
|
|
||||||
(*env)->NewObject(
|
|
||||||
env, android_util_DisplayMetrics,
|
|
||||||
(*env)->GetMethodID(env, android_util_DisplayMetrics, "<init>", "()V"));
|
|
||||||
(*env)->CallVoidMethod(
|
|
||||||
env, display,
|
|
||||||
(*env)->GetMethodID(env, android_view_Display, "getRealMetrics", "(Landroid/util/DisplayMetrics;)V"),
|
|
||||||
displayMetrics);
|
|
||||||
const float density =
|
|
||||||
(*env)->GetFloatField(
|
|
||||||
env, displayMetrics,
|
|
||||||
(*env)->GetFieldID(env, android_util_DisplayMetrics, "density", "F"));
|
|
||||||
|
|
||||||
(*env)->DeleteLocalRef(env, android_content_Context);
|
|
||||||
(*env)->DeleteLocalRef(env, android_view_WindowManager);
|
|
||||||
(*env)->DeleteLocalRef(env, android_view_Display);
|
|
||||||
(*env)->DeleteLocalRef(env, android_util_DisplayMetrics);
|
|
||||||
|
|
||||||
(*env)->DeleteLocalRef(env, android_context_Context_WINDOW_SERVICE);
|
|
||||||
(*env)->DeleteLocalRef(env, windowManager);
|
|
||||||
(*env)->DeleteLocalRef(env, display);
|
|
||||||
(*env)->DeleteLocalRef(env, displayMetrics);
|
|
||||||
|
|
||||||
return density;
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"golang.org/x/mobile/app"
|
|
||||||
)
|
|
||||||
|
|
||||||
func impl(x, y int) float64 {
|
|
||||||
s := 0.0
|
|
||||||
if err := app.RunOnJVM(func(vm, env, ctx uintptr) error {
|
|
||||||
// TODO: This might be crash when this is called from init(). How can we detect this?
|
|
||||||
s = float64(C.deviceScale(C.uintptr_t(vm), C.uintptr_t(env), C.uintptr_t(ctx)))
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
|
||||||
panic(fmt.Sprintf("devicescale: error %v", err))
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
// Copyright 2016 Hajime Hoshi
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package devicescale
|
|
||||||
|
|
||||||
// #cgo CFLAGS: -x objective-c
|
|
||||||
// #cgo LDFLAGS: -framework Foundation -framework UIKit
|
|
||||||
//
|
|
||||||
// #import <UIKit/UIKit.h>
|
|
||||||
//
|
|
||||||
// static double devicePixelRatio() {
|
|
||||||
// return [[UIScreen mainScreen] nativeScale];
|
|
||||||
// }
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
func impl(x, y int) float64 {
|
|
||||||
return float64(C.devicePixelRatio())
|
|
||||||
}
|
|
@ -14,7 +14,80 @@
|
|||||||
|
|
||||||
package ui
|
package ui
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <jni.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
// Basically same as:
|
||||||
|
//
|
||||||
|
// WindowService windowService = context.getSystemService(Context.WINDOW_SERVICE);
|
||||||
|
// Display display = windowManager.getDefaultDisplay();
|
||||||
|
// DisplayMetrics displayMetrics = new DisplayMetrics();
|
||||||
|
// display.getRealMetrics(displayMetrics);
|
||||||
|
// this.deviceScale = displayMetrics.density;
|
||||||
|
//
|
||||||
|
static float deviceScale(uintptr_t java_vm, uintptr_t jni_env, uintptr_t ctx) {
|
||||||
|
JavaVM* vm = (JavaVM*)java_vm;
|
||||||
|
JNIEnv* env = (JNIEnv*)jni_env;
|
||||||
|
jobject context = (jobject)ctx;
|
||||||
|
|
||||||
|
const char* kWindowService = "window";
|
||||||
|
|
||||||
|
const jclass android_content_Context =
|
||||||
|
(*env)->FindClass(env, "android/content/Context");
|
||||||
|
const jclass android_view_WindowManager =
|
||||||
|
(*env)->FindClass(env, "android/view/WindowManager");
|
||||||
|
const jclass android_view_Display =
|
||||||
|
(*env)->FindClass(env, "android/view/Display");
|
||||||
|
const jclass android_util_DisplayMetrics =
|
||||||
|
(*env)->FindClass(env, "android/util/DisplayMetrics");
|
||||||
|
|
||||||
|
const jobject android_context_Context_WINDOW_SERVICE =
|
||||||
|
(*env)->GetStaticObjectField(
|
||||||
|
env, android_content_Context,
|
||||||
|
(*env)->GetStaticFieldID(env, android_content_Context, "WINDOW_SERVICE", "Ljava/lang/String;"));
|
||||||
|
|
||||||
|
const jobject windowManager =
|
||||||
|
(*env)->CallObjectMethod(
|
||||||
|
env, context,
|
||||||
|
(*env)->GetMethodID(env, android_content_Context, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;"),
|
||||||
|
android_context_Context_WINDOW_SERVICE);
|
||||||
|
const jobject display =
|
||||||
|
(*env)->CallObjectMethod(
|
||||||
|
env, windowManager,
|
||||||
|
(*env)->GetMethodID(env, android_view_WindowManager, "getDefaultDisplay", "()Landroid/view/Display;"));
|
||||||
|
const jobject displayMetrics =
|
||||||
|
(*env)->NewObject(
|
||||||
|
env, android_util_DisplayMetrics,
|
||||||
|
(*env)->GetMethodID(env, android_util_DisplayMetrics, "<init>", "()V"));
|
||||||
|
(*env)->CallVoidMethod(
|
||||||
|
env, display,
|
||||||
|
(*env)->GetMethodID(env, android_view_Display, "getRealMetrics", "(Landroid/util/DisplayMetrics;)V"),
|
||||||
|
displayMetrics);
|
||||||
|
const float density =
|
||||||
|
(*env)->GetFloatField(
|
||||||
|
env, displayMetrics,
|
||||||
|
(*env)->GetFieldID(env, android_util_DisplayMetrics, "density", "F"));
|
||||||
|
|
||||||
|
(*env)->DeleteLocalRef(env, android_content_Context);
|
||||||
|
(*env)->DeleteLocalRef(env, android_view_WindowManager);
|
||||||
|
(*env)->DeleteLocalRef(env, android_view_Display);
|
||||||
|
(*env)->DeleteLocalRef(env, android_util_DisplayMetrics);
|
||||||
|
|
||||||
|
(*env)->DeleteLocalRef(env, android_context_Context_WINDOW_SERVICE);
|
||||||
|
(*env)->DeleteLocalRef(env, windowManager);
|
||||||
|
(*env)->DeleteLocalRef(env, display);
|
||||||
|
(*env)->DeleteLocalRef(env, displayMetrics);
|
||||||
|
|
||||||
|
return density;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"golang.org/x/mobile/app"
|
||||||
"golang.org/x/mobile/gl"
|
"golang.org/x/mobile/gl"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||||
@ -41,3 +114,15 @@ func (*graphicsDriverCreatorImpl) newDirectX() (graphicsdriver.Graphics, error)
|
|||||||
func (*graphicsDriverCreatorImpl) newMetal() (graphicsdriver.Graphics, error) {
|
func (*graphicsDriverCreatorImpl) newMetal() (graphicsdriver.Graphics, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func deviceScaleFactorImpl() float64 {
|
||||||
|
var s float64
|
||||||
|
if err := app.RunOnJVM(func(vm, env, ctx uintptr) error {
|
||||||
|
// TODO: This might be crash when this is called from init(). How can we detect this?
|
||||||
|
s = float64(C.deviceScale(C.uintptr_t(vm), C.uintptr_t(env), C.uintptr_t(ctx)))
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
panic(fmt.Sprintf("devicescale: error %v", err))
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
@ -14,6 +14,16 @@
|
|||||||
|
|
||||||
package ui
|
package ui
|
||||||
|
|
||||||
|
// #cgo CFLAGS: -x objective-c
|
||||||
|
// #cgo LDFLAGS: -framework Foundation -framework UIKit
|
||||||
|
//
|
||||||
|
// #import <UIKit/UIKit.h>
|
||||||
|
//
|
||||||
|
// static double devicePixelRatio() {
|
||||||
|
// return [[UIScreen mainScreen] nativeScale];
|
||||||
|
// }
|
||||||
|
import "C"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
@ -86,3 +96,8 @@ func (u *userInterfaceImpl) isGL() (bool, error) {
|
|||||||
|
|
||||||
return u.graphicsDriver.IsGL(), nil
|
return u.graphicsDriver.IsGL(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func deviceScaleFactorImpl() float64 {
|
||||||
|
// TODO: Can this be called from non-main threads?
|
||||||
|
return float64(C.devicePixelRatio())
|
||||||
|
}
|
||||||
|
@ -33,7 +33,6 @@ import (
|
|||||||
"golang.org/x/mobile/event/touch"
|
"golang.org/x/mobile/event/touch"
|
||||||
"golang.org/x/mobile/gl"
|
"golang.org/x/mobile/gl"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/devicescale"
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/gamepad"
|
"github.com/hajimehoshi/ebiten/v2/internal/gamepad"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicscommand"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicscommand"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||||
@ -102,6 +101,9 @@ type userInterfaceImpl struct {
|
|||||||
outsideWidth float64
|
outsideWidth float64
|
||||||
outsideHeight float64
|
outsideHeight float64
|
||||||
|
|
||||||
|
deviceScaleFactorOnce sync.Once
|
||||||
|
deviceScaleFactor float64
|
||||||
|
|
||||||
foreground int32
|
foreground int32
|
||||||
errCh chan error
|
errCh chan error
|
||||||
|
|
||||||
@ -124,10 +126,6 @@ type userInterfaceImpl struct {
|
|||||||
m sync.RWMutex
|
m sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func deviceScale() float64 {
|
|
||||||
return devicescale.GetAt(0, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// appMain is the main routine for gomobile-build mode.
|
// appMain is the main routine for gomobile-build mode.
|
||||||
func (u *userInterfaceImpl) appMain(a app.App) {
|
func (u *userInterfaceImpl) appMain(a app.App) {
|
||||||
var glctx gl.Context
|
var glctx gl.Context
|
||||||
@ -185,7 +183,7 @@ func (u *userInterfaceImpl) appMain(a app.App) {
|
|||||||
}
|
}
|
||||||
switch e.Type {
|
switch e.Type {
|
||||||
case touch.TypeBegin, touch.TypeMove:
|
case touch.TypeBegin, touch.TypeMove:
|
||||||
s := deviceScale()
|
s := u.DeviceScaleFactor()
|
||||||
touches[e.Sequence] = TouchForInput{
|
touches[e.Sequence] = TouchForInput{
|
||||||
ID: TouchID(e.Sequence),
|
ID: TouchID(e.Sequence),
|
||||||
X: float64(e.X) / s,
|
X: float64(e.X) / s,
|
||||||
@ -317,7 +315,7 @@ func (u *userInterfaceImpl) outsideSize() (float64, float64) {
|
|||||||
outsideHeight = u.outsideHeight
|
outsideHeight = u.outsideHeight
|
||||||
} else {
|
} else {
|
||||||
// gomobile build
|
// gomobile build
|
||||||
d := deviceScale()
|
d := u.DeviceScaleFactor()
|
||||||
outsideWidth = float64(u.gbuildWidthPx) / d
|
outsideWidth = float64(u.gbuildWidthPx) / d
|
||||||
outsideHeight = float64(u.gbuildHeightPx) / d
|
outsideHeight = float64(u.gbuildHeightPx) / d
|
||||||
}
|
}
|
||||||
@ -333,7 +331,7 @@ func (u *userInterfaceImpl) update() error {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
w, h := u.outsideSize()
|
w, h := u.outsideSize()
|
||||||
if err := u.context.updateFrame(u.graphicsDriver, w, h, deviceScale(), u, nil); err != nil {
|
if err := u.context.updateFrame(u.graphicsDriver, w, h, u.DeviceScaleFactor(), u, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -417,7 +415,11 @@ func (u *userInterfaceImpl) updateExplicitRenderingModeIfNeeded() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *userInterfaceImpl) DeviceScaleFactor() float64 {
|
func (u *userInterfaceImpl) DeviceScaleFactor() float64 {
|
||||||
return deviceScale()
|
// Assume that the device scale factor never changes on mobiles.
|
||||||
|
u.deviceScaleFactorOnce.Do(func() {
|
||||||
|
u.deviceScaleFactor = deviceScaleFactorImpl()
|
||||||
|
})
|
||||||
|
return u.deviceScaleFactor
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *userInterfaceImpl) readInputState(inputState *InputState) {
|
func (u *userInterfaceImpl) readInputState(inputState *InputState) {
|
||||||
|
Loading…
Reference in New Issue
Block a user