You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#lockdown Nick.Penwarden
#rb None
==========================
MAJOR FEATURES + CHANGES
==========================
Change 3156770 on 2016/10/10 by Allan.Bentham
Fix VULKAN_ENABLE_API_DUMP build on android.
Change 3157838 on 2016/10/11 by Allan.Bentham
Fix Vulkan API tracing on android.
Change 3170713 on 2016/10/21 by Steve.Cano
Adding the "Optional Mobile Features BP Library" plugin to explose Blueprint functions for Sound Volume, Battery level, system temperature (only available on android), and Headphones being plugged in
#jira UE-30896
#android
#ios
#ue4
Change 3171064 on 2016/10/21 by Steve.Cano
Plugins to provide a common interface and Android implemenation for providing access to GPS / Location data from Blueprints
#ue4
#android
#jira UE-35917
Change 3171065 on 2016/10/21 by Steve.Cano
IOS implementation of LocationServices plugin to provide access to location data in Blueprints
#ue4
#ios
#jira UE-35917
Change 3181802 on 2016/11/01 by Steve.Cano
Fix an issue introduced in CL 3170713 - Adding new config section to RequiredSections list so that we can generate projects successfully.
#jira UE-30896
#ios
Change 3181807 on 2016/11/01 by Steve.Cano
Make sure to clear out references to our eglSurface when we destroy it, else we will try to set our context with an invalid surface.
#jira UE-35004
#android
#ue4
Change 3184827 on 2016/11/03 by Allan.Bentham
Do not HDR32 encode for views without view family.
TranslucentAlphaOnly blend mode now works with encoding.
#jira UE-37951
Change 3186684 on 2016/11/04 by Jack.Porter
Merging //UE4/Dev-Main to Dev-Mobile (//UE4/Dev-Mobile)
Change 3188693 on 2016/11/07 by Chris.Babcock
Corrections to memory stats for Android
#jira WEX-3760
#ue4
#android
Change 3191538 on 2016/11/09 by Allan.Bentham
Mobile tonemapper can use CVarTonemapperOverride
Change 3192575 on 2016/11/09 by Chris.Babcock
Support placing UE4Game files in ExternalFilesDir for automatic cleanup on uninstall for distribution packages
#jira UEPLAT-1422
#ue4
#android
Change 3196231 on 2016/11/13 by Jack.Porter
Merging //UE4/Dev-Main to Dev-Mobile (//UE4/Dev-Mobile)
Change 3196538 on 2016/11/14 by Jack.Porter
Fix issue where lighting would not build for the first editor session of projects defaulting to MobileHDR=false as HardwareTargetingModule didn't set cvars
#jira UE-38507
Change 3198068 on 2016/11/15 by Dmitriy.Dyomin
Fixed android console command sender to work with ADB version 1.0.36
#jira UE-35171
Change 3200230 on 2016/11/16 by Jack.Porter
Remove mosaic resolution limitation on ES3 devices
#jira WEX-3119
Change 3201251 on 2016/11/16 by Chris.Babcock
Fix Android compile error
Change 3203542 on 2016/11/18 by Jack.Porter
Merging //UE4/Dev-Main to Dev-Mobile (//UE4/Dev-Mobile)
Change 3205598 on 2016/11/21 by Dmitriy.Dyomin
Fixed: Missing selection outline in editor ES2 preview
#jira UE-6458
Change 3205622 on 2016/11/21 by Dmitriy.Dyomin
Fix ES2 build error from CL# 3205598
Change 3207232 on 2016/11/22 by Dmitriy.Dyomin
ES2 GLSL generated shader simplifications
Change 3208608 on 2016/11/23 by Dmitriy.Dyomin
Fixed: Landscape Grasstype warning causes log spam when landscape is streamed in or out
#jira UE-38694
Change 3209135 on 2016/11/23 by Alicia.Cano
Packaging for iOS fails due to several invalid object type errors
#jira UE-38431
#ios
Change 3209822 on 2016/11/24 by Jack.Porter
IWYU changes for LocationServicesBPLibrary
Change 3209824 on 2016/11/24 by Jack.Porter
Merging //UE4/Dev-Main to Dev-Mobile (//UE4/Dev-Mobile)
Change 3210264 on 2016/11/25 by Jack.Porter
Fix unicode compile issue on Korean windows
Change 3210268 on 2016/11/25 by Jack.Porter
IWYU and unicode fixes to Dev-Mobile
Change 3211800 on 2016/11/28 by Allan.Bentham
Create and set PrimitiveSceneProxy->PrimitiveSceneInfo before SetTransform render thread command is enqueued. Avoids race condition with FPrimitiveSceneInfo's constructor which can occur on out-of-order CPUs.
Change 3212621 on 2016/11/28 by Jack.Porter
More IWYU fixes.
Change 3213080 on 2016/11/29 by Allan.Bentham
enable UseSingleSampleShadowFromStationaryLights on mobile.
PR #2990: Fixes single sample shadows for mobile. (Contributed by kallehamalainen)
Change 3213164 on 2016/11/29 by Jack.Porter
Win32 IWYU fix
Change 3213932 on 2016/11/29 by Chris.Babcock
Fix handling of ETC2 filtering by Google Play Store (if only ETC2, require ES3.0+ but don't use texture filtering in manifest)
#jira UE-39120
#ue4
#android
Change 3214563 on 2016/11/29 by Dmitriy.Dyomin
Disable dynamic buffer discarding on Adreno330 (was casuing 10ms stalls on slate buffers update)
Change 3214571 on 2016/11/29 by Dmitriy.Dyomin
Custom stencil on Mobile
#jira UEMOB-183
Change 3214641 on 2016/11/30 by Dmitriy.Dyomin
Disable distance culling when rendering image for world composition
#jira UE-37754
Change 3214656 on 2016/11/30 by Jack.Porter
Merging //UE4/Dev-Main to Dev-Mobile (//UE4/Dev-Mobile)
Change 3218479 on 2016/12/01 by Jack.Porter
Fix for Vulkan build error when using AutoSDK
Change 3218596 on 2016/12/02 by Dmitriy.Dyomin
Fixed: Android split screen multiplayer does not function or render correctly
#jira UE-35204
Change 3218874 on 2016/12/02 by Allan.Bentham
Fix CSM shadow bug when ES3.1 + mobileHDR == false.
Fix inverted culling when rendering shadow depths with mobilehdr == false
#jira UE-39111
Change 3220911 on 2016/12/04 by Jack.Porter
Fixed landscape duplicated GUID detection and crash when one of the landscapes is in a hidden streaming level
Change 3220935 on 2016/12/04 by Jack.Porter
Merging //UE4/Dev-Main to Dev-Mobile (//UE4/Dev-Mobile)
Change 3222831 on 2016/12/05 by Dmitriy.Dyomin
Added support for MGD and Andreno profilers
#jira UEMOB-184
Change 3222843 on 2016/12/05 by Jack.Porter
Fixed bug caused by CL 3196538 causing r.MobileHDR to toggle and crash when opening render settings
#jira UE-38507
Change 3222934 on 2016/12/06 by Jack.Porter
Android graphics debugger text changes
Change 3223042 on 2016/12/06 by Dmitriy.Dyomin
Fixed: missing GPU particles in LDR mode on device
#jira UE-39363
Change 3223043 on 2016/12/06 by Jack.Porter
Fixed logspam warnings from TcpMessaging launching on Android
#jira UE-37895
Change 3223046 on 2016/12/06 by Allan.Bentham
Move ES3.1 preview mode out of experimental.
Add per device quality level preview to ES3.1 preview sub menu when project settings allow.
#jira UEMOB-178
Change 3223113 on 2016/12/06 by Allan.Bentham
changed MOBILE_EMULATION define for METAL_PROFILE on mac. fixes issues with editor primitive rendering with ES3.1 feature level preview.
added -featureleveles2/31 commandline support to metalrhi.
Change 3223117 on 2016/12/06 by Allan.Bentham
Initialise FPrimitiveSceneInfo::CachedReflectionCaptureProxies
Change 3223131 on 2016/12/06 by Allan.Bentham
Fix translucency rendering when mobilehdr == false. (Disable mod shadows when mobilehdr == false.)
#jira UE-38343
Change 3223162 on 2016/12/06 by Jack.Porter
Disallow Absolute World Position with "excluding shader offset" on ES2
#jra UE-25555
Change 3223204 on 2016/12/06 by Jack.Porter
Fix for unable to save levels when landscape components with tessellation moved to another level
#jira UE-39372
Change 3223677 on 2016/12/06 by Chris.Babcock
Fix tabs
Change 3224139 on 2016/12/06 by Chris.Babcock
Support modification of build.xml and add post import additions to GameActivity
#jira UE-31372
#PR #2440
#ue4
#android
Change 3224152 on 2016/12/06 by Chris.Babcock
Add support for MadCatz C.T.R.L.R Android controller models
#ue4
#android
Change 3224162 on 2016/12/06 by Chris.Babcock
Driver bug fix and using separate context for MediaPlayer14 (contributed by BrianHarris)
#jira UE-35825
#PR #2787
#ue4
#android
Change 3224581 on 2016/12/07 by Dmitriy.Dyomin
Fixed black screen regression on iOS OpenGL
Also now reporting shader compiler errors in iOS
Change 3224589 on 2016/12/07 by Allan.Bentham
Increase mobile renderer's maximum CSM cascade limit to 4 and introduce max shadow cascade cvar for mobile which defaults to 2 retaining existing behaviour.
#jira UEMOB-187
Change 3224774 on 2016/12/07 by Jack.Porter
Added flags for mobile shader permutation reduction
Renamed mobile lighting policies to better describe them
Set flags to remove policies not used by SunTemple - saves 22MB package size on Android
#jira: UEMOB-179
Change 3224782 on 2016/12/07 by Allan.Bentham
Add project option to set maximum supported CSM cascades to mobile renderer.
#jira UEMOB-187
Change 3224943 on 2016/12/07 by Dmitriy.Dyomin
Metal iOS will use sRGB textures
#jira UEMOB-189
Change 3225098 on 2016/12/07 by Dmitriy.Dyomin
fix for compile error from 3224943
Change 3225188 on 2016/12/07 by Chris.Babcock
Fix #includes in deferred Android OpenGL
#jira UE-39440
#ue4
#android
Change 3226402 on 2016/12/07 by Dmitriy.Dyomin
Fixed: wrong condition for r8 srgb on mac
#jira UE-39471
Change 3226485 on 2016/12/08 by Dmitriy.Dyomin
Fixed: Rendering Artifacts and invisible objects in Fortnite
regression from nobile custom stencil changes
#jira UE-39452, UE-39455
Change 3226637 on 2016/12/08 by Dmitriy.Dyomin
Fixed: Odin Ensure Texture passed to ClearDepthStencil is not what is currently set as RenderTarget
#jira UE-39482
Change 3226922 on 2016/12/08 by Jack.Porter
Merging //UE4/Dev-Main to Dev-Mobile (//UE4/Dev-Mobile)
Change 3227353 on 2016/12/08 by Chris.Babcock
Remove CopyVisualizers batch call again
Change 3228013 on 2016/12/08 By Chris.Babcock
Merging //UE4/Dev-Main to Dev-Mobile (//UE4/Dev-Mobile)
[CL 3228374 by Jack Porter in Main branch]
644 lines
18 KiB
C++
644 lines
18 KiB
C++
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
|
|
|
|
#if PLATFORM_ANDROIDESDEFERRED
|
|
/*=============================================================================
|
|
AndroidESDeferredOpenGL.cpp: Manual loading of OpenGL functions from DLL.
|
|
=============================================================================*/
|
|
|
|
#include "OpenGLDrvPrivate.h"
|
|
|
|
#include "AndroidApplication.h"
|
|
#include "AndroidOpenGLPrivate.h"
|
|
#include <dlfcn.h>
|
|
#include <android/log.h>
|
|
#include <android/native_window_jni.h>
|
|
|
|
#include "Misc/ScopeLock.h"
|
|
|
|
|
|
#define LOG_TAG "UE4"
|
|
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
|
|
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
|
|
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// OpenGL function pointers
|
|
|
|
#define DEFINE_GL_ENTRYPOINTS(Type,Func) Type Func = NULL;
|
|
ENUM_GL_ENTRYPOINTS_CORE(DEFINE_GL_ENTRYPOINTS) \
|
|
ENUM_GL_ENTRYPOINTS_MANUAL(DEFINE_GL_ENTRYPOINTS) \
|
|
ENUM_GL_ENTRYPOINTS_OPTIONAL(DEFINE_GL_ENTRYPOINTS)
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool FAndroidESDeferredOpenGL::bSupportsBindlessTexture = false;
|
|
bool FAndroidESDeferredOpenGL::bSupportsMobileMultiView = false;
|
|
|
|
void FAndroidESDeferredOpenGL::ProcessExtensions(const FString& ExtensionsString)
|
|
{
|
|
FOpenGLESDeferred::ProcessExtensions(ExtensionsString);
|
|
|
|
bSupportsBindlessTexture = ExtensionsString.Contains(TEXT("GL_NV_bindless_texture"));
|
|
|
|
// Nexus 9 running Android < 6.0 runs slow with NvTimerQuery so disable it
|
|
if (FAndroidMisc::GetDeviceModel() == FString(TEXT("Nexus 9")))
|
|
{
|
|
TArray<FString> VersionParts;
|
|
FAndroidMisc::GetAndroidVersion().ParseIntoArray(VersionParts, TEXT("."), true);
|
|
if (VersionParts.Num() > 0 && FCString::Atoi(*VersionParts[0]) < 6)
|
|
{
|
|
UE_LOG(LogRHI, Log, TEXT("Disabling support for NvTimerQuery on Nexus 9 before Android 6.0"));
|
|
bSupportsNvTimerQuery = false;
|
|
}
|
|
}
|
|
|
|
// Mobile multi-view setup
|
|
const bool bMultiViewSupport = ExtensionsString.Contains(TEXT("GL_OVR_multiview"));
|
|
const bool bMultiView2Support = ExtensionsString.Contains(TEXT("GL_OVR_multiview2"));
|
|
const bool bMultiViewMultiSampleSupport = ExtensionsString.Contains(TEXT("GL_OVR_multiview_multisampled_render_to_texture"));
|
|
if (bMultiViewSupport && bMultiView2Support && bMultiViewMultiSampleSupport)
|
|
{
|
|
// function pointers are set in Init as part of ENUM_GL_ENTRYPOINTS_OPTIONAL
|
|
bSupportsMobileMultiView = (glFramebufferTextureMultiviewOVR != NULL) && (glFramebufferTextureMultisampleMultiviewOVR != NULL);
|
|
|
|
// Just because the driver declares multi-view support and hands us valid function pointers doesn't actually guarantee the feature works...
|
|
if (bSupportsMobileMultiView)
|
|
{
|
|
// Disable for now, not supported with deferred path yet
|
|
bSupportsMobileMultiView = false;
|
|
//UE_LOG(LogRHI, Log, TEXT("Device supports mobile multi-view."));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// OpenGL platform functions
|
|
|
|
class FScopeContext
|
|
{
|
|
public:
|
|
FScopeContext(FPlatformOpenGLContext* PlatformContext)
|
|
{
|
|
check(PlatformContext);
|
|
LastContext = eglGetCurrentContext();
|
|
LastSurface = eglGetCurrentSurface(EGL_DRAW);
|
|
bSameContextAndSurface = (LastContext == PlatformContext->eglContext) && (LastSurface == PlatformContext->eglSurface);
|
|
if (!bSameContextAndSurface)
|
|
{
|
|
eglMakeCurrent(AndroidEGL::GetInstance()->GetDisplay(), PlatformContext->eglSurface, PlatformContext->eglSurface, PlatformContext->eglContext);
|
|
}
|
|
}
|
|
|
|
~FScopeContext( void )
|
|
{
|
|
if (!bSameContextAndSurface)
|
|
{
|
|
if (LastContext)
|
|
{
|
|
eglMakeCurrent(AndroidEGL::GetInstance()->GetDisplay(), LastSurface, LastSurface, LastContext);
|
|
}
|
|
else
|
|
{
|
|
eglMakeCurrent(AndroidEGL::GetInstance()->GetDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
|
}
|
|
}
|
|
}
|
|
|
|
private:
|
|
EGLContext LastContext;
|
|
EGLSurface LastSurface;
|
|
bool bSameContextAndSurface;
|
|
};
|
|
|
|
/**
|
|
* Enable/Disable debug context from the commandline
|
|
*/
|
|
static bool PlatformOpenGLDebugCtx()
|
|
{
|
|
#if UE_BUILD_DEBUG
|
|
return ! FParse::Param(FCommandLine::Get(),TEXT("openglNoDebug"));
|
|
#else
|
|
return FParse::Param(FCommandLine::Get(),TEXT("openglDebug"));;
|
|
#endif
|
|
}
|
|
|
|
|
|
struct FPlatformOpenGLDevice
|
|
{
|
|
void SetCurrentSharedContext();
|
|
void SetCurrentRenderingContext();
|
|
void SetCurrentNULLContext();
|
|
|
|
FPlatformOpenGLDevice();
|
|
~FPlatformOpenGLDevice();
|
|
void Init();
|
|
void LoadEXT();
|
|
void Terminate();
|
|
void ReInit();
|
|
};
|
|
|
|
FPlatformOpenGLDevice::FPlatformOpenGLDevice()
|
|
{
|
|
}
|
|
|
|
FPlatformOpenGLDevice::~FPlatformOpenGLDevice()
|
|
{
|
|
AndroidEGL::GetInstance()->DestroyBackBuffer();
|
|
AndroidEGL::GetInstance()->Terminate();
|
|
}
|
|
|
|
void FPlatformOpenGLDevice::Init()
|
|
{
|
|
UE_LOG( LogRHI, Warning, TEXT("Entering FPlatformOpenGLDevice::Init"));
|
|
extern void InitDebugContext();
|
|
|
|
AndroidEGL::GetInstance()->InitSurface(false, true);
|
|
AndroidEGL::GetInstance()->SetSingleThreadRenderingContext();
|
|
|
|
// Initialize all of the entry points we have to query manually
|
|
#define GET_GL_ENTRYPOINTS(Type,Func) Func = (Type)eglGetProcAddress(#Func);
|
|
ENUM_GL_ENTRYPOINTS_CORE(GET_GL_ENTRYPOINTS);
|
|
ENUM_GL_ENTRYPOINTS_MANUAL(GET_GL_ENTRYPOINTS);
|
|
ENUM_GL_ENTRYPOINTS_OPTIONAL(GET_GL_ENTRYPOINTS);
|
|
|
|
// Check that all of the required entry points have been initialized
|
|
bool bFoundAllEntryPoints = true;
|
|
#define CHECK_GL_ENTRYPOINTS(Type,Func) if (Func == NULL) { bFoundAllEntryPoints = false; UE_LOG(LogRHI, Warning, TEXT("Failed to find entry point for %s"), TEXT(#Func)); }
|
|
ENUM_GL_ENTRYPOINTS_CORE(CHECK_GL_ENTRYPOINTS);
|
|
|
|
checkf(bFoundAllEntryPoints, TEXT("Failed to find all required OpenGL entry points."));
|
|
|
|
ENUM_GL_ENTRYPOINTS_MANUAL(CHECK_GL_ENTRYPOINTS);
|
|
ENUM_GL_ENTRYPOINTS_OPTIONAL(CHECK_GL_ENTRYPOINTS);
|
|
|
|
const FString ExtensionsString = ANSI_TO_TCHAR((const ANSICHAR*)glGetString(GL_EXTENSIONS));
|
|
|
|
// If EXT_disjoint_timer_query wasn't found, NV_timer_query might be available
|
|
{
|
|
// These functions get exported under different names by different extensions
|
|
// Can't just check for NULL, because Android returns and unimplemented function catch
|
|
|
|
if ( !ExtensionsString.Contains(TEXT("GL_EXT_disjoint_timer_query")) && ExtensionsString.Contains(TEXT("GL_NV_timer_query")))
|
|
{
|
|
glQueryCounterEXT = (PFNGLQUERYCOUNTEREXTPROC)eglGetProcAddress("glQueryCounterNV");
|
|
glGetQueryObjectui64vEXT = (PFNGLGETQUERYOBJECTUI64VEXTPROC)eglGetProcAddress("glGetQueryObjectui64vNV");
|
|
}
|
|
}
|
|
|
|
const bool bAdvancedFeatures = FOpenGL::SupportsAdvancedFeatures();
|
|
|
|
// devices that have ES2.0 only might support some ES3.x core functionality with extensions
|
|
if(!bAdvancedFeatures)
|
|
{
|
|
if(ExtensionsString.Contains(TEXT("GL_EXT_occlusion_query_boolean")))
|
|
{
|
|
glGenQueries = (PFNGLGENQUERIESPROC(eglGetProcAddress("glGenQueriesEXT")));
|
|
glDeleteQueries = (PFNGLDELETEQUERIESPROC(eglGetProcAddress("glDeleteQueriesEXT")));
|
|
glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)((void*)eglGetProcAddress("glGetQueryObjectuivEXT"));
|
|
|
|
}
|
|
|
|
// Android doesn't setup formats completely compatible with glTexStorage in ES2 mode
|
|
glTexStorage2D = nullptr;
|
|
glTexStorage3D = nullptr;
|
|
|
|
}
|
|
|
|
// For MSAA
|
|
glFramebufferTexture2DMultisampleEXT = (PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC)((void*)eglGetProcAddress("glFramebufferTexture2DMultisampleEXT"));
|
|
glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)((void*)eglGetProcAddress("glRenderbufferStorageMultisampleEXT"));
|
|
|
|
if (!bFoundAllEntryPoints)
|
|
{
|
|
UE_LOG(LogRHI, Warning, TEXT("Failed to acquire all optional OpenGL entrypoints, may fall back to OpenGL ES 2.0"));
|
|
}
|
|
|
|
if (bAdvancedFeatures)
|
|
{
|
|
GLuint DefaultVertexArrayObject = 0;
|
|
glGenVertexArrays(1, &DefaultVertexArrayObject);
|
|
glBindVertexArray(DefaultVertexArrayObject);
|
|
}
|
|
InitDefaultGLContextState();
|
|
InitDebugContext();
|
|
|
|
AndroidEGL::GetInstance()->SetMultithreadRenderingContext();
|
|
if (bAdvancedFeatures)
|
|
{
|
|
GLuint DefaultVertexArrayObject = 0;
|
|
glGenVertexArrays(1, &DefaultVertexArrayObject);
|
|
glBindVertexArray(DefaultVertexArrayObject);
|
|
}
|
|
InitDefaultGLContextState();
|
|
InitDebugContext();
|
|
|
|
AndroidEGL::GetInstance()->SetSharedContext();
|
|
if (bAdvancedFeatures)
|
|
{
|
|
GLuint DefaultVertexArrayObject = 0;
|
|
glGenVertexArrays(1, &DefaultVertexArrayObject);
|
|
glBindVertexArray(DefaultVertexArrayObject);
|
|
}
|
|
InitDefaultGLContextState();
|
|
InitDebugContext();
|
|
|
|
PlatformSharedContextSetup(this);
|
|
|
|
AndroidEGL::GetInstance()->InitBackBuffer(); //can be done only after context is made current.
|
|
}
|
|
|
|
void FPlatformOpenGLDevice::SetCurrentSharedContext()
|
|
{
|
|
AndroidEGL::GetInstance()->SetCurrentSharedContext();
|
|
}
|
|
|
|
void FPlatformOpenGLDevice::SetCurrentRenderingContext()
|
|
{
|
|
AndroidEGL::GetInstance()->SetCurrentRenderingContext();
|
|
}
|
|
|
|
|
|
FPlatformOpenGLDevice* PlatformCreateOpenGLDevice()
|
|
{
|
|
FPlatformOpenGLDevice* Device = new FPlatformOpenGLDevice();
|
|
Device->Init();
|
|
return Device;
|
|
}
|
|
|
|
bool PlatformCanEnableGPUCapture()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
void PlatformDestroyOpenGLDevice(FPlatformOpenGLDevice* Device)
|
|
{
|
|
delete Device;
|
|
}
|
|
|
|
FPlatformOpenGLContext* PlatformCreateOpenGLContext(FPlatformOpenGLDevice* Device, void* InWindowHandle)
|
|
{
|
|
//Assumes Device is already initialized and context already created.
|
|
return AndroidEGL::GetInstance()->GetRenderingContext();
|
|
}
|
|
|
|
void PlatformReleaseOpenGLContext(FPlatformOpenGLDevice* Device, FPlatformOpenGLContext* PlatformContext)
|
|
{
|
|
// nothing to do for now
|
|
}
|
|
|
|
void* PlatformGetWindow(FPlatformOpenGLContext* Context, void** AddParam)
|
|
{
|
|
check(Context);
|
|
|
|
return (void*)&Context->eglContext;
|
|
}
|
|
|
|
void PlatformDestroyOpenGLContext(FPlatformOpenGLDevice* Device, FPlatformOpenGLContext* PlatformContext)
|
|
{
|
|
delete Device; //created here, destroyed here, but held by RHI.
|
|
}
|
|
|
|
bool PlatformBlitToViewport( FPlatformOpenGLDevice* Device, const FOpenGLViewport& Viewport, uint32 BackbufferSizeX, uint32 BackbufferSizeY, bool bPresent,bool bLockToVsync, int32 SyncInterval )
|
|
{
|
|
if (FOpenGL::IsES2())
|
|
{
|
|
AndroidEGL::GetInstance()->SwapBuffers();
|
|
}
|
|
else
|
|
{
|
|
FPlatformOpenGLContext* const Context = Viewport.GetGLContext();
|
|
|
|
check(Context && Context->eglContext );
|
|
|
|
FScopeContext ScopeContext(Context);
|
|
|
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
|
//Disabling for now to work around a GL_INVALID_OPERATION which might or might not be legit in the context of EGL.
|
|
//Note that the drawbuffer state is part of the FBO state, so we don't need to touch it per frame.
|
|
//glDrawBuffer(GL_BACK);
|
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, Context->ViewportFramebuffer);
|
|
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
|
|
|
//LOGD("PlatformBlitToViewport: backbuffer (%d, %d) to screen (%d, %d)", BackbufferSizeX, BackbufferSizeY, GRealScreenWidth, GRealScreenHeight);
|
|
|
|
uint32 GRealScreenHeight, GRealScreenWidth;
|
|
AndroidEGL::GetInstance()->GetDimensions( GRealScreenWidth, GRealScreenHeight);
|
|
|
|
glBlitFramebuffer(
|
|
0, 0, BackbufferSizeX, BackbufferSizeY,
|
|
0, GRealScreenHeight, GRealScreenWidth, 0,
|
|
GL_COLOR_BUFFER_BIT,
|
|
GL_LINEAR
|
|
);
|
|
|
|
if (bPresent)
|
|
{
|
|
uint32 IdleStart = FPlatformTime::Cycles();
|
|
|
|
AndroidEGL::GetInstance()->SwapBuffers();
|
|
REPORT_GL_END_BUFFER_EVENT_FOR_FRAME_DUMP();
|
|
// INITIATE_GL_FRAME_DUMP_EVERY_X_CALLS( 1000 );
|
|
|
|
GRenderThreadIdle[ERenderThreadIdleTypes::WaitingForGPUPresent] += FPlatformTime::Cycles() - IdleStart;
|
|
GRenderThreadNumIdle[ERenderThreadIdleTypes::WaitingForGPUPresent]++;
|
|
}
|
|
}
|
|
// return true;
|
|
//Do not want WaitForFrameEventCompletion
|
|
return false;
|
|
}
|
|
|
|
void PlatformRenderingContextSetup(FPlatformOpenGLDevice* Device)
|
|
{
|
|
Device->SetCurrentRenderingContext();
|
|
}
|
|
|
|
void PlatformFlushIfNeeded()
|
|
{
|
|
}
|
|
|
|
void PlatformRebindResources(FPlatformOpenGLDevice* Device)
|
|
{
|
|
}
|
|
|
|
void PlatformSharedContextSetup(FPlatformOpenGLDevice* Device)
|
|
{
|
|
Device->SetCurrentSharedContext();
|
|
}
|
|
|
|
void PlatformNULLContextSetup()
|
|
{
|
|
AndroidEGL::GetInstance()->SetCurrentContext(EGL_NO_CONTEXT, EGL_NO_SURFACE);
|
|
}
|
|
|
|
EOpenGLCurrentContext PlatformOpenGLCurrentContext(FPlatformOpenGLDevice* Device)
|
|
{
|
|
return (EOpenGLCurrentContext)AndroidEGL::GetInstance()->GetCurrentContextType();
|
|
}
|
|
|
|
void PlatformRestoreDesktopDisplayMode()
|
|
{
|
|
}
|
|
|
|
FRHITexture* PlatformCreateBuiltinBackBuffer(FOpenGLDynamicRHI* OpenGLRHI, uint32 SizeX, uint32 SizeY)
|
|
{
|
|
FOpenGLTexture2D* Texture2D = NULL;
|
|
|
|
if ( FOpenGL::IsES2())
|
|
{
|
|
uint32 Flags = TexCreate_RenderTargetable;
|
|
Texture2D = new FOpenGLTexture2D(OpenGLRHI, AndroidEGL::GetInstance()->GetOnScreenColorRenderBuffer(), GL_RENDERBUFFER, GL_COLOR_ATTACHMENT0, SizeX, SizeY, 0, 1, 1, 1, PF_B8G8R8A8, false, false, Flags, nullptr, FClearValueBinding::Transparent);
|
|
OpenGLTextureAllocated(Texture2D, Flags);
|
|
}
|
|
|
|
return Texture2D;
|
|
}
|
|
|
|
void PlatformResizeGLContext( FPlatformOpenGLDevice* Device, FPlatformOpenGLContext* Context, uint32 SizeX, uint32 SizeY, bool bFullscreen, bool bWasFullscreen, GLenum BackBufferTarget, GLuint BackBufferResource)
|
|
{
|
|
check(Context);
|
|
FScopeContext ScopeContext(Context);
|
|
|
|
if (FOpenGL::IsES2())
|
|
{
|
|
glViewport(0, 0, SizeX, SizeY);
|
|
VERIFY_GL(glViewport);
|
|
}
|
|
else
|
|
{
|
|
if (Context->ViewportFramebuffer == 0)
|
|
{
|
|
glGenFramebuffers(1, &Context->ViewportFramebuffer);
|
|
}
|
|
glBindFramebuffer(GL_FRAMEBUFFER, Context->ViewportFramebuffer);
|
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, BackBufferTarget, BackBufferResource, 0);
|
|
|
|
#if UE_BUILD_DEBUG
|
|
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
|
FOpenGL::DrawBuffer(GL_COLOR_ATTACHMENT0);
|
|
GLenum CompleteResult = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
|
if (CompleteResult != GL_FRAMEBUFFER_COMPLETE)
|
|
{
|
|
UE_LOG(LogRHI, Fatal, TEXT("PlatformResizeGLContext: Framebuffer not complete. Status = 0x%x"), CompleteResult);
|
|
}
|
|
#endif
|
|
|
|
glViewport(0, 0, SizeX, SizeY);
|
|
static GLfloat ZeroColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
|
glClearBufferfv(GL_COLOR, 0, ZeroColor);
|
|
}
|
|
}
|
|
|
|
void PlatformGetSupportedResolution(uint32 &Width, uint32 &Height)
|
|
{
|
|
}
|
|
|
|
bool PlatformGetAvailableResolutions(FScreenResolutionArray& Resolutions, bool bIgnoreRefreshRate)
|
|
{
|
|
|
|
return true;
|
|
}
|
|
|
|
bool PlatformInitOpenGL()
|
|
{
|
|
// Original location for querying function entrypoints
|
|
return true;
|
|
}
|
|
|
|
bool PlatformOpenGLContextValid()
|
|
{
|
|
return (eglGetCurrentContext() != EGL_NO_CONTEXT);
|
|
}
|
|
|
|
int32 PlatformGlGetError()
|
|
{
|
|
return glGetError();
|
|
}
|
|
|
|
void PlatformGetBackbufferDimensions( uint32& OutWidth, uint32& OutHeight )
|
|
{
|
|
AndroidEGL::GetInstance()->GetDimensions(OutWidth, OutHeight);
|
|
}
|
|
|
|
// =============================================================
|
|
|
|
/* Query management
|
|
* Queries can be per context, depending on the extension / version used
|
|
* This code attempts to be safe about it. The ES2 version of Android
|
|
* is #if 0 below
|
|
*/
|
|
// ES2 FALLBACK HACK
|
|
#if 0
|
|
void PlatformGetNewRenderQuery( GLuint* OutQuery, uint64* OutQueryContext )
|
|
{
|
|
GLuint NewQuery = 0;
|
|
FOpenGL::GenQueries(1, &NewQuery);
|
|
*OutQuery = NewQuery;
|
|
*OutQueryContext = 0;
|
|
}
|
|
|
|
void PlatformReleaseRenderQuery( GLuint Query, uint64 QueryContext )
|
|
{
|
|
FOpenGL::DeleteQueries(1, &Query);
|
|
}
|
|
|
|
bool PlatformContextIsCurrent( uint64 QueryContext )
|
|
{
|
|
return true;
|
|
}
|
|
|
|
#else
|
|
|
|
struct FOpenGLReleasedQuery
|
|
{
|
|
EGLContext Context;
|
|
GLuint Query;
|
|
};
|
|
|
|
static TArray<FOpenGLReleasedQuery> ReleasedQueries;
|
|
static FCriticalSection* ReleasedQueriesGuard;
|
|
|
|
void PlatformGetNewRenderQuery(GLuint* OutQuery, uint64* OutQueryContext)
|
|
{
|
|
if (!ReleasedQueriesGuard)
|
|
{
|
|
ReleasedQueriesGuard = new FCriticalSection;
|
|
}
|
|
|
|
{
|
|
FScopeLock Lock(ReleasedQueriesGuard);
|
|
|
|
#ifdef UE_BUILD_DEBUG
|
|
check(OutQuery && OutQueryContext);
|
|
#endif
|
|
|
|
EGLContext Context = eglGetCurrentContext();
|
|
check(Context);
|
|
|
|
GLuint NewQuery = 0;
|
|
|
|
/*
|
|
* Note, not reusing queries, because timestamp and occlusion are different
|
|
*/
|
|
|
|
if (!NewQuery)
|
|
{
|
|
FOpenGL::GenQueries(1, &NewQuery);
|
|
}
|
|
|
|
*OutQuery = NewQuery;
|
|
*OutQueryContext = (uint64)Context;
|
|
}
|
|
}
|
|
|
|
void PlatformReleaseRenderQuery(GLuint Query, uint64 QueryContext)
|
|
{
|
|
EGLContext Context = eglGetCurrentContext();
|
|
if ((uint64)Context == QueryContext)
|
|
{
|
|
FOpenGL::DeleteQueries(1, &Query);
|
|
}
|
|
else
|
|
{
|
|
FScopeLock Lock(ReleasedQueriesGuard);
|
|
#ifdef UE_BUILD_DEBUG
|
|
check(Query && QueryContext && ReleasedQueriesGuard);
|
|
#endif
|
|
FOpenGLReleasedQuery ReleasedQuery;
|
|
ReleasedQuery.Context = (EGLContext)QueryContext;
|
|
ReleasedQuery.Query = Query;
|
|
ReleasedQueries.Add(ReleasedQuery);
|
|
}
|
|
}
|
|
|
|
void DeleteOcclusionQueriesForCurrentContext(EGLContext Context)
|
|
{
|
|
if (!ReleasedQueriesGuard)
|
|
{
|
|
ReleasedQueriesGuard = new FCriticalSection;
|
|
}
|
|
|
|
{
|
|
FScopeLock Lock(ReleasedQueriesGuard);
|
|
for (int32 Index = 0; Index < ReleasedQueries.Num(); ++Index)
|
|
{
|
|
if (ReleasedQueries[Index].Context == Context)
|
|
{
|
|
FOpenGL::DeleteQueries(1, &ReleasedQueries[Index].Query);
|
|
ReleasedQueries.RemoveAtSwap(Index);
|
|
--Index;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool PlatformContextIsCurrent( uint64 QueryContext )
|
|
{
|
|
return (uint64)eglGetCurrentContext() == QueryContext;
|
|
}
|
|
#endif
|
|
|
|
|
|
FString FAndroidMisc::GetGPUFamily()
|
|
{
|
|
return FAndroidGPUInfo::Get().GPUFamily;
|
|
}
|
|
|
|
FString FAndroidMisc::GetGLVersion()
|
|
{
|
|
return FAndroidGPUInfo::Get().GLVersion;
|
|
}
|
|
|
|
bool FAndroidMisc::SupportsFloatingPointRenderTargets()
|
|
{
|
|
return FAndroidGPUInfo::Get().bSupportsFloatingPointRenderTargets;
|
|
}
|
|
|
|
bool FAndroidMisc::SupportsShaderFramebufferFetch()
|
|
{
|
|
return FAndroidGPUInfo::Get().bSupportsFrameBufferFetch;
|
|
}
|
|
|
|
bool FAndroidMisc::SupportsES30()
|
|
{
|
|
return FAndroidGPUInfo::Get().bES30Support;
|
|
}
|
|
|
|
bool FAndroidMisc::SupportsShaderIOBlocks()
|
|
{
|
|
return FAndroidGPUInfo::Get().bSupportsShaderIOBlocks;
|
|
}
|
|
|
|
void FAndroidMisc::GetValidTargetPlatforms(TArray<FString>& TargetPlatformNames)
|
|
{
|
|
TargetPlatformNames = FAndroidGPUInfo::Get().TargetPlatformNames;
|
|
}
|
|
|
|
void FAndroidAppEntry::PlatformInit()
|
|
{
|
|
const bool Debug = PlatformOpenGLDebugCtx();
|
|
|
|
// @todo vulkan: Yet another bit of FAndroidApp stuff that's in GL - and should be cleaned up if possible
|
|
if (!FAndroidMisc::ShouldUseVulkan())
|
|
{
|
|
//AndroidEGL::GetInstance()->Init(AndroidEGL::AV_OpenGLES, 3, 1, Debug);
|
|
AndroidEGL::GetInstance()->Init(AndroidEGL::AV_OpenGLES, 2, 0, Debug);
|
|
}
|
|
}
|
|
|
|
void FAndroidAppEntry::ReleaseEGL()
|
|
{
|
|
AndroidEGL* EGL = AndroidEGL::GetInstance();
|
|
if (EGL->IsInitialized())
|
|
{
|
|
EGL->DestroyBackBuffer();
|
|
EGL->Terminate();
|
|
}
|
|
}
|
|
|
|
#endif
|