Merge "CanvasState frame init refactor"

This commit is contained in:
Chris Craik
2015-09-09 20:51:41 +00:00
committed by Android (Google) Code Review
10 changed files with 54 additions and 93 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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