Merge "Fix matrix mapping of negative rects" into nyc-dev

This commit is contained in:
Chris Craik
2016-02-29 22:02:23 +00:00
committed by Android (Google) Code Review
7 changed files with 63 additions and 2 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View 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.";
}

View File

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