Merge "Fix matrix mapping of negative rects" into nyc-dev
This commit is contained in:
@@ -242,6 +242,7 @@ LOCAL_SRC_FILES += \
|
||||
tests/unit/GpuMemoryTrackerTests.cpp \
|
||||
tests/unit/LayerUpdateQueueTests.cpp \
|
||||
tests/unit/LinearAllocatorTests.cpp \
|
||||
tests/unit/MatrixTests.cpp \
|
||||
tests/unit/OffscreenBufferPoolTests.cpp \
|
||||
tests/unit/SkiaBehaviorTests.cpp \
|
||||
tests/unit/StringUtilsTests.cpp \
|
||||
|
||||
@@ -404,11 +404,17 @@ static bool cannotFitInRectangleList(const ClipArea& clipArea, const ClipBase* s
|
||||
return currentRectCount + recordedRectCount > RectangleList::kMaxTransformedRectangles;
|
||||
}
|
||||
|
||||
static const ClipRect sEmptyClipRect(Rect(0, 0));
|
||||
|
||||
const ClipBase* ClipArea::serializeIntersectedClip(LinearAllocator& allocator,
|
||||
const ClipBase* recordedClip, const Matrix4& recordedClipTransform) {
|
||||
|
||||
// if no recordedClip passed, just serialize current state
|
||||
if (!recordedClip) return serializeClip(allocator);
|
||||
|
||||
// if either is empty, clip is empty
|
||||
if (CC_UNLIKELY(recordedClip->rect.isEmpty())|| mClipRect.isEmpty()) return &sEmptyClipRect;
|
||||
|
||||
if (!mLastResolutionResult
|
||||
|| recordedClip != mLastResolutionClip
|
||||
|| recordedClipTransform != mLastResolutionTransform) {
|
||||
|
||||
@@ -438,7 +438,7 @@ void Matrix4::mapPoint(float& x, float& y) const {
|
||||
}
|
||||
|
||||
void Matrix4::mapRect(Rect& r) const {
|
||||
if (isIdentity()) return;
|
||||
if (isIdentity() || r.isEmpty()) return;
|
||||
|
||||
if (isSimple()) {
|
||||
MUL_ADD_STORE(r.left, data[kScaleX], data[kTranslateX]);
|
||||
|
||||
@@ -594,7 +594,14 @@ void RecordingCanvas::callDrawGLFunction(Functor* functor) {
|
||||
}
|
||||
|
||||
size_t RecordingCanvas::addOp(RecordedOp* op) {
|
||||
// TODO: validate if "addDrawOp" quickrejection logic is useful before adding
|
||||
// skip op with empty clip
|
||||
if (op->localClip && op->localClip->rect.isEmpty()) {
|
||||
// NOTE: this rejection happens after op construction/content ref-ing, so content ref'd
|
||||
// and held by renderthread isn't affected by clip rejection.
|
||||
// Could rewind alloc here if desired, but callers would have to not touch op afterwards.
|
||||
return -1;
|
||||
}
|
||||
|
||||
int insertIndex = mDisplayList->ops.size();
|
||||
mDisplayList->ops.push_back(op);
|
||||
if (mDeferredBarrierType != DeferredBarrierType::None) {
|
||||
|
||||
@@ -228,6 +228,7 @@ TEST(ClipArea, serializeIntersectedClip) {
|
||||
|
||||
ClipRegion recordedClip;
|
||||
recordedClip.region.setPath(ovalPath, SkRegion(SkIRect::MakeWH(200, 200)));
|
||||
recordedClip.rect = Rect(200, 200);
|
||||
|
||||
Matrix4 translate10x20;
|
||||
translate10x20.loadTranslate(10, 20, 0);
|
||||
|
||||
35
libs/hwui/tests/unit/MatrixTests.cpp
Normal file
35
libs/hwui/tests/unit/MatrixTests.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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 "Matrix.h"
|
||||
#include "Rect.h"
|
||||
|
||||
using namespace android::uirenderer;
|
||||
|
||||
TEST(Matrix, mapRect) {
|
||||
// Skew, so we don't hit identity/translate/simple fast paths
|
||||
Matrix4 matrix;
|
||||
matrix.skew(0.1f, 0.1f);
|
||||
|
||||
// non-zero empty rect, so sorting x/y would make rect non-empty
|
||||
Rect empty(100, 100, -100, -100);
|
||||
ASSERT_TRUE(empty.isEmpty());
|
||||
matrix.mapRect(empty);
|
||||
EXPECT_TRUE(empty.isEmpty())
|
||||
<< "Empty rect should always remain empty, regardless of mapping.";
|
||||
}
|
||||
@@ -58,6 +58,17 @@ TEST(RecordingCanvas, clipRect) {
|
||||
<< "Clip should be serialized once";
|
||||
}
|
||||
|
||||
TEST(RecordingCanvas, emptyClipRect) {
|
||||
auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
|
||||
canvas.save(SaveFlags::MatrixClip);
|
||||
canvas.clipRect(0, 0, 100, 100, SkRegion::kIntersect_Op);
|
||||
canvas.clipRect(100, 100, 200, 200, SkRegion::kIntersect_Op);
|
||||
canvas.drawRect(0, 0, 50, 50, SkPaint()); // rejected at record time
|
||||
canvas.restore();
|
||||
});
|
||||
ASSERT_EQ(0u, dl->getOps().size()) << "Must be zero ops. Rect should be rejected.";
|
||||
}
|
||||
|
||||
TEST(RecordingCanvas, drawArc) {
|
||||
auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
|
||||
canvas.drawArc(0, 0, 200, 200, 0, 180, true, SkPaint());
|
||||
|
||||
Reference in New Issue
Block a user