Files
UnrealEngineUWP/Engine/Source/Runtime/OpenGLDrv/Private/Android/AndroidESDeferredOpenGL.cpp
Chris Babcock 53d0f6830a Copying //UE4/Dev-Mobile to //UE4/Dev-Main (Source: //UE4/Dev-Mobile @ 3116515)
#lockdown Nick.Penwarden
#rb none

==========================
MAJOR FEATURES + CHANGES
==========================

Change 3065209 on 2016/07/26 by Steve.Cano

Add Android Texture Format used for packaging/cooking to the Manifest File

#ue4
#android
#jira UE-33645

Change 3068915 on 2016/07/28 by Steve.Cano

Add an additional Texture Compression support line in the manifest for DXT

#ue4
#android
#jira UE-33645

Change 3075911 on 2016/08/03 by Steve.Cano

Make the "Running {ProjectName} on {Device}" toast stay up when launching a game to an Android device until we've finished running it, as it does on other platforms. This logic already existed but only ran if the "Prebuilt" flag was passed in, however we want this to always run now. Re-writing to run through waiting on each process to finish for each device launched on

#jira UE-3122
#ue4
#android

Change 3080981 on 2016/08/08 by Steve.Cano

Clear any input before removing the TouchInterface from the screen to prevent infinite input after it is cleared

#jira UE-33956
#ue4
#platform

Change 3092587 on 2016/08/17 by Steve.Cano

Adding "IsGamepadAttached" functionality to Android Application

#jira UE-33264
#ue4
#android

Change 3095840 on 2016/08/21 by Dmitriy.Dyomin

Fixed: Particle Cutout Crashes On Certain Devices (Samsung Galaxy Note 2)
Happens only with non-instanced path

#jira UE-34604

Change 3095855 on 2016/08/22 by Dmitriy.Dyomin

Allow UWorldComposition::GetTilesList to be used in runtime code
Licensee request https://udn.unrealengine.com/questions/307586/world-compositions-world-dimensions.html

Change 3096093 on 2016/08/22 by Allan.Bentham

Allow Vulkan api logging on android

Change 3096361 on 2016/08/22 by Steve.Cano

Github 2663 pull - Pass any extras used to launch SplashActivity down to GameActivity (Contributed by sangpan)

#jira UE-34050
#github #2663
#ue4
#android

Change 3097412 on 2016/08/23 by Dmitriy.Dyomin

Using BulkSerialize for cooked collision data to speed up serialization

Change 3098957 on 2016/08/23 by Jack.Porter

Merging //UE4/Dev-Main to Dev-Mobile (//UE4/Dev-Mobile)

Change 3099058 on 2016/08/24 by Jack.Porter

Check EXT_debug_label and EXT_debug_marker functions were found before calling as a few devices to not implement these extensions
#UE-35087

Change 3099131 on 2016/08/24 by Dmitriy.Dyomin

Fixed: HDR compressed texture become black in some mali devices
Use sized internal format for half-float textures on ES3 devices, as ES3 spec expects it
#jira UE-35018

Change 3099150 on 2016/08/24 by Dmitriy.Dyomin

Enable HALF_FLOAT and UNSIGNED_INT_2_10_10_10_REV vertex formats on ES3+ devices, spec req

Change 3102252 on 2016/08/26 by Dmitriy.Dyomin

Prevent view uniform buffer crash on ES2 devices that do not support 3D textures

Change 3102258 on 2016/08/26 by Dmitriy.Dyomin

Enabled refraction on iPadMini4
#jira UE-35079

Change 3102651 on 2016/08/26 by Dmitriy.Dyomin

Fixed: instanced static mesh world normals
Also removed unnecessary instance matrix transposing
#jira UE-35075

Change 3109397 on 2016/09/01 by Jack.Porter

Fix problem with Android sessions not appearing in Session Frontend

#jira UE-35261

Change 3109490 on 2016/09/01 by Jack.Porter

Merging //UE4/Dev-Main to Dev-Mobile (//UE4/Dev-Mobile)

Change 3111628 on 2016/09/02 by Jack.Porter

Landscape wireframe LOD visualization with tessellation

Change 3112809 on 2016/09/02 by Chris.Babcock

Update cached length when file is written to on Android
#jira UE-35558
#ue4
#android

Change 3113245 on 2016/09/04 by Dmitriy.Dyomin

Fixed: Subway Sequencer plays only a black screen when packaged for ESDSR (3.1+AEP)
#jira UE-34291

Change 3113249 on 2016/09/04 by Dmitriy.Dyomin

Replicated fix from 4.13: GPU particles no longer work on iOS or TVOS Metal devices
#jira UE-34782

Change 3113513 on 2016/09/05 by Allan.Bentham

Add vulkan version parameter to android device profile selector's source inputs .
reinstate Vulkan Disable cvar functionality.
Added mali no vulkan device profile.

Change 3113519 on 2016/09/05 by Allan.Bentham

Remove temp 4.13 hack to avoid public header changes.

Change 3113535 on 2016/09/05 by Allan.Bentham

Decode 32 bit HDR formats when using scene captures.
#jira UE-25444

Change 3113813 on 2016/09/06 by Dmitriy.Dyomin

Resend to server sub-levels visibility state right after world actors are initialized.
During seamless travel client loads always-loaded sub-levels before world actors are initialized and ServerUpdateLevelVisibility calls in UWorld::AddToWorld are skipped.

Change 3113870 on 2016/09/06 by Jack.Porter

Fix issue with ES2 Feature Level preview and Mobile Preview PIE not limiting materials to 8 textures
#jira UE-35591

Change 3115031 on 2016/09/06 by Chris.Babcock

Add Vulkan version code not moved over from 4.13.1
#jira UE-35642
#ue4
#android

Change 3115496 on 2016/09/07 by Dmitriy.Dyomin

Use the same DDC key for source reflection data and encoded data. Fixes broken reflections on mobile
#jira UE-35647

[CL 3116720 by Chris Babcock in Main branch]
2016-09-07 17:04:11 -04:00

608 lines
16 KiB
C++

// Copyright 1998-2016 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>
#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;
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;
}
}
}
///////////////////////////////////////////////////////////////////////////////
// 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;
}
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;
}
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