Class Renderer
- java.lang.Object
-
- com.google.android.filament.Renderer
-
public class Renderer extends java.lang.ObjectARendererinstance represents an operating system's window.Typically, applications create a
Rendererper window. TheRenderergenerates drawing commands for the render thread and manages frame latency.
A Renderer generates drawing commands from a View, itself containing a Scene description.Creation and Destruction
A
Rendereris created usingEngine.createRenderer()and destroyed usingEngine.destroyRenderer(com.google.android.filament.Renderer).
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classRenderer.ClearOptionsClearOptions are used at the beginning of a frame to clear or retain the SwapChain content.static classRenderer.DisplayInfoInformation about the display this renderer is associated tostatic classRenderer.FrameRateOptionsUse FrameRateOptions to set the desired frame rate and control how quickly the system reacts to GPU load changes.
-
Field Summary
Fields Modifier and Type Field Description static intMIRROR_FRAME_FLAG_CLEARIndicates that thedstSwapChainpassed intocopyFrame(com.google.android.filament.SwapChain, com.google.android.filament.Viewport, com.google.android.filament.Viewport, int)should be cleared to black before the frame is copied into the specified viewport.static intMIRROR_FRAME_FLAG_COMMITIndicates that thedstSwapChainpassed intocopyFrame(com.google.android.filament.SwapChain, com.google.android.filament.Viewport, com.google.android.filament.Viewport, int)should be committed after the frame has been copied.static intMIRROR_FRAME_FLAG_SET_PRESENTATION_TIMEIndicates that the presentation time should be set on thedstSwapChainpassed intocopyFrame(com.google.android.filament.SwapChain, com.google.android.filament.Viewport, com.google.android.filament.Viewport, int)to the monotonic clock time when the frame is copied.
-
Method Summary
All Methods Instance Methods Concrete Methods Deprecated Methods Modifier and Type Method Description booleanbeginFrame(SwapChain swapChain, long frameTimeNanos)Sets up a frame for thisRenderer.voidcopyFrame(SwapChain dstSwapChain, Viewport dstViewport, Viewport srcViewport, int flags)voidendFrame()Finishes the current frame and schedules it for display.Renderer.ClearOptionsgetClearOptions()Returns the ClearOptions object set insetClearOptions(com.google.android.filament.Renderer.ClearOptions)or a new instance otherwise.Renderer.DisplayInfogetDisplayInfo()Returns the DisplayInfo object set insetDisplayInfo(com.google.android.filament.Renderer.DisplayInfo)or a new instance otherwise.EnginegetEngine()Gets theEnginethat created thisRenderer.Renderer.FrameRateOptionsgetFrameRateOptions()Returns the FrameRateOptions object set insetFrameRateOptions(com.google.android.filament.Renderer.FrameRateOptions)or a new instance otherwise.longgetNativeObject()doublegetUserTime()Returns a timestamp (in seconds) for the last call tobeginFrame(com.google.android.filament.SwapChain, long).voidmirrorFrame(SwapChain dstSwapChain, Viewport dstViewport, Viewport srcViewport, int flags)Deprecated.voidreadPixels(int xoffset, int yoffset, int width, int height, Texture.PixelBufferDescriptor buffer)Reads back the content of theSwapChainassociated with thisRenderer.voidreadPixels(RenderTarget renderTarget, int xoffset, int yoffset, int width, int height, Texture.PixelBufferDescriptor buffer)Reads back the content of a specifiedRenderTarget.voidrender(View view)Renders aViewinto thisRenderer's window.voidrenderStandaloneView(View view)Renders a standaloneViewinto its associatedRenderTarget.voidresetUserTime()Sets the user time epoch to now, i.e.voidsetClearOptions(Renderer.ClearOptions options)Set ClearOptions which are used at the beginning of a frame to clear or retain the SwapChain content.voidsetDisplayInfo(Renderer.DisplayInfo info)Information about the display this Renderer is associated to.voidsetFrameRateOptions(Renderer.FrameRateOptions options)Set options controlling the desired frame-rate.
-
-
-
Field Detail
-
MIRROR_FRAME_FLAG_COMMIT
public static final int MIRROR_FRAME_FLAG_COMMIT
Indicates that thedstSwapChainpassed intocopyFrame(com.google.android.filament.SwapChain, com.google.android.filament.Viewport, com.google.android.filament.Viewport, int)should be committed after the frame has been copied.
-
MIRROR_FRAME_FLAG_SET_PRESENTATION_TIME
public static final int MIRROR_FRAME_FLAG_SET_PRESENTATION_TIME
Indicates that the presentation time should be set on thedstSwapChainpassed intocopyFrame(com.google.android.filament.SwapChain, com.google.android.filament.Viewport, com.google.android.filament.Viewport, int)to the monotonic clock time when the frame is copied.
-
MIRROR_FRAME_FLAG_CLEAR
public static final int MIRROR_FRAME_FLAG_CLEAR
Indicates that thedstSwapChainpassed intocopyFrame(com.google.android.filament.SwapChain, com.google.android.filament.Viewport, com.google.android.filament.Viewport, int)should be cleared to black before the frame is copied into the specified viewport.
-
-
Method Detail
-
setDisplayInfo
public void setDisplayInfo(@NonNull Renderer.DisplayInfo info)Information about the display this Renderer is associated to. This information is needed to accurately compute dynamic-resolution scaling and for frame-pacing.
-
getDisplayInfo
@NonNull public Renderer.DisplayInfo getDisplayInfo()
Returns the DisplayInfo object set insetDisplayInfo(com.google.android.filament.Renderer.DisplayInfo)or a new instance otherwise.- Returns:
- a DisplayInfo instance
-
setFrameRateOptions
public void setFrameRateOptions(@NonNull Renderer.FrameRateOptions options)Set options controlling the desired frame-rate.
-
getFrameRateOptions
@NonNull public Renderer.FrameRateOptions getFrameRateOptions()
Returns the FrameRateOptions object set insetFrameRateOptions(com.google.android.filament.Renderer.FrameRateOptions)or a new instance otherwise.- Returns:
- a FrameRateOptions instance
-
setClearOptions
public void setClearOptions(@NonNull Renderer.ClearOptions options)Set ClearOptions which are used at the beginning of a frame to clear or retain the SwapChain content.
-
getClearOptions
@NonNull public Renderer.ClearOptions getClearOptions()
Returns the ClearOptions object set insetClearOptions(com.google.android.filament.Renderer.ClearOptions)or a new instance otherwise.- Returns:
- a ClearOptions instance
-
getEngine
@NonNull public Engine getEngine()
Gets theEnginethat created thisRenderer.- Returns:
Engineinstance thisRendereris associated to.
-
beginFrame
public boolean beginFrame(@NonNull SwapChain swapChain, long frameTimeNanos)Sets up a frame for thisRenderer.beginFramemanages frame pacing, and returns whether or not a frame should be drawn. The goal of this is to skip frames when the GPU falls behind in order to keep the frame latency low.If a given frame takes too much time in the GPU, the CPU will get ahead of the GPU. The display will draw the same frame twice producing a stutter. At this point, the CPU is ahead of the GPU and depending on how many frames are buffered, latency increases. beginFrame() attempts to detect this situation and returns
falsein that case, indicating to the caller to skip the current frame.All calls to render() must happen after beginFrame().
- Parameters:
swapChain- theSwapChaininstance to useframeTimeNanos- The time in nanoseconds when the frame started being rendered, in theSystem.nanoTime()timebase. Divide this value by 1000000 to convert it to theSystemClock.uptimeMillis()time base. This typically comes fromChoreographer.FrameCallback.- Returns:
true: the current frame must be drawn, andendFrame()must be called
false: the current frame should be skipped, when skipping a frame, the whole frame is canceled, andendFrame()must not be called. However, the user can choose to proceed as thoughtruewas returned and produce a frame anyways, by making calls torender(View), in which caseendFrame()must be called.- See Also:
endFrame(),render(com.google.android.filament.View)
-
endFrame
public void endFrame()
Finishes the current frame and schedules it for display.endFrame()schedules the current frame to be displayed on theRenderer's window.All calls to render() must happen before endFrame().
-
render
public void render(@NonNull View view)Renders aViewinto thisRenderer's window.This is filament's main rendering method, most of the CPU-side heavy lifting is performed here. The purpose of the
render()function is to generate render commands which are asynchronously executed by theEngine's render thread.render()generates commands for each of the following stages:- Shadow map passes, if needed
- Depth pre-pass
- SSAO pass, if enabled
- Color pass
- Post-processing pass
A typical render loop looks like this:
void renderLoop(Renderer renderer, SwapChain swapChain) { do { // typically we wait for VSYNC and user input events if (renderer.beginFrame(swapChain)) { renderer.render(mView); renderer.endFrame(); } } while (!quit()); }render()must be called afterbeginFrame(com.google.android.filament.SwapChain, long)and beforeendFrame().render()must be called from theEngine's main thread (or external synchronization must be provided). In particular, calls torender()on differentRendererinstances must be synchronized.render()performs potentially heavy computations and cannot be multi-threaded. However, internally, it is highly multi-threaded to both improve performance and mitigate the call's latency.render()is typically called once per frame (but not necessarily).
- Parameters:
view- theViewto render- See Also:
beginFrame(com.google.android.filament.SwapChain, long),endFrame(),View
-
renderStandaloneView
public void renderStandaloneView(@NonNull View view)Renders a standaloneViewinto its associatedRenderTarget.This call is mostly equivalent to calling
render(View)inside abeginFrame(com.google.android.filament.SwapChain, long)/endFrame()block, but incurs less overhead. It can be used as a poor man's compute API.renderStandaloneView()must be called outside ofbeginFrame(com.google.android.filament.SwapChain, long)/endFrame().renderStandaloneView()must be called from theEngine's main thread (or external synchronization must be provided). In particular, calls torenderStandaloneView()on differentRendererinstances must be synchronized.renderStandaloneView()performs potentially heavy computations and cannot be multi-threaded. However, internally, it is highly multi-threaded to both improve performance and mitigate the call's latency.
- Parameters:
view- theViewto render. This View must have an associatedRenderTarget- See Also:
View
-
copyFrame
public void copyFrame(@NonNull SwapChain dstSwapChain, @NonNull Viewport dstViewport, @NonNull Viewport srcViewport, int flags)Copies the currently renderedViewto the indicatedSwapChain, using the indicated source and destination rectangle.copyFrame()should be called after a frame is rendered usingrender(com.google.android.filament.View)but beforeendFrame()is called.- Parameters:
dstSwapChain- theSwapChaininto which the frame should be copieddstViewport- the destination rectangle in which to draw the viewsrcViewport- the source rectangle to be copiedflags- one or moreCopyFrameFlagbehavior configuration flags
-
mirrorFrame
@Deprecated public void mirrorFrame(@NonNull SwapChain dstSwapChain, @NonNull Viewport dstViewport, @NonNull Viewport srcViewport, int flags)Deprecated.
-
readPixels
public void readPixels(@IntRange(from=0L) int xoffset, @IntRange(from=0L) int yoffset, @IntRange(from=0L) int width, @IntRange(from=0L) int height, @NonNull Texture.PixelBufferDescriptor buffer)Reads back the content of theSwapChainassociated with thisRenderer.Framebuffer as seen on User buffer (PixelBufferDescriptor) screen +--------------------+ | | .stride .alignment | | ----------------------->--> | | O----------------------+--+ low addresses | | | | | | | w | | | .top | | | <---------> | | V | | | +---------+ | | +---------+ | | | | ^ | | ======> | | | | | | x | h| | | |.left| | | | +------>| v | | +---->| | | | | +.........+ | | +.........+ | | | ^ | | | | | y | | +----------------------+--+ high addresses O------------+-------+
readPixelsmust be called within a frame, meaning afterbeginFrame(com.google.android.filament.SwapChain, long)and beforeendFrame(). Typically,readPixelswill be called afterrender(com.google.android.filament.View).
After calling this method, the callback associated with
bufferwill be invoked on the main thread, indicating that the read-back has completed. Typically, this will happen after multiple calls tobeginFrame(com.google.android.filament.SwapChain, long),render(com.google.android.filament.View),endFrame().
readPixelsis intended for debugging and testing. It will impact performance significantly.- Parameters:
xoffset- left offset of the sub-region to read backyoffset- bottom offset of the sub-region to read backwidth- width of the sub-region to read backheight- height of the sub-region to read backbuffer- client-side buffer where the read-back will be writtenThe following format are always supported:
Texture.Format.RGBATexture.Format.RGBA_INTEGERThe following types are always supported:
Texture.Type.UBYTETexture.Type.UINTTexture.Type.INTTexture.Type.FLOATOther combination of format/type may be supported. If a combination is not supported, this operation may fail silently. Use a DEBUG build to get some logs about the failure.
- Throws:
java.nio.BufferOverflowException- if the specified parameters would result in reading outside ofbuffer.
-
readPixels
public void readPixels(@NonNull RenderTarget renderTarget, @IntRange(from=0L) int xoffset, @IntRange(from=0L) int yoffset, @IntRange(from=0L) int width, @IntRange(from=0L) int height, @NonNull Texture.PixelBufferDescriptor buffer)Reads back the content of a specifiedRenderTarget.Framebuffer as seen on User buffer (PixelBufferDescriptor) screen +--------------------+ | | .stride .alignment | | ----------------------->--> | | O----------------------+--+ low addresses | | | | | | | w | | | .top | | | <---------> | | V | | | +---------+ | | +---------+ | | | | ^ | | ======> | | | | | | x | h| | | |.left| | | | +------>| v | | +---->| | | | | +.........+ | | +.........+ | | | ^ | | | | | y | | +----------------------+--+ high addresses O------------+-------+
Typically
readPixelswill be called afterrender(com.google.android.filament.View)and beforeendFrame().
After calling this method, the callback associated with
bufferwill be invoked on the main thread, indicating that the read-back has completed. Typically, this will happen after multiple calls tobeginFrame(com.google.android.filament.SwapChain, long),render(com.google.android.filament.View),endFrame().
readPixelsis intended for debugging and testing. It will impact performance significantly.- Parameters:
renderTarget-RenderTargetto read back fromxoffset- left offset of the sub-region to read backyoffset- bottom offset of the sub-region to read backwidth- width of the sub-region to read backheight- height of the sub-region to read backbuffer- client-side buffer where the read-back will be writtenThe following format are always supported:
Texture.Format.RGBATexture.Format.RGBA_INTEGERThe following types are always supported:
Texture.Type.UBYTETexture.Type.UINTTexture.Type.INTTexture.Type.FLOATOther combination of format/type may be supported. If a combination is not supported, this operation may fail silently. Use a DEBUG build to get some logs about the failure.
- Throws:
java.nio.BufferOverflowException- if the specified parameters would result in reading outside ofbuffer.
-
getUserTime
public double getUserTime()
Returns a timestamp (in seconds) for the last call tobeginFrame(com.google.android.filament.SwapChain, long). This value is constant for allviewsrendered during a frame. The epoch is set withresetUserTime().
In materials, this value can be queried using
vec4 getUserTime(). The value returned is ahighp vec4encoded as follows:time.x = (float)Renderer.getUserTime(); time.y = Renderer.getUserTime() - time.x;It follows that the following invariants are true:(double)time.x + (double)time.y == Renderer.getUserTime() time.x == (float)Renderer.getUserTime()This encoding allows the shader code to perform high precision (i.e. double) time calculations when needed despite the lack of double precision in the shader, e.g.:
To compute(double)time * vertexin the material, use the following construct:vec3 result = time.x * vertex + time.y * vertex;Most of the time, high precision computations are not required, but be aware that the precision oftime.xrapidly diminishes as time passes:time precision 16.7s us 4h39.7s ms 77h 1/60s In other words, it is only possible to get microsecond accuracy for about 16s or millisecond accuracy for just under 5h. This problem can be mitigated by calling
resetUserTime(), or using high precision time as described above.- Returns:
- the time in seconds since
resetUserTime()was last called - See Also:
resetUserTime()
-
resetUserTime
public void resetUserTime()
Sets the user time epoch to now, i.e. resets the user time to zero.
Use this method used to keep the precision of time high in materials, in practice it should be called at least when the application is paused, e.g.
Activity.onPausein Android.- See Also:
getUserTime()
-
getNativeObject
public long getNativeObject()
-
-