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:
Romain Guy
2018-11-29 16:55:36 -08:00
committed by GitHub
parent da7dbbc04b
commit bd0b752337
7 changed files with 136 additions and 28 deletions

View File

@@ -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());
}

View File

@@ -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);

View File

@@ -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.
*

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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;