Merge "Fix flickering when layers resize in-place" into nyc-dev
This commit is contained in:
@@ -255,6 +255,7 @@ LOCAL_SRC_FILES += \
|
||||
ifeq (true, $(HWUI_NEW_OPS))
|
||||
LOCAL_SRC_FILES += \
|
||||
tests/unit/BakedOpDispatcherTests.cpp \
|
||||
tests/unit/BakedOpRendererTests.cpp \
|
||||
tests/unit/BakedOpStateTests.cpp \
|
||||
tests/unit/FrameBuilderTests.cpp \
|
||||
tests/unit/LeakCheckTests.cpp \
|
||||
|
||||
@@ -40,6 +40,16 @@ OffscreenBuffer* BakedOpRenderer::startTemporaryLayer(uint32_t width, uint32_t h
|
||||
void BakedOpRenderer::startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect) {
|
||||
LOG_ALWAYS_FATAL_IF(mRenderTarget.offscreenBuffer, "already has layer...");
|
||||
|
||||
// subtract repaintRect from region, since it will be regenerated
|
||||
if (repaintRect.contains(0, 0,
|
||||
offscreenBuffer->viewportWidth, offscreenBuffer->viewportHeight)) {
|
||||
// repaint full layer, so throw away entire region
|
||||
offscreenBuffer->region.clear();
|
||||
} else {
|
||||
offscreenBuffer->region.subtractSelf(android::Rect(repaintRect.left, repaintRect.top,
|
||||
repaintRect.right, repaintRect.bottom));
|
||||
}
|
||||
|
||||
mRenderTarget.offscreenBuffer = offscreenBuffer;
|
||||
|
||||
// create and bind framebuffer
|
||||
|
||||
@@ -41,6 +41,10 @@ Rect transformAndCalculateBounds(const Rect& r, const Matrix4& transform) {
|
||||
return transformedBounds;
|
||||
}
|
||||
|
||||
void ClipBase::dump() const {
|
||||
ALOGD("mode %d" RECT_STRING, mode, RECT_ARGS(rect));
|
||||
}
|
||||
|
||||
/*
|
||||
* TransformedRectangle
|
||||
*/
|
||||
|
||||
@@ -106,6 +106,8 @@ struct ClipBase {
|
||||
// Bounds of the clipping area, used to define the scissor, and define which
|
||||
// portion of the stencil is updated/used
|
||||
Rect rect;
|
||||
|
||||
void dump() const;
|
||||
};
|
||||
|
||||
struct ClipRect : ClipBase {
|
||||
|
||||
@@ -349,8 +349,9 @@ void LayerBuilder::replayBakedOpsImpl(void* arg,
|
||||
}
|
||||
|
||||
void LayerBuilder::dump() const {
|
||||
ALOGD("LayerBuilder %p, %ux%u buffer %p, blo %p, rn %p",
|
||||
this, width, height, offscreenBuffer, beginLayerOp, renderNode);
|
||||
ALOGD("LayerBuilder %p, %ux%u buffer %p, blo %p, rn %p (%s)",
|
||||
this, width, height, offscreenBuffer, beginLayerOp,
|
||||
renderNode, renderNode ? renderNode->getName() : "-");
|
||||
for (const BatchBase* batch : mBatches) {
|
||||
batch->dump();
|
||||
}
|
||||
|
||||
@@ -133,6 +133,15 @@ void glGetIntegerv(GLenum pname, GLint *data) {
|
||||
}
|
||||
}
|
||||
|
||||
GLenum glCheckFramebufferStatus(GLenum target) {
|
||||
switch (target) {
|
||||
case GL_FRAMEBUFFER:
|
||||
return GL_FRAMEBUFFER_COMPLETE;
|
||||
default:
|
||||
return 0; // error case
|
||||
}
|
||||
}
|
||||
|
||||
const char* getString(GLenum name) {
|
||||
switch (name) {
|
||||
case GL_VENDOR:
|
||||
|
||||
@@ -164,6 +164,9 @@ OffscreenBuffer* OffscreenBufferPool::resize(OffscreenBuffer* layer,
|
||||
// resize in place
|
||||
layer->viewportWidth = width;
|
||||
layer->viewportHeight = height;
|
||||
|
||||
// entire area will be repainted (and may be smaller) so clear usage region
|
||||
layer->region.clear();
|
||||
return layer;
|
||||
}
|
||||
putOrDelete(layer);
|
||||
|
||||
54
libs/hwui/tests/unit/BakedOpRendererTests.cpp
Normal file
54
libs/hwui/tests/unit/BakedOpRendererTests.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <BakedOpRenderer.h>
|
||||
#include <tests/common/TestUtils.h>
|
||||
|
||||
using namespace android::uirenderer;
|
||||
|
||||
const BakedOpRenderer::LightInfo sLightInfo = { 128, 128 };
|
||||
|
||||
RENDERTHREAD_TEST(BakedOpRenderer, startRepaintLayer_clear) {
|
||||
BakedOpRenderer renderer(Caches::getInstance(), renderThread.renderState(), true, sLightInfo);
|
||||
OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 200u, 200u);
|
||||
|
||||
layer.dirty(Rect(200, 200));
|
||||
{
|
||||
renderer.startRepaintLayer(&layer, Rect(200, 200));
|
||||
EXPECT_TRUE(layer.region.isEmpty()) << "Repaint full layer should clear region";
|
||||
renderer.endLayer();
|
||||
}
|
||||
|
||||
layer.dirty(Rect(200, 200));
|
||||
{
|
||||
renderer.startRepaintLayer(&layer, Rect(100, 200)); // repainting left side
|
||||
EXPECT_TRUE(layer.region.isRect());
|
||||
//ALOGD("bounds %d %d %d %d", RECT_ARGS(layer.region.getBounds()));
|
||||
EXPECT_EQ(android::Rect(100, 0, 200, 200), layer.region.getBounds())
|
||||
<< "Left side being repainted, so right side should be clear";
|
||||
renderer.endLayer();
|
||||
}
|
||||
|
||||
// right side is now only dirty portion
|
||||
{
|
||||
renderer.startRepaintLayer(&layer, Rect(100, 0, 200, 200)); // repainting right side
|
||||
EXPECT_TRUE(layer.region.isEmpty())
|
||||
<< "Now right side being repainted, so region should be entirely clear";
|
||||
renderer.endLayer();
|
||||
}
|
||||
}
|
||||
@@ -103,9 +103,11 @@ TEST(OffscreenBufferPool, resize) {
|
||||
OffscreenBufferPool pool;
|
||||
|
||||
auto layer = pool.get(thread.renderState(), 64u, 64u);
|
||||
layer->dirty(Rect(64, 64));
|
||||
|
||||
// resize in place
|
||||
ASSERT_EQ(layer, pool.resize(layer, 60u, 55u));
|
||||
EXPECT_TRUE(layer->region.isEmpty()) << "In place resize should clear usage region";
|
||||
EXPECT_EQ(60u, layer->viewportWidth);
|
||||
EXPECT_EQ(55u, layer->viewportHeight);
|
||||
EXPECT_EQ(64u, layer->texture.width());
|
||||
@@ -113,9 +115,13 @@ TEST(OffscreenBufferPool, resize) {
|
||||
|
||||
// resized to use different object in pool
|
||||
auto layer2 = pool.get(thread.renderState(), 128u, 128u);
|
||||
layer2->dirty(Rect(128, 128));
|
||||
EXPECT_FALSE(layer2->region.isEmpty());
|
||||
pool.putOrDelete(layer2);
|
||||
ASSERT_EQ(1u, pool.getCount());
|
||||
|
||||
ASSERT_EQ(layer2, pool.resize(layer, 120u, 125u));
|
||||
EXPECT_TRUE(layer2->region.isEmpty()) << "Swap resize should clear usage region";
|
||||
EXPECT_EQ(120u, layer2->viewportWidth);
|
||||
EXPECT_EQ(125u, layer2->viewportHeight);
|
||||
EXPECT_EQ(128u, layer2->texture.width());
|
||||
|
||||
Reference in New Issue
Block a user