| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #pragma once |
| |
| #include "BakedOpState.h" |
| #include "Matrix.h" |
| #include "utils/Macros.h" |
| |
| namespace android { |
| namespace uirenderer { |
| |
| class Caches; |
| struct Glop; |
| class Layer; |
| class RenderState; |
| struct ClipBase; |
| |
| /** |
| * Main rendering manager for a collection of work - one frame + any contained FBOs. |
| * |
| * Manages frame and FBO lifecycle, binding the GL framebuffer as appropriate. This is the only |
| * place where FBOs are bound, created, and destroyed. |
| * |
| * All rendering operations will be sent by the Dispatcher, a collection of static methods, |
| * which has intentionally limited access to the renderer functionality. |
| */ |
| class BakedOpRenderer { |
| public: |
| typedef void (*GlopReceiver)(BakedOpRenderer&, const Rect*, const ClipBase*, const Glop&); |
| /** |
| * Position agnostic shadow lighting info. Used with all shadow ops in scene. |
| */ |
| struct LightInfo { |
| LightInfo() : LightInfo(0, 0) {} |
| LightInfo(uint8_t ambientShadowAlpha, |
| uint8_t spotShadowAlpha) |
| : ambientShadowAlpha(ambientShadowAlpha) |
| , spotShadowAlpha(spotShadowAlpha) {} |
| uint8_t ambientShadowAlpha; |
| uint8_t spotShadowAlpha; |
| }; |
| |
| BakedOpRenderer(Caches& caches, RenderState& renderState, bool opaque, |
| const LightInfo& lightInfo) |
| : mGlopReceiver(DefaultGlopReceiver) |
| , mRenderState(renderState) |
| , mCaches(caches) |
| , mOpaque(opaque) |
| , mLightInfo(lightInfo) { |
| } |
| |
| RenderState& renderState() { return mRenderState; } |
| Caches& caches() { return mCaches; } |
| |
| void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect); |
| void endFrame(const Rect& repaintRect); |
| WARN_UNUSED_RESULT OffscreenBuffer* startTemporaryLayer(uint32_t width, uint32_t height); |
| void recycleTemporaryLayer(OffscreenBuffer* offscreenBuffer); |
| void startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect); |
| void endLayer(); |
| WARN_UNUSED_RESULT OffscreenBuffer* copyToLayer(const Rect& area); |
| |
| Texture* getTexture(const SkBitmap* bitmap); |
| const LightInfo& getLightInfo() const { return mLightInfo; } |
| |
| void renderGlop(const BakedOpState& state, const Glop& glop) { |
| renderGlop(&state.computedState.clippedBounds, |
| state.computedState.getClipIfNeeded(), |
| glop); |
| } |
| void renderFunctor(const FunctorOp& op, const BakedOpState& state); |
| |
| void renderGlop(const Rect* dirtyBounds, const ClipBase* clip, const Glop& glop) { |
| mGlopReceiver(*this, dirtyBounds, clip, glop); |
| } |
| bool offscreenRenderTarget() { return mRenderTarget.offscreenBuffer != nullptr; } |
| void dirtyRenderTarget(const Rect& dirtyRect); |
| bool didDraw() const { return mHasDrawn; } |
| |
| uint32_t getViewportWidth() const { return mRenderTarget.viewportWidth; } |
| uint32_t getViewportHeight() const { return mRenderTarget.viewportHeight; } |
| |
| // simple draw methods, to be used for end frame decoration |
| void drawRect(float left, float top, float right, float bottom, const SkPaint* paint) { |
| float ltrb[4] = { left, top, right, bottom }; |
| drawRects(ltrb, 4, paint); |
| } |
| void drawRects(const float* rects, int count, const SkPaint* paint); |
| protected: |
| GlopReceiver mGlopReceiver; |
| private: |
| static void DefaultGlopReceiver(BakedOpRenderer& renderer, const Rect* dirtyBounds, |
| const ClipBase* clip, const Glop& glop) { |
| renderer.renderGlopImpl(dirtyBounds, clip, glop); |
| } |
| void renderGlopImpl(const Rect* dirtyBounds, const ClipBase* clip, const Glop& glop); |
| void setViewport(uint32_t width, uint32_t height); |
| void clearColorBuffer(const Rect& clearRect); |
| void prepareRender(const Rect* dirtyBounds, const ClipBase* clip); |
| void setupStencilRectList(const ClipBase* clip); |
| void setupStencilRegion(const ClipBase* clip); |
| void setupStencilQuads(std::vector<Vertex>& quadVertices, int incrementThreshold); |
| |
| RenderState& mRenderState; |
| Caches& mCaches; |
| bool mOpaque; |
| bool mHasDrawn = false; |
| |
| // render target state - setup by start/end layer/frame |
| // only valid to use in between start/end pairs. |
| struct { |
| // If not drawing to a layer: fbo = 0, offscreenBuffer = null, |
| // Otherwise these refer to currently painting layer's state |
| GLuint frameBufferId = 0; |
| OffscreenBuffer* offscreenBuffer = nullptr; |
| |
| // Used when drawing to a layer and using stencil clipping. otherwise null. |
| RenderBuffer* stencil = nullptr; |
| |
| // value representing the ClipRectList* or ClipRegion* currently stored in |
| // the stencil of the current render target |
| const ClipBase* lastStencilClip = nullptr; |
| |
| // Size of renderable region in current render target - for layers, may not match actual |
| // bounds of FBO texture. offscreenBuffer->texture has this information. |
| uint32_t viewportWidth = 0; |
| uint32_t viewportHeight = 0; |
| |
| Matrix4 orthoMatrix; |
| } mRenderTarget; |
| |
| const LightInfo mLightInfo; |
| }; |
| |
| }; // namespace uirenderer |
| }; // namespace android |