Add RenderQuality API (#555)
View::setRenderQuality gives the ability to control the rendering quality of a given view. In particular this allows the app to lower the quality of the HDR color buffer by using R11G11B10F instead of RGB(A)16F.
This commit is contained in:
@@ -119,7 +119,7 @@ extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_View_nGetAntiAliasing(JNIEnv*, jclass,
|
||||
jlong nativeView) {
|
||||
View* view = (View*) nativeView;
|
||||
return (jint)view->getAntiAliasing();
|
||||
return (jint) view->getAntiAliasing();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
@@ -134,21 +134,31 @@ Java_com_google_android_filament_View_nSetDynamicResolutionOptions(JNIEnv*,
|
||||
options.targetFrameTimeMilli = targetFrameTimeMilli;
|
||||
options.headRoomRatio = headRoomRatio;
|
||||
options.scaleRate = scaleRate;
|
||||
options.minScale = math::float2{ minScale };
|
||||
options.maxScale = math::float2{ maxScale };
|
||||
options.history = (uint8_t)history;
|
||||
return view->setDynamicResolutionOptions(options);
|
||||
options.minScale = math::float2{minScale};
|
||||
options.maxScale = math::float2{maxScale};
|
||||
options.history = (uint8_t) history;
|
||||
view->setDynamicResolutionOptions(options);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetRenderQuality(JNIEnv*, jclass,
|
||||
jlong nativeView, jint hdrColorBufferQuality) {
|
||||
View* view = (View*) nativeView;
|
||||
View::RenderQuality renderQuality;
|
||||
renderQuality.hdrColorBuffer = View::QualityLevel(hdrColorBufferQuality);
|
||||
view->setRenderQuality(renderQuality);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetDynamicLightingOptions(JNIEnv *env,
|
||||
Java_com_google_android_filament_View_nSetDynamicLightingOptions(JNIEnv*,
|
||||
jclass, jlong nativeView, jfloat zLightNear, jfloat zLightFar) {
|
||||
View* view = (View*) nativeView;
|
||||
view->setDynamicLightingOptions(zLightNear, zLightFar);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetDepthPrepass(JNIEnv *env,
|
||||
Java_com_google_android_filament_View_nSetDepthPrepass(JNIEnv*,
|
||||
jclass, jlong nativeView, jint value) {
|
||||
View* view = (View*) nativeView;
|
||||
view->setDepthPrepass(View::DepthPrepass(value));
|
||||
@@ -165,5 +175,5 @@ extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_View_nIsPostProcessingEnabled(JNIEnv*,
|
||||
jclass, jlong nativeView) {
|
||||
View* view = (View*) nativeView;
|
||||
return view->isPostProcessingEnabled();
|
||||
return static_cast<jboolean>(view->isPostProcessingEnabled());
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ public class View {
|
||||
private Camera mCamera;
|
||||
private Viewport mViewport = new Viewport(0, 0, 0, 0);
|
||||
private DynamicResolutionOptions mDynamicResolution;
|
||||
private RenderQuality mRenderQuality;
|
||||
private DepthPrepass mDepthPrepass = DepthPrepass.DEFAULT;
|
||||
|
||||
public static class DynamicResolutionOptions {
|
||||
@@ -41,7 +42,18 @@ public class View {
|
||||
public float minScale = 0.5f;
|
||||
public float maxScale = 1.0f;
|
||||
public int history = 9;
|
||||
};
|
||||
}
|
||||
|
||||
public enum QualityLevel {
|
||||
LOW,
|
||||
MEDIUM,
|
||||
HIGH,
|
||||
ULTRA
|
||||
}
|
||||
|
||||
public static class RenderQuality {
|
||||
public QualityLevel hdrColorBuffer = QualityLevel.HIGH;
|
||||
}
|
||||
|
||||
public enum AntiAliasing {
|
||||
NONE,
|
||||
@@ -169,13 +181,26 @@ public class View {
|
||||
return mDynamicResolution;
|
||||
}
|
||||
|
||||
public void setRenderQuality(@NonNull RenderQuality renderQuality) {
|
||||
mRenderQuality = renderQuality;
|
||||
nSetRenderQuality(getNativeObject(), renderQuality.hdrColorBuffer.ordinal());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public RenderQuality getRenderQuality() {
|
||||
if (mRenderQuality == null) {
|
||||
mRenderQuality = new RenderQuality();
|
||||
}
|
||||
return mRenderQuality;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public DepthPrepass getDepthPrepass() {
|
||||
return mDepthPrepass;
|
||||
}
|
||||
|
||||
public void setDepthPrepass(@NonNull DepthPrepass depthPrepass) {
|
||||
mDepthPrepass = mDepthPrepass;
|
||||
mDepthPrepass = depthPrepass;
|
||||
nSetDepthPrepass(getNativeObject(), depthPrepass.value);
|
||||
}
|
||||
|
||||
@@ -228,6 +253,7 @@ public class View {
|
||||
boolean enabled, boolean homogeneousScaling,
|
||||
float targetFrameTimeMilli, float headRoomRatio, float scaleRate,
|
||||
float minScale, float maxScale, int history);
|
||||
private static native void nSetRenderQuality(long nativeView, int hdrColorBufferQuality);
|
||||
private static native void nSetDynamicLightingOptions(long nativeView, float zLightNear, float zLightFar);
|
||||
private static native void nSetDepthPrepass(long nativeView, int value);
|
||||
private static native void nSetPostProcessingEnabled(long nativeView, boolean enabled);
|
||||
|
||||
@@ -110,12 +110,41 @@ public:
|
||||
float scaleRate = 0.125f; //!< rate at which the scale will change
|
||||
float targetFrameTimeMilli = 1000.0f / 60.0f; //!< desired frame time, or budget.
|
||||
float headRoomRatio = 0.0f; //!< additional headroom for the GPU
|
||||
float reserved[5] = { 0.0f }; //!< reserved fields, must be zero
|
||||
uint8_t history = 9; //!< history size
|
||||
bool enabled = false; //!< enable or disable dynamic resolution
|
||||
bool homogeneousScaling = false; //!< set to true to force homogeneous scaling
|
||||
};
|
||||
|
||||
enum class QualityLevel : int8_t {
|
||||
LOW,
|
||||
MEDIUM,
|
||||
HIGH,
|
||||
ULTRA
|
||||
};
|
||||
|
||||
/**
|
||||
* Structure used to set the quality of the rendering of a View. This structure
|
||||
* offers separate quality settings for different parts of the rendering pipeline:
|
||||
*
|
||||
* hdrColorBuffer: sets the quality of the HDR color buffer. A quality of HIGH or ULTRA means
|
||||
* using an RGB16F or RGBA16F color buffer. This means colors in the LDR
|
||||
* range (0..1) have a 10 bit precision. A quality of LOW or MEDIUM means
|
||||
* using an R11G11B10F opaque color buffer or an RGBA16F transparent color
|
||||
* buffer. With R11G11B10F colors in the LDR range have a precision of either
|
||||
* 6 bits (red and green channels) or 5 bits (blue channel).
|
||||
*/
|
||||
struct RenderQuality {
|
||||
QualityLevel hdrColorBuffer = QualityLevel::HIGH; //!< quality of the color buffer
|
||||
};
|
||||
|
||||
/**
|
||||
* List of available post-processing anti-aliasing techniques.
|
||||
*/
|
||||
enum AntiAliasing : uint8_t {
|
||||
NONE = 0,
|
||||
FXAA = 1
|
||||
};
|
||||
|
||||
enum class DepthPrepass : int8_t {
|
||||
DEFAULT = -1,
|
||||
DISABLED,
|
||||
@@ -178,6 +207,10 @@ public:
|
||||
*/
|
||||
Scene* getScene() noexcept;
|
||||
|
||||
/**
|
||||
* Returns the Scene currently associated with this View.
|
||||
* @return A pointer to the Scene associated to this View. nullptr if no Scene is set.
|
||||
*/
|
||||
Scene const* getScene() const noexcept {
|
||||
return const_cast<View*>(this)->getScene();
|
||||
}
|
||||
@@ -326,11 +359,6 @@ public:
|
||||
*/
|
||||
uint8_t getSampleCount() const noexcept;
|
||||
|
||||
enum AntiAliasing : uint8_t {
|
||||
NONE = 0,
|
||||
FXAA = 1
|
||||
};
|
||||
|
||||
/**
|
||||
* Enables or disables anti-aliasing in the post-processing stage. Enabled by default.
|
||||
* MSAA can be enabled in addition, see setSampleCount().
|
||||
@@ -361,6 +389,20 @@ public:
|
||||
*/
|
||||
DynamicResolutionOptions getDynamicResolutionOptions() const noexcept;
|
||||
|
||||
/**
|
||||
* Sets the rendering quality for this view. Refer to RenderQuality for more
|
||||
* information about the different settings available.
|
||||
*
|
||||
* @param renderQuality The render quality to use on this view
|
||||
*/
|
||||
void setRenderQuality(RenderQuality const& renderQuality) noexcept;
|
||||
|
||||
/**
|
||||
* Returns the render quality used by this view.
|
||||
* @return value set by setRenderQuality().
|
||||
*/
|
||||
RenderQuality getRenderQuality() const noexcept;
|
||||
|
||||
/**
|
||||
* Sets options relative to dynamic lighting for this view.
|
||||
*
|
||||
|
||||
@@ -95,6 +95,27 @@ void FRenderer::terminate(FEngine& engine) {
|
||||
}
|
||||
}
|
||||
|
||||
driver::TextureFormat FRenderer::getHdrFormat(const View& view) const noexcept {
|
||||
const bool translucent = mSwapChain->isTransparent();
|
||||
if (translucent) return driver::TextureFormat::RGBA16F;
|
||||
|
||||
switch (view.getRenderQuality().hdrColorBuffer) {
|
||||
case View::QualityLevel::LOW:
|
||||
case View::QualityLevel::MEDIUM:
|
||||
return driver::TextureFormat::R11F_G11F_B10F;
|
||||
case View::QualityLevel::HIGH:
|
||||
case View::QualityLevel::ULTRA:
|
||||
return !mIsRGB16FSupported ? driver::TextureFormat::RGBA16F
|
||||
: driver::TextureFormat::RGB16F;
|
||||
}
|
||||
}
|
||||
|
||||
driver::TextureFormat FRenderer::getLdrFormat() const noexcept {
|
||||
const bool translucent = mSwapChain->isTransparent();
|
||||
return (translucent || !mIsRGB8Supported) ? driver::TextureFormat::RGBA8
|
||||
: driver::TextureFormat::RGB8;
|
||||
}
|
||||
|
||||
void FRenderer::render(FView const* view) {
|
||||
SYSTRACE_CALL();
|
||||
|
||||
@@ -177,7 +198,7 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
|
||||
*/
|
||||
|
||||
const uint8_t useMSAA = view.getSampleCount();
|
||||
const TextureFormat hdrFormat = getHdrFormat();
|
||||
const TextureFormat hdrFormat = getHdrFormat(view);
|
||||
const TextureFormat ldrFormat = getLdrFormat();
|
||||
RenderTargetPool::Target const* colorTarget = nullptr;
|
||||
|
||||
|
||||
@@ -847,6 +847,14 @@ View::DynamicResolutionOptions View::getDynamicResolutionOptions() const noexcep
|
||||
return upcast(this)->getDynamicResolutionOptions();
|
||||
}
|
||||
|
||||
void View::setRenderQuality(const RenderQuality& renderQuality) noexcept {
|
||||
upcast(this)->setRenderQuality(renderQuality);
|
||||
}
|
||||
|
||||
View::RenderQuality View::getRenderQuality() const noexcept {
|
||||
return upcast(this)->getRenderQuality();
|
||||
}
|
||||
|
||||
void View::setPostProcessingEnabled(bool enabled) noexcept {
|
||||
upcast(this)->setPostProcessingEnabled(enabled);
|
||||
}
|
||||
|
||||
@@ -120,17 +120,8 @@ private:
|
||||
return mCommandsHighWatermark * sizeof(RenderPass::Command);
|
||||
}
|
||||
|
||||
driver::TextureFormat getHdrFormat() const noexcept {
|
||||
const bool translucent = mSwapChain->isTransparent();
|
||||
return (translucent || !mIsRGB16FSupported) ? driver::TextureFormat::RGBA16F
|
||||
: driver::TextureFormat::RGB16F;
|
||||
}
|
||||
|
||||
driver::TextureFormat getLdrFormat() const noexcept {
|
||||
const bool translucent = mSwapChain->isTransparent();
|
||||
return (translucent || !mIsRGB8Supported) ? driver::TextureFormat::RGBA8
|
||||
: driver::TextureFormat::RGB8;
|
||||
}
|
||||
driver::TextureFormat getHdrFormat(const View& view) const noexcept;
|
||||
driver::TextureFormat getLdrFormat() const noexcept;
|
||||
|
||||
// keep a reference to our engine
|
||||
FEngine& mEngine;
|
||||
|
||||
@@ -180,6 +180,14 @@ public:
|
||||
return mDynamicResolution;
|
||||
}
|
||||
|
||||
void setRenderQuality(RenderQuality const& renderQuality) noexcept {
|
||||
mRenderQuality = renderQuality;
|
||||
}
|
||||
|
||||
RenderQuality getRenderQuality() const noexcept {
|
||||
return mRenderQuality;
|
||||
}
|
||||
|
||||
void setDynamicLightingOptions(float zLightNear, float zLightFar) noexcept;
|
||||
|
||||
void setPostProcessingEnabled(bool enabled) noexcept {
|
||||
@@ -279,6 +287,8 @@ private:
|
||||
float mDynamicWorkloadScale = 1.0f;
|
||||
bool mIsDynamicResolutionSupported = false;
|
||||
|
||||
RenderQuality mRenderQuality;
|
||||
|
||||
mutable UniformBuffer mPerViewUb;
|
||||
mutable SamplerBuffer mPerViewSb;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user