Merge "CanvasState frame init refactor"
This commit is contained in:
@@ -34,12 +34,17 @@ CanvasState::CanvasState(CanvasStateClient& renderer)
|
||||
|
||||
}
|
||||
|
||||
CanvasState::~CanvasState() {
|
||||
|
||||
}
|
||||
|
||||
void CanvasState::initializeSaveStack(float clipLeft, float clipTop,
|
||||
void CanvasState::initializeSaveStack(
|
||||
int viewportWidth, int viewportHeight,
|
||||
float clipLeft, float clipTop,
|
||||
float clipRight, float clipBottom, const Vector3& lightCenter) {
|
||||
if (mWidth != viewportWidth || mHeight != viewportHeight) {
|
||||
mWidth = viewportWidth;
|
||||
mHeight = viewportHeight;
|
||||
mFirstSnapshot->initializeViewport(viewportWidth, viewportHeight);
|
||||
mCanvas.onViewportInitialized();
|
||||
}
|
||||
|
||||
mSnapshot = new Snapshot(mFirstSnapshot,
|
||||
SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
|
||||
mSnapshot->setClip(clipLeft, clipTop, clipRight, clipBottom);
|
||||
@@ -48,20 +53,6 @@ void CanvasState::initializeSaveStack(float clipLeft, float clipTop,
|
||||
mSaveCount = 1;
|
||||
}
|
||||
|
||||
void CanvasState::setViewport(int width, int height) {
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
mFirstSnapshot->initializeViewport(width, height);
|
||||
mCanvas.onViewportInitialized();
|
||||
|
||||
// create a temporary 1st snapshot, so old snapshots are released,
|
||||
// and viewport can be queried safely.
|
||||
// TODO: remove, combine viewport + save stack initialization
|
||||
mSnapshot = new Snapshot(mFirstSnapshot,
|
||||
SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
|
||||
mSaveCount = 1;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Save (layer)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -71,20 +71,18 @@ public:
|
||||
* (getClip/Matrix), but so that quickRejection can also be used.
|
||||
*/
|
||||
|
||||
class ANDROID_API CanvasState {
|
||||
class CanvasState {
|
||||
public:
|
||||
CanvasState(CanvasStateClient& renderer);
|
||||
~CanvasState();
|
||||
|
||||
/**
|
||||
* Initializes the first snapshot, computing the projection matrix,
|
||||
* and stores the dimensions of the render target.
|
||||
*/
|
||||
void initializeSaveStack(float clipLeft, float clipTop, float clipRight, float clipBottom,
|
||||
void initializeSaveStack(int viewportWidth, int viewportHeight,
|
||||
float clipLeft, float clipTop, float clipRight, float clipBottom,
|
||||
const Vector3& lightCenter);
|
||||
|
||||
void setViewport(int width, int height);
|
||||
|
||||
bool hasRectToRectTransform() const {
|
||||
return CC_LIKELY(currentTransform()->rectToRect());
|
||||
}
|
||||
@@ -159,16 +157,11 @@ public:
|
||||
int getHeight() const { return mHeight; }
|
||||
bool clipIsSimple() const { return currentSnapshot()->clipIsSimple(); }
|
||||
|
||||
inline const Snapshot* currentSnapshot() const {
|
||||
return mSnapshot != nullptr ? mSnapshot.get() : mFirstSnapshot.get();
|
||||
}
|
||||
inline const Snapshot* currentSnapshot() const { return mSnapshot.get(); }
|
||||
inline Snapshot* writableSnapshot() { return mSnapshot.get(); }
|
||||
inline const Snapshot* firstSnapshot() const { return mFirstSnapshot.get(); }
|
||||
|
||||
private:
|
||||
/// No default constructor - must supply a CanvasStateClient (mCanvas).
|
||||
CanvasState();
|
||||
|
||||
/// indicates that the clip has been changed since the last time it was consumed
|
||||
bool mDirtyClip;
|
||||
|
||||
|
||||
@@ -54,8 +54,8 @@ void DisplayListCanvas::reset(int width, int height) {
|
||||
"prepareDirty called a second time during a recording!");
|
||||
mDisplayListData = new DisplayListData();
|
||||
|
||||
mState.setViewport(width, height);
|
||||
mState.initializeSaveStack(0, 0, mState.getWidth(), mState.getHeight(), Vector3());
|
||||
mState.initializeSaveStack(width, height,
|
||||
0, 0, width, height, Vector3());
|
||||
|
||||
mDeferredBarrierType = kBarrier_InOrder;
|
||||
mState.setDirtyClip(false);
|
||||
|
||||
@@ -236,8 +236,7 @@ void Layer::defer(const OpenGLRenderer& rootRenderer) {
|
||||
DeferStateStruct deferredState(*deferredList, *renderer,
|
||||
RenderNode::kReplayFlag_ClipChildren);
|
||||
|
||||
renderer->setViewport(width, height);
|
||||
renderer->setupFrameState(dirtyRect.left, dirtyRect.top,
|
||||
renderer->setupFrameState(width, height, dirtyRect.left, dirtyRect.top,
|
||||
dirtyRect.right, dirtyRect.bottom, !isBlend());
|
||||
|
||||
renderNode->computeOrdering();
|
||||
@@ -258,9 +257,8 @@ void Layer::flush() {
|
||||
ATRACE_LAYER_WORK("Issue");
|
||||
renderer->startMark((renderNode.get() != nullptr) ? renderNode->getName() : "Layer");
|
||||
|
||||
renderer->setViewport(layer.getWidth(), layer.getHeight());
|
||||
renderer->prepareDirty(dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom,
|
||||
!isBlend());
|
||||
renderer->prepareDirty(layer.getWidth(), layer.getHeight(),
|
||||
dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom, !isBlend());
|
||||
|
||||
deferredList->flush(*renderer, dirtyRect);
|
||||
|
||||
@@ -277,9 +275,8 @@ void Layer::render(const OpenGLRenderer& rootRenderer) {
|
||||
ATRACE_LAYER_WORK("Direct-Issue");
|
||||
|
||||
updateLightPosFromRenderer(rootRenderer);
|
||||
renderer->setViewport(layer.getWidth(), layer.getHeight());
|
||||
renderer->prepareDirty(dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom,
|
||||
!isBlend());
|
||||
renderer->prepareDirty(layer.getWidth(), layer.getHeight(),
|
||||
dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom, !isBlend());
|
||||
|
||||
renderer->drawRenderNode(renderNode.get(), dirtyRect, RenderNode::kReplayFlag_ClipChildren);
|
||||
|
||||
|
||||
@@ -43,8 +43,8 @@ LayerRenderer::LayerRenderer(RenderState& renderState, Layer* layer)
|
||||
LayerRenderer::~LayerRenderer() {
|
||||
}
|
||||
|
||||
void LayerRenderer::prepareDirty(float left, float top, float right, float bottom,
|
||||
bool opaque) {
|
||||
void LayerRenderer::prepareDirty(int viewportWidth, int viewportHeight,
|
||||
float left, float top, float right, float bottom, bool opaque) {
|
||||
LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->getFbo());
|
||||
|
||||
mRenderState.bindFramebuffer(mLayer->getFbo());
|
||||
@@ -64,7 +64,8 @@ void LayerRenderer::prepareDirty(float left, float top, float right, float botto
|
||||
}
|
||||
mLayer->clipRect.set(dirty);
|
||||
|
||||
OpenGLRenderer::prepareDirty(dirty.left, dirty.top, dirty.right, dirty.bottom, opaque);
|
||||
OpenGLRenderer::prepareDirty(viewportWidth, viewportHeight,
|
||||
dirty.left, dirty.top, dirty.right, dirty.bottom, opaque);
|
||||
}
|
||||
|
||||
void LayerRenderer::clear(float left, float top, float right, float bottom, bool opaque) {
|
||||
@@ -430,9 +431,8 @@ bool LayerRenderer::copyLayer(RenderState& renderState, Layer* layer, SkBitmap*
|
||||
|
||||
{
|
||||
LayerRenderer renderer(renderState, layer);
|
||||
renderer.setViewport(bitmap->width(), bitmap->height());
|
||||
renderer.OpenGLRenderer::prepareDirty(0.0f, 0.0f,
|
||||
bitmap->width(), bitmap->height(), !layer->isBlend());
|
||||
renderer.OpenGLRenderer::prepareDirty(bitmap->width(), bitmap->height(),
|
||||
0.0f, 0.0f, bitmap->width(), bitmap->height(), !layer->isBlend());
|
||||
|
||||
renderState.scissor().setEnabled(false);
|
||||
renderer.translate(0.0f, bitmap->height());
|
||||
|
||||
@@ -50,8 +50,8 @@ public:
|
||||
virtual ~LayerRenderer();
|
||||
|
||||
virtual void onViewportInitialized() override { /* do nothing */ }
|
||||
virtual void prepareDirty(float left, float top, float right, float bottom,
|
||||
bool opaque) override;
|
||||
virtual void prepareDirty(int viewportWidth, int viewportHeight,
|
||||
float left, float top, float right, float bottom, bool opaque) override;
|
||||
virtual void clear(float left, float top, float right, float bottom, bool opaque) override;
|
||||
virtual bool finish() override;
|
||||
|
||||
|
||||
@@ -113,10 +113,11 @@ void OpenGLRenderer::onViewportInitialized() {
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
void OpenGLRenderer::setupFrameState(float left, float top,
|
||||
float right, float bottom, bool opaque) {
|
||||
void OpenGLRenderer::setupFrameState(int viewportWidth, int viewportHeight,
|
||||
float left, float top, float right, float bottom, bool opaque) {
|
||||
mCaches.clearGarbage();
|
||||
mState.initializeSaveStack(left, top, right, bottom, mLightCenter);
|
||||
mState.initializeSaveStack(viewportWidth, viewportHeight,
|
||||
left, top, right, bottom, mLightCenter);
|
||||
mOpaque = opaque;
|
||||
mTilingClip.set(left, top, right, bottom);
|
||||
}
|
||||
@@ -137,10 +138,10 @@ void OpenGLRenderer::startFrame() {
|
||||
mTilingClip.right, mTilingClip.bottom, mOpaque);
|
||||
}
|
||||
|
||||
void OpenGLRenderer::prepareDirty(float left, float top,
|
||||
float right, float bottom, bool opaque) {
|
||||
void OpenGLRenderer::prepareDirty(int viewportWidth, int viewportHeight,
|
||||
float left, float top, float right, float bottom, bool opaque) {
|
||||
|
||||
setupFrameState(left, top, right, bottom, opaque);
|
||||
setupFrameState(viewportWidth, viewportHeight, left, top, right, bottom, opaque);
|
||||
|
||||
// Layer renderers will start the frame immediately
|
||||
// The framebuffer renderer will first defer the display list
|
||||
|
||||
@@ -119,15 +119,6 @@ public:
|
||||
OpenGLRenderer(RenderState& renderState);
|
||||
virtual ~OpenGLRenderer();
|
||||
|
||||
/**
|
||||
* Sets the dimension of the underlying drawing surface. This method must
|
||||
* be called at least once every time the drawing surface changes size.
|
||||
*
|
||||
* @param width The width in pixels of the underlysing surface
|
||||
* @param height The height in pixels of the underlysing surface
|
||||
*/
|
||||
void setViewport(int width, int height) { mState.setViewport(width, height); }
|
||||
|
||||
void initProperties();
|
||||
void initLight(float lightRadius, uint8_t ambientShadowAlpha,
|
||||
uint8_t spotShadowAlpha);
|
||||
@@ -143,21 +134,8 @@ public:
|
||||
* and will not be cleared. If false, the target surface
|
||||
* will be cleared
|
||||
*/
|
||||
virtual void prepareDirty(float left, float top, float right, float bottom,
|
||||
bool opaque);
|
||||
|
||||
/**
|
||||
* Prepares the renderer to draw a frame. This method must be invoked
|
||||
* at the beginning of each frame. When this method is invoked, the
|
||||
* entire drawing surface is assumed to be redrawn.
|
||||
*
|
||||
* @param opaque If true, the target surface is considered opaque
|
||||
* and will not be cleared. If false, the target surface
|
||||
* will be cleared
|
||||
*/
|
||||
void prepare(bool opaque) {
|
||||
prepareDirty(0.0f, 0.0f, mState.getWidth(), mState.getHeight(), opaque);
|
||||
}
|
||||
virtual void prepareDirty(int viewportWidth, int viewportHeight,
|
||||
float left, float top, float right, float bottom, bool opaque);
|
||||
|
||||
/**
|
||||
* Indicates the end of a frame. This method must be invoked whenever
|
||||
@@ -430,7 +408,8 @@ protected:
|
||||
* Perform the setup specific to a frame. This method does not
|
||||
* issue any OpenGL commands.
|
||||
*/
|
||||
void setupFrameState(float left, float top, float right, float bottom, bool opaque);
|
||||
void setupFrameState(int viewportWidth, int viewportHeight,
|
||||
float left, float top, float right, float bottom, bool opaque);
|
||||
|
||||
/**
|
||||
* Indicates the start of rendering. This method will setup the
|
||||
|
||||
@@ -248,7 +248,7 @@ void CanvasContext::draw() {
|
||||
Frame frame = mEglManager.beginFrame(mEglSurface);
|
||||
if (frame.width() != mCanvas->getViewportWidth()
|
||||
|| frame.height() != mCanvas->getViewportHeight()) {
|
||||
mCanvas->setViewport(frame.width(), frame.height());
|
||||
// can't rely on prior content of window if viewport size changes
|
||||
dirty.setEmpty();
|
||||
} else if (mHaveNewSurface || frame.bufferAge() == 0) {
|
||||
// New surface needs a full draw
|
||||
@@ -295,8 +295,8 @@ void CanvasContext::draw() {
|
||||
mDamageHistory.next() = screenDirty;
|
||||
|
||||
mEglManager.damageFrame(frame, dirty);
|
||||
mCanvas->prepareDirty(dirty.fLeft, dirty.fTop,
|
||||
dirty.fRight, dirty.fBottom, mOpaque);
|
||||
mCanvas->prepareDirty(frame.width(), frame.height(),
|
||||
dirty.fLeft, dirty.fTop, dirty.fRight, dirty.fBottom, mOpaque);
|
||||
|
||||
Rect outBounds;
|
||||
mCanvas->drawRenderNode(mRootRenderNode.get(), outBounds);
|
||||
|
||||
@@ -47,8 +47,8 @@ static bool approxEqual(const Matrix4& a, const Matrix4& b) {
|
||||
|
||||
TEST(CanvasState, gettersAndSetters) {
|
||||
CanvasState state(sNullClient);
|
||||
state.setViewport(200, 200);
|
||||
state.initializeSaveStack(0, 0, state.getWidth(), state.getHeight(), Vector3());
|
||||
state.initializeSaveStack(200, 200,
|
||||
0, 0, 200, 200, Vector3());
|
||||
|
||||
ASSERT_EQ(state.getWidth(), 200);
|
||||
ASSERT_EQ(state.getHeight(), 200);
|
||||
@@ -65,8 +65,8 @@ TEST(CanvasState, gettersAndSetters) {
|
||||
|
||||
TEST(CanvasState, simpleClipping) {
|
||||
CanvasState state(sNullClient);
|
||||
state.setViewport(200, 200);
|
||||
state.initializeSaveStack(0, 0, state.getWidth(), state.getHeight(), Vector3());
|
||||
state.initializeSaveStack(200, 200,
|
||||
0, 0, 200, 200, Vector3());
|
||||
|
||||
state.clipRect(0, 0, 100, 100, SkRegion::kIntersect_Op);
|
||||
ASSERT_EQ(state.getRenderTargetClipBounds(), Rect(0, 0, 100, 100));
|
||||
@@ -80,8 +80,8 @@ TEST(CanvasState, simpleClipping) {
|
||||
|
||||
TEST(CanvasState, complexClipping) {
|
||||
CanvasState state(sNullClient);
|
||||
state.setViewport(200, 200);
|
||||
state.initializeSaveStack(0, 0, state.getWidth(), state.getHeight(), Vector3());
|
||||
state.initializeSaveStack(200, 200,
|
||||
0, 0, 200, 200, Vector3());
|
||||
|
||||
state.save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag);
|
||||
{
|
||||
@@ -116,8 +116,8 @@ TEST(CanvasState, complexClipping) {
|
||||
|
||||
TEST(CanvasState, saveAndRestore) {
|
||||
CanvasState state(sNullClient);
|
||||
state.setViewport(200, 200);
|
||||
state.initializeSaveStack(0, 0, state.getWidth(), state.getHeight(), Vector3());
|
||||
state.initializeSaveStack(200, 200,
|
||||
0, 0, 200, 200, Vector3());
|
||||
|
||||
state.save(SkCanvas::kClip_SaveFlag);
|
||||
{
|
||||
@@ -140,10 +140,10 @@ TEST(CanvasState, saveAndRestore) {
|
||||
|
||||
TEST(CanvasState, saveAndRestoreButNotTooMuch) {
|
||||
CanvasState state(sNullClient);
|
||||
state.setViewport(200, 200);
|
||||
state.initializeSaveStack(0, 0, state.getWidth(), state.getHeight(), Vector3());
|
||||
state.initializeSaveStack(200, 200,
|
||||
0, 0, 200, 200, Vector3());
|
||||
|
||||
state.save(SkCanvas::kMatrix_SaveFlag); // Note: clip not saved
|
||||
state.save(SkCanvas::kMatrix_SaveFlag); // NOTE: clip not saved
|
||||
{
|
||||
state.clipRect(0, 0, 10, 10, SkRegion::kIntersect_Op);
|
||||
ASSERT_EQ(state.getRenderTargetClipBounds(), Rect(0, 0, 10, 10));
|
||||
|
||||
Reference in New Issue
Block a user