Use the hardware scaler again on Android. Move all DPI handling code from java to app-android.cpp.

This commit is contained in:
Henrik Rydgard 2015-12-16 14:52:44 +01:00
parent 04f8bffa29
commit 13515bf235
13 changed files with 239 additions and 197 deletions

View File

@ -72,7 +72,7 @@
<PreprocessorDefinitions>USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;_M_IX86=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<AdditionalIncludeDirectories>../ext/native</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../ext/native;..</AdditionalIncludeDirectories>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
@ -99,7 +99,7 @@
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PreprocessorDefinitions>USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_64=1;_M_X64=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../ext/native</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../ext/native;..</AdditionalIncludeDirectories>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
<OmitFramePointers>false</OmitFramePointers>
@ -132,7 +132,7 @@
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
<AdditionalIncludeDirectories>../ext/native</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../ext/native;..</AdditionalIncludeDirectories>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
@ -161,7 +161,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_64=1;_M_X64=1;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
<AdditionalIncludeDirectories>../ext/native</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../ext/native;..</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Fast</FloatingPointModel>
@ -209,6 +209,19 @@
<ClInclude Include="Crypto\sha256.h" />
<ClInclude Include="FileUtil.h" />
<ClInclude Include="FixedSizeQueue.h" />
<ClInclude Include="GL\GLInterfaceBase.h" />
<ClInclude Include="GL\GLInterface\EGL.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="GL\GLInterface\EGLAndroid.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="KeyMap.h" />
<ClInclude Include="Log.h" />
<ClInclude Include="LogManager.h" />
@ -258,6 +271,24 @@
<ClCompile Include="Crypto\sha1.cpp" />
<ClCompile Include="Crypto\sha256.cpp" />
<ClCompile Include="FileUtil.cpp" />
<ClCompile Include="GL\GLInterface\EGL.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GL\GLInterface\EGLAndroid.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GL\GLInterface\GLInterface.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="KeyMap.cpp" />
<ClCompile Include="LogManager.cpp" />
<ClCompile Include="MemArena.cpp" />

View File

@ -48,6 +48,15 @@
<ClInclude Include="ColorConv.h" />
<ClInclude Include="ColorConvNEON.h" />
<ClInclude Include="ThreadSafeList.h" />
<ClInclude Include="GL\GLInterface\EGL.h">
<Filter>GL\GLInterface</Filter>
</ClInclude>
<ClInclude Include="GL\GLInterface\EGLAndroid.h">
<Filter>GL\GLInterface</Filter>
</ClInclude>
<ClInclude Include="GL\GLInterfaceBase.h">
<Filter>GL</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp" />
@ -84,6 +93,15 @@
<ClCompile Include="Arm64Emitter.cpp" />
<ClCompile Include="ColorConv.cpp" />
<ClCompile Include="ColorConvNEON.cpp" />
<ClCompile Include="GL\GLInterface\EGL.cpp">
<Filter>GL\GLInterface</Filter>
</ClCompile>
<ClCompile Include="GL\GLInterface\EGLAndroid.cpp">
<Filter>GL\GLInterface</Filter>
</ClCompile>
<ClCompile Include="GL\GLInterface\GLInterface.cpp">
<Filter>GL\GLInterface</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="CMakeLists.txt" />
@ -92,5 +110,11 @@
<Filter Include="Crypto">
<UniqueIdentifier>{1b593f03-7b28-4707-9228-4981796f5589}</UniqueIdentifier>
</Filter>
<Filter Include="GL">
<UniqueIdentifier>{2f2ca112-9e26-499e-9cb9-38a78b4ac09d}</UniqueIdentifier>
</Filter>
<Filter Include="GL\GLInterface">
<UniqueIdentifier>{2c723cf4-75b6-406a-90c0-ebb7a13ba476}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>

View File

@ -116,6 +116,7 @@ bool cInterfaceEGL::Create(void *window_handle, bool core)
INFO_LOG(G3D, "Error: eglInitialize() failed\n");
return false;
}
INFO_LOG(G3D, "eglInitialize() succeeded\n");
/* Detection code */
EGLConfig config;
@ -124,7 +125,7 @@ bool cInterfaceEGL::Create(void *window_handle, bool core)
DetectMode();
// attributes for a visual in RGBA format with at least
// 8 bits per color
// 8 bits per color, 16 bits of depth and 8 bits of stencil.
int attribs[] = {
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_RED_SIZE, 8,
@ -139,8 +140,8 @@ bool cInterfaceEGL::Create(void *window_handle, bool core)
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
switch (s_opengl_mode)
{
switch (s_opengl_mode) {
case MODE_OPENGL:
attribs[1] = EGL_OPENGL_BIT;
ctx_attribs[0] = EGL_NONE;
@ -159,11 +160,13 @@ bool cInterfaceEGL::Create(void *window_handle, bool core)
break;
}
if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) {
if (!eglChooseConfig(egl_dpy, attribs, &config, 1, &num_configs)) {
INFO_LOG(G3D, "Error: couldn't get an EGL visual config\n");
exit(1);
}
INFO_LOG(G3D, "eglChooseConfig successful");
if (s_opengl_mode == MODE_OPENGL)
eglBindAPI(EGL_OPENGL_API);
else

View File

@ -25,4 +25,3 @@ EGLNativeWindowType cInterfaceEGLAndroid::InitializePlatform(EGLNativeWindowType
void cInterfaceEGLAndroid::ShutdownPlatform()
{
}

View File

@ -13,7 +13,7 @@ protected:
EGLDisplay OpenDisplay() override;
EGLNativeWindowType InitializePlatform(EGLNativeWindowType host_window, EGLConfig config) override;
void ShutdownPlatform() override;
void SetInternalResolution(int internalWidth, int internalHeight) override {
void OverrideBackbufferDimensions(int internalWidth, int internalHeight) override {
internalWidth_ = internalWidth;
internalHeight_ = internalHeight;
}

View File

@ -20,8 +20,7 @@
#error Platform doesnt have a GLInterface
#endif
cInterfaceBase* HostGL_CreateGLInterface()
{
cInterfaceBase* HostGL_CreateGLInterface(){
#ifdef ANDROID
return new cInterfaceEGLAndroid;
#elif defined(__APPLE__)

View File

@ -15,8 +15,7 @@ enum GLInterfaceMode {
MODE_OPENGLES3,
};
class cInterfaceBase
{
class cInterfaceBase {
protected:
// Window dimensions.
u32 s_backbuffer_width;
@ -38,6 +37,9 @@ public:
virtual void SwapInterval(int Interval) { }
virtual u32 GetBackBufferWidth() { return s_backbuffer_width; }
virtual u32 GetBackBufferHeight() { return s_backbuffer_height; }
virtual void OverrideBackbufferDimensions(int w, int h) = 0;
virtual void SetBackBufferDimensions(u32 W, u32 H) {s_backbuffer_width = W; s_backbuffer_height = H; }
virtual void Update() { }
virtual bool PeekMessages() { return false; }

View File

@ -11,7 +11,6 @@
#include <stdint.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <EGL/EGL.h>
#include <queue>
#include "base/basictypes.h"
@ -65,14 +64,29 @@ static int androidVersion;
static int deviceType;
// Should only be used for display detection during startup (for config defaults etc)
// This is the ACTUAL display size, not the hardware scaled display size.
static int display_dpi;
static int display_xres;
static int display_yres;
static int desiredBackbufferSizeX;
static int desiredBackbufferSizeY;
static jmethodID postCommand;
static jobject nativeActivity;
static volatile bool exitRenderLoop;
bool renderLoopRunning;
float dp_xscale = 1.0f;
float dp_yscale = 1.0f;
InputState input_state;
static bool renderer_inited = false;
static bool first_lost = true;
static std::string library_path;
// Android implementation of callbacks to the Java part of the app
void SystemToast(const char *text) {
lock_guard guard(frameCommandLock);
@ -149,18 +163,6 @@ int System_GetPropertyInt(SystemProperty prop) {
}
}
// Remember that all of these need initialization on init! The process
// may be reused when restarting the game. Globals are DANGEROUS.
float dp_xscale = 1.0f;
float dp_yscale = 1.0f;
InputState input_state;
static bool renderer_inited = false;
static bool first_lost = true;
static std::string library_path;
std::string GetJavaString(JNIEnv *env, jstring jstr) {
const char *str = env->GetStringUTFChars(jstr, 0);
std::string cpp_string = std::string(str);
@ -208,7 +210,7 @@ extern "C" jstring Java_org_ppsspp_ppsspp_NativeApp_queryConfig
}
extern "C" void Java_org_ppsspp_ppsspp_NativeApp_init
(JNIEnv *env, jclass, jstring jmodel, jint jdeviceType, jint jxres, jint jyres, jstring jlangRegion, jstring japkpath,
(JNIEnv *env, jclass, jstring jmodel, jint jdeviceType, jstring jlangRegion, jstring japkpath,
jstring jdataDir, jstring jexternalDir, jstring jlibraryDir, jstring jshortcutParam,
jstring jinstallID, jint jAndroidVersion) {
jniEnvUI = env;
@ -232,8 +234,6 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_init
right_joystick_y_async = 0;
hat_joystick_x_async = 0;
hat_joystick_y_async = 0;
display_xres = jxres;
display_yres = jyres;
std::string apkPath = GetJavaString(env, japkpath);
VFSRegister("", new ZipAssetReader(apkPath.c_str(), "assets/"));
@ -319,23 +319,6 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_shutdown(JNIEnv *, jclass) {
ILOG("NativeApp.shutdown() -- end");
}
extern "C" void Java_org_ppsspp_ppsspp_NativeApp_displayResize(JNIEnv *, jclass, jint w, jint h, jint dpi, jfloat refreshRate) {
ILOG("NativeApp.displayResize(%i x %i, dpi=%i, refresh=%0.2f)", w, h, dpi, refreshRate);
g_dpi = dpi;
g_dpi_scale = 240.0f / (float)g_dpi;
pixel_xres = w;
pixel_yres = h;
dp_xres = pixel_xres * g_dpi_scale;
dp_yres = pixel_yres * g_dpi_scale;
dp_xscale = (float)dp_xres / pixel_xres;
dp_yscale = (float)dp_yres / pixel_yres;
display_hz = refreshRate;
NativeResized();
}
extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayShutdown(JNIEnv *env, jobject obj) {
if (renderer_inited) {
renderer_inited = false;
@ -493,21 +476,116 @@ extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeActivity_exitEGLRenderLoop(
}
}
void correctRatio(int &sz_x, int &sz_y, float scale) {
float x = (float)sz_x;
float y = (float)sz_y;
float ratio = x / y;
ILOG("CorrectRatio: Considering size: %0.2f/%0.2f=%0.2f for scale %f", x, y, ratio, scale);
float targetRatio;
// Try to get the longest dimension to match scale*PSP resolution.
if (x >= y) {
targetRatio = 480.0f / 272.0f;
x = 480.f * scale;
y = 272.f * scale;
} else {
targetRatio = 272.0f / 480.0f;
x = 272.0f * scale;
y = 480.0f * scale;
}
float correction = targetRatio / ratio;
ILOG("Target ratio: %0.2f ratio: %0.2f correction: %0.2f", targetRatio, ratio, correction);
if (ratio < targetRatio) {
y *= correction;
} else {
x /= correction;
}
sz_x = x;
sz_y = y;
ILOG("Corrected ratio: %dx%d", sz_x, sz_y);
}
void getDesiredBackbufferSize(int &sz_x, int &sz_y) {
sz_x = display_xres;
sz_y = display_yres;
std::string config = NativeQueryConfig("hwScale");
int scale;
if (1 == sscanf(config.c_str(), "%d", &scale) && scale > 0) {
correctRatio(sz_x, sz_y, scale);
} else {
sz_x = 0;
sz_y = 0;
}
}
extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeApp_setDisplayParameters(JNIEnv *, jclass, jint xres, jint yres, jint dpi, jfloat refreshRate) {
ILOG("NativeApp.setDisplayParameters(%d x %d, dpi=%d, refresh=%0.2f)", xres, yres, dpi, refreshRate);
display_xres = xres;
display_yres = yres;
display_dpi = dpi;
display_hz = refreshRate;
}
extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeApp_backbufferResize(JNIEnv *, jclass, jint bufw, jint bufh) {
ILOG("NativeApp.backbufferResize(%d x %d)", bufw, bufh);
// pixel_*res is the backbuffer resolution.
pixel_xres = bufw;
pixel_yres = bufh;
g_dpi = (int)display_dpi;
g_dpi_scale = 240.0f / (float)g_dpi;
dp_xres = display_xres * g_dpi_scale;
dp_yres = display_yres * g_dpi_scale;
// Touch scaling is from display pixels to dp pixels.
dp_xscale = (float)dp_xres / (float)display_xres;
dp_yscale = (float)dp_yres / (float)display_yres;
pixel_in_dps = (float)pixel_xres / dp_xres;
ILOG("dp_xscale=%f dp_yscale=%f", dp_xscale, dp_yscale);
ILOG("dp_xres=%d dp_yres=%d", dp_xres, dp_yres);
ILOG("pixel_xres=%d pixel_yres=%d", pixel_xres, pixel_yres);
ILOG("g_dpi=%d g_dpi_scale=%f", g_dpi, g_dpi_scale);
NativeResized();
}
extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeApp_computeDesiredBackbufferDimensions() {
getDesiredBackbufferSize(desiredBackbufferSizeX, desiredBackbufferSizeY);
}
extern "C" jint JNICALL Java_org_ppsspp_ppsspp_NativeApp_getDesiredBackbufferWidth(JNIEnv *, jclass) {
return desiredBackbufferSizeX;
}
extern "C" jint JNICALL Java_org_ppsspp_ppsspp_NativeApp_getDesiredBackbufferHeight(JNIEnv *, jclass) {
return desiredBackbufferSizeY;
}
extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(JNIEnv *env, jobject obj, jobject _surf) {
ANativeWindow *wnd = ANativeWindow_fromSurface(env, _surf);
WLOG("runEGLRenderLoop");
WLOG("runEGLRenderLoop. display_xres=%d display_yres=%d", display_xres, display_yres);
if (wnd == nullptr) {
ELOG("Error: Surface is null.");
return;
}
cInterfaceBase *gl = HostGL_CreateGLInterface();
if (!gl) {
ELOG("ERROR: Failed to create GL interface");
return;
}
ILOG("EGL interface created. Desired backbuffer size: %dx%d", desiredBackbufferSizeX, desiredBackbufferSizeY);
// Apparently we still have to set this through Java through setFixedSize on the bufferHolder for it to take effect...
gl->SetBackBufferDimensions(desiredBackbufferSizeX, desiredBackbufferSizeY);
gl->SetMode(MODE_DETECT);
gl->Create(wnd);
gl->MakeCurrent();
@ -566,11 +644,14 @@ extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(J
}
}
// Restore lost device objects. TODO: This feels like the wrong place for this.
NativeDeviceLost();
ILOG("NativeDeviceLost completed.");
NativeShutdownGraphics();
renderer_inited = false;
gl->ClearCurrent();
delete gl;
ANativeWindow_release(wnd);

View File

@ -8,7 +8,6 @@ import java.util.Locale;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.UiModeManager;
import android.content.Context;
@ -16,11 +15,9 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ConfigurationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.media.AudioManager;
import android.net.Uri;
@ -29,6 +26,7 @@ import android.os.Bundle;
import android.os.Environment;
import android.os.Vibrator;
import android.text.InputType;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
@ -215,10 +213,8 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback {
String model = Build.MANUFACTURER + ":" + Build.MODEL;
String languageRegion = Locale.getDefault().getLanguage() + "_" + Locale.getDefault().getCountry();
Point displaySize = new Point();
GetScreenSize(displaySize);
NativeApp.audioConfig(optimalFramesPerBuffer, optimalSampleRate);
NativeApp.init(model, deviceType, displaySize.x, displaySize.y, languageRegion, apkFilePath, dataDir, externalStorageDir, libraryDir, shortcutParam, installID, Build.VERSION.SDK_INT);
NativeApp.init(model, deviceType, languageRegion, apkFilePath, dataDir, externalStorageDir, libraryDir, shortcutParam, installID, Build.VERSION.SDK_INT);
NativeApp.sendMessage("cacheDir", getCacheDir().getAbsolutePath());
@ -291,12 +287,6 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback {
}
}
// Override this to scale the backbuffer (use the Android hardware scaler)
public void getDesiredBackbufferSize(Point sz) {
sz.x = 0;
sz.y = 0;
}
private Runnable mEmulationRunner = new Runnable()
{
@Override
@ -331,6 +321,15 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback {
registerCallbacks();
installID = Installation.id(this);
DisplayMetrics metrics = new DisplayMetrics();
Display display = getWindowManager().getDefaultDisplay();
display.getMetrics(metrics);
float refreshRate = display.getRefreshRate();
Point outSize = new Point();
GetScreenSize(outSize);
NativeApp.setDisplayParameters(outSize.x, outSize.y, metrics.densityDpi, refreshRate);
if (!initialized) {
Initialize();
initialized = true;
@ -349,19 +348,6 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback {
gainAudioFocus(this.audioManager, this.audioFocusChangeListener);
NativeApp.audioInit();
mSurfaceView = new NativeSurfaceView(this);
mSurfaceView.getHolder().addCallback(this);
Point sz = new Point();
getDesiredBackbufferSize(sz);
if (sz.x > 0) {
Log.i(TAG, "Requesting fixed size buffer: " + sz.x + "x" + sz.y);
// Auto-calculates new DPI and forwards to the correct call on mGLSurfaceView.getHolder()
mSurfaceView.setFixedSize(sz.x, sz.y);
}
setContentView(mSurfaceView);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
updateSystemUiVisibility();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
@ -369,6 +355,16 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback {
}
}
NativeApp.computeDesiredBackbufferDimensions();
int bbW = NativeApp.getDesiredBackbufferWidth();
int bbH = NativeApp.getDesiredBackbufferHeight();
mSurfaceView = new NativeSurfaceView(this, bbW, bbH);
mSurfaceView.getHolder().addCallback(this);
Log.i(TAG, "setcontentview before");
setContentView(mSurfaceView);
Log.i(TAG, "setcontentview after");
mRenderLoopThread = new Thread(mEmulationRunner);
mRenderLoopThread.start();
}
@ -383,6 +379,7 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback {
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
Log.w(TAG, "Surface changed. Resolution: " + width + "x" + height);
NativeApp.backbufferResize(width, height);
mSurface = holder.getSurface();
if (mRenderLoopThread == null || !mRenderLoopThread.isAlive()) {
mRenderLoopThread = new Thread(mEmulationRunner);
@ -440,18 +437,6 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback {
unregisterCallbacks();
}
private boolean detectOpenGLES20() {
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
ConfigurationInfo info = am.getDeviceConfigurationInfo();
return info.reqGlEsVersion >= 0x20000;
}
private boolean detectOpenGLES30() {
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
ConfigurationInfo info = am.getDeviceConfigurationInfo();
return info.reqGlEsVersion >= 0x30000;
}
@Override
protected void onPause() {
super.onPause();
@ -489,12 +474,6 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
updateSystemUiVisibility();
}
Point sz = new Point();
getDesiredBackbufferSize(sz);
if (sz.x > 0) {
mSurfaceView.getHolder().setFixedSize(sz.x/2, sz.y/2);
}
}
//keep this static so we can call this even if we don't

View File

@ -13,13 +13,19 @@ public class NativeApp {
public final static int DEVICE_TYPE_TV = 1;
public final static int DEVICE_TYPE_DESKTOP = 2;
public static native void init(String model, int deviceType, int xres, int yres, String languageRegion, String apkPath, String dataDir, String externalDir, String libraryDir, String shortcutParam, String installID, int androidVersion);
public static native void init(String model, int deviceType, String languageRegion, String apkPath, String dataDir, String externalDir, String libraryDir, String shortcutParam, String installID, int androidVersion);
public static native void audioInit();
public static native void audioShutdown();
public static native void audioConfig(int optimalFramesPerBuffer, int optimalSampleRate);
public static native void displayResize(int width, int height, int scaled_dpi, float refreshRate);
public static native void computeDesiredBackbufferDimensions();
public static native int getDesiredBackbufferWidth();
public static native int getDesiredBackbufferHeight();
public static native void setDisplayParameters(int display_xres, int display_yres, int dpi, float refreshRate);
public static native void backbufferResize(int bufferWidth, int bufferHeight);
public static native boolean isLandscape();
public static native boolean isAtTopLevel();

View File

@ -1,66 +1,48 @@
package org.ppsspp.ppsspp;
// Touch- and sensor-enabled GLSurfaceView.
// Touch- and sensor-enabled SurfaceView.
// Supports simple multitouch and pressure.
// DPI scaling is handled by the native code.
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.graphics.Point;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.opengl.GLSurfaceView;
import android.os.Build;
import android.os.Handler;
import android.util.DisplayMetrics;
// import android.os.Build;
// import android.util.Log;
import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;
import android.view.SurfaceView;
import com.bda.controller.*;
public class NativeSurfaceView extends SurfaceView implements SensorEventListener, ControllerListener {
private static String TAG = "NativeGLView";
private static String TAG = "NativeSurfaceView";
private SensorManager mSensorManager;
private Sensor mAccelerometer;
private NativeActivity mActivity;
// Moga controller
private Controller mController = null;
private boolean isMogaPro = false;
private int dpi;
private float refreshRate;
private double dpi_scale_x;
private double dpi_scale_y;
int last_width, last_height;
public int fixedW = 0;
public int fixedH = 0;
public NativeSurfaceView(NativeActivity activity) {
public NativeSurfaceView(NativeActivity activity, int fixedW, int fixedH) {
super(activity);
DisplayMetrics metrics = new DisplayMetrics();
Display display = activity.getWindowManager().getDefaultDisplay();
display.getMetrics(metrics);
dpi = metrics.densityDpi;
refreshRate = display.getRefreshRate();
mActivity = activity;
Log.i(TAG, "NativeSurfaceView");
mSensorManager = (SensorManager)activity.getSystemService(Activity.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mController = Controller.getInstance(activity);
onResize(display.getWidth(), display.getHeight());
// Maybe we need to use this?
if (fixedW != 0 && fixedH != 0) {
Log.i(TAG, "Setting surface holder to use a fixed size of " + fixedW + "x" + fixedH + " pixels");
this.getHolder().setFixedSize(fixedW, fixedH);
}
try {
MogaHack.init(mController, activity);
@ -71,37 +53,17 @@ public class NativeSurfaceView extends SurfaceView implements SensorEventListene
}
}
void onResize(int width, int height) {
Point sz = new Point();
mActivity.GetScreenSize(sz);
double actualW = sz.x;
double actualH = sz.y;
dpi_scale_x = (width / actualW);
dpi_scale_y = (height / actualH);
Log.i(TAG, "onSurfaceChanged: " + dpi_scale_x + "x" + dpi_scale_y + " (width=" + width + ", actualW=" + actualW);
int scaled_dpi = (int)(dpi * dpi_scale_x);
NativeApp.displayResize(width, height, scaled_dpi, refreshRate);
last_width = width;
last_height = height;
}
void setFixedSize(int w, int h) {
fixedW = w;
fixedH = h;
}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
private int getToolType(final MotionEvent ev, int pointer) {
return ev.getToolType(pointer);
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(final MotionEvent ev) {
boolean canReadToolType = Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
int numTouchesHandled = 0;
float scaleX = (float)this.dpi_scale_x;
float scaleY = (float)this.dpi_scale_y;
for (int i = 0; i < ev.getPointerCount(); i++) {
int pid = ev.getPointerId(i);
int code = 0;
@ -133,7 +95,7 @@ public class NativeSurfaceView extends SurfaceView implements SensorEventListene
code |= tool << 10; // We use the Android tool type codes
}
// Can't use || due to short circuit evaluation
numTouchesHandled += NativeApp.touch(scaleX * ev.getX(i), scaleY * ev.getY(i), code, pid) ? 1 : 0;
numTouchesHandled += NativeApp.touch(ev.getX(i), ev.getY(i), code, pid) ? 1 : 0;
}
}
return numTouchesHandled > 0;

View File

@ -1,7 +1,6 @@
package org.ppsspp.ppsspp;
import android.app.AlertDialog;
import android.graphics.Point;
import android.os.Build;
import android.os.Bundle;
import android.os.Looper;
@ -15,7 +14,8 @@ public class PpssppActivity extends NativeActivity {
private static boolean m_hasUnsupportedABI = false;
private static boolean m_hasNoNativeBinary = false;
static {
@SuppressWarnings("deprecation")
static void CheckABIAndLoadLibrary() {
if (Build.CPU_ABI.equals("armeabi")) {
m_hasUnsupportedABI = true;
} else {
@ -28,6 +28,10 @@ public class PpssppActivity extends NativeActivity {
}
}
static {
CheckABIAndLoadLibrary();
}
public PpssppActivity() {
super();
}
@ -36,6 +40,7 @@ public class PpssppActivity extends NativeActivity {
public void onCreate(Bundle savedInstanceState) {
if (m_hasUnsupportedABI || m_hasNoNativeBinary) {
new Thread() {
@SuppressWarnings("deprecation")
@Override
public void run() {
Looper.prepare();
@ -68,55 +73,6 @@ public class PpssppActivity extends NativeActivity {
super.onCreate(savedInstanceState);
}
private void correctRatio(Point sz, float scale) {
float x = sz.x;
float y = sz.y;
float ratio = x / y;
// Log.i(TAG, "Considering size: " + sz.x + "x" + sz.y + "=" + ratio);
float targetRatio;
if (x >= y) {
targetRatio = 480.0f / 272.0f;
x = 480.f * scale;
y = 272.f * scale;
} else {
targetRatio = 272.0f / 480.0f;
x = 272.0f * scale;
y = 480.0f * scale;
}
float correction = targetRatio / ratio;
// Log.i(TAG, "Target ratio: " + targetRatio + " ratio: " + ratio + " correction: " + correction);
if (ratio < targetRatio) {
y *= correction;
} else {
x /= correction;
}
sz.x = (int)x;
sz.y = (int)y;
// Log.i(TAG, "Corrected ratio: " + sz.x + "x" + sz.y);
}
@Override
public void getDesiredBackbufferSize(Point sz) {
GetScreenSize(sz);
String config = NativeApp.queryConfig("hwScale");
int scale;
try {
scale = Integer.parseInt(config);
if (scale == 0) {
sz.x = 0;
sz.y = 0;
return;
}
}
catch (NumberFormatException e) {
sz.x = 0;
sz.y = 0;
return;
}
correctRatio(sz, scale);
}
// called by the C++ code through JNI. Dispatch anything we can't directly handle
// on the gfx thread to the UI thread.
public void postCommand(String command, String parameter) {

View File

@ -97,7 +97,7 @@ Bounds UIContext::GetScissorBounds() {
void UIContext::ActivateTopScissor() {
if (scissorStack_.size()) {
const Bounds &bounds = scissorStack_.back();
float scale = 1.0f / g_dpi_scale;
float scale = pixel_in_dps;
int x = scale * bounds.x;
int y = scale * bounds.y;
int w = scale * bounds.w;