BakedOpState.cpp revision b87eadda1818034ce03d85f30388384d1ac65916
1e4db79de127cfe961195f52907af8451026eaa20Chris Craik/* 2e4db79de127cfe961195f52907af8451026eaa20Chris Craik * Copyright (C) 2015 The Android Open Source Project 3e4db79de127cfe961195f52907af8451026eaa20Chris Craik * 4e4db79de127cfe961195f52907af8451026eaa20Chris Craik * Licensed under the Apache License, Version 2.0 (the "License"); 5e4db79de127cfe961195f52907af8451026eaa20Chris Craik * you may not use this file except in compliance with the License. 6e4db79de127cfe961195f52907af8451026eaa20Chris Craik * You may obtain a copy of the License at 7e4db79de127cfe961195f52907af8451026eaa20Chris Craik * 8e4db79de127cfe961195f52907af8451026eaa20Chris Craik * http://www.apache.org/licenses/LICENSE-2.0 9e4db79de127cfe961195f52907af8451026eaa20Chris Craik * 10e4db79de127cfe961195f52907af8451026eaa20Chris Craik * Unless required by applicable law or agreed to in writing, software 11e4db79de127cfe961195f52907af8451026eaa20Chris Craik * distributed under the License is distributed on an "AS IS" BASIS, 12e4db79de127cfe961195f52907af8451026eaa20Chris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e4db79de127cfe961195f52907af8451026eaa20Chris Craik * See the License for the specific language governing permissions and 14e4db79de127cfe961195f52907af8451026eaa20Chris Craik * limitations under the License. 15e4db79de127cfe961195f52907af8451026eaa20Chris Craik */ 16e4db79de127cfe961195f52907af8451026eaa20Chris Craik 17e4db79de127cfe961195f52907af8451026eaa20Chris Craik#include "BakedOpState.h" 18e4db79de127cfe961195f52907af8451026eaa20Chris Craik 19e4db79de127cfe961195f52907af8451026eaa20Chris Craik#include "ClipArea.h" 20e4db79de127cfe961195f52907af8451026eaa20Chris Craik 21e4db79de127cfe961195f52907af8451026eaa20Chris Craiknamespace android { 22e4db79de127cfe961195f52907af8451026eaa20Chris Craiknamespace uirenderer { 23e4db79de127cfe961195f52907af8451026eaa20Chris Craik 24e4db79de127cfe961195f52907af8451026eaa20Chris CraikResolvedRenderState::ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot, 25e4db79de127cfe961195f52907af8451026eaa20Chris Craik const RecordedOp& recordedOp, bool expandForStroke) { 26e4db79de127cfe961195f52907af8451026eaa20Chris Craik // resolvedMatrix = parentMatrix * localMatrix 27e4db79de127cfe961195f52907af8451026eaa20Chris Craik transform.loadMultiply(*snapshot.transform, recordedOp.localMatrix); 28e4db79de127cfe961195f52907af8451026eaa20Chris Craik 29e4db79de127cfe961195f52907af8451026eaa20Chris Craik // resolvedClippedBounds = intersect(resolvedMatrix * opBounds, resolvedClipRect) 30e4db79de127cfe961195f52907af8451026eaa20Chris Craik clippedBounds = recordedOp.unmappedBounds; 31e4db79de127cfe961195f52907af8451026eaa20Chris Craik if (CC_UNLIKELY(expandForStroke)) { 32e4db79de127cfe961195f52907af8451026eaa20Chris Craik // account for non-hairline stroke 33e4db79de127cfe961195f52907af8451026eaa20Chris Craik clippedBounds.outset(recordedOp.paint->getStrokeWidth() * 0.5f); 34e4db79de127cfe961195f52907af8451026eaa20Chris Craik } 35e4db79de127cfe961195f52907af8451026eaa20Chris Craik transform.mapRect(clippedBounds); 36e4db79de127cfe961195f52907af8451026eaa20Chris Craik if (CC_UNLIKELY(expandForStroke 37e4db79de127cfe961195f52907af8451026eaa20Chris Craik && (!transform.isPureTranslate() || recordedOp.paint->getStrokeWidth() < 1.0f))) { 38e4db79de127cfe961195f52907af8451026eaa20Chris Craik // account for hairline stroke when stroke may be < 1 scaled pixel 39e4db79de127cfe961195f52907af8451026eaa20Chris Craik // Non translate || strokeWidth < 1 is conservative, but will cover all cases 40e4db79de127cfe961195f52907af8451026eaa20Chris Craik clippedBounds.outset(0.5f); 41e4db79de127cfe961195f52907af8451026eaa20Chris Craik } 42e4db79de127cfe961195f52907af8451026eaa20Chris Craik 43e4db79de127cfe961195f52907af8451026eaa20Chris Craik // resolvedClipRect = intersect(parentMatrix * localClip, parentClip) 44e4db79de127cfe961195f52907af8451026eaa20Chris Craik clipState = snapshot.mutateClipArea().serializeIntersectedClip(allocator, 45e4db79de127cfe961195f52907af8451026eaa20Chris Craik recordedOp.localClip, *(snapshot.transform)); 46e4db79de127cfe961195f52907af8451026eaa20Chris Craik LOG_ALWAYS_FATAL_IF(!clipState, "must clip!"); 47e4db79de127cfe961195f52907af8451026eaa20Chris Craik 48e4db79de127cfe961195f52907af8451026eaa20Chris Craik const Rect& clipRect = clipState->rect; 49e4db79de127cfe961195f52907af8451026eaa20Chris Craik if (CC_UNLIKELY(clipRect.isEmpty() || !clippedBounds.intersects(clipRect))) { 50e4db79de127cfe961195f52907af8451026eaa20Chris Craik // Rejected based on either empty clip, or bounds not intersecting with clip 51e4db79de127cfe961195f52907af8451026eaa20Chris Craik if (clipState) { 52e4db79de127cfe961195f52907af8451026eaa20Chris Craik allocator.rewindIfLastAlloc(clipState); 53e4db79de127cfe961195f52907af8451026eaa20Chris Craik clipState = nullptr; 54e4db79de127cfe961195f52907af8451026eaa20Chris Craik } 55e4db79de127cfe961195f52907af8451026eaa20Chris Craik clippedBounds.setEmpty(); 56e4db79de127cfe961195f52907af8451026eaa20Chris Craik } else { 57e4db79de127cfe961195f52907af8451026eaa20Chris Craik // Not rejected! compute true clippedBounds and clipSideFlags 58e4db79de127cfe961195f52907af8451026eaa20Chris Craik if (clipRect.left > clippedBounds.left) clipSideFlags |= OpClipSideFlags::Left; 59e4db79de127cfe961195f52907af8451026eaa20Chris Craik if (clipRect.top > clippedBounds.top) clipSideFlags |= OpClipSideFlags::Top; 60e4db79de127cfe961195f52907af8451026eaa20Chris Craik if (clipRect.right < clippedBounds.right) clipSideFlags |= OpClipSideFlags::Right; 61e4db79de127cfe961195f52907af8451026eaa20Chris Craik if (clipRect.bottom < clippedBounds.bottom) clipSideFlags |= OpClipSideFlags::Bottom; 62e4db79de127cfe961195f52907af8451026eaa20Chris Craik clippedBounds.doIntersect(clipRect); 63e4db79de127cfe961195f52907af8451026eaa20Chris Craik } 64e4db79de127cfe961195f52907af8451026eaa20Chris Craik} 65e4db79de127cfe961195f52907af8451026eaa20Chris Craik 66e4db79de127cfe961195f52907af8451026eaa20Chris CraikResolvedRenderState::ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot) { 67e4db79de127cfe961195f52907af8451026eaa20Chris Craik transform = *snapshot.transform; 68e4db79de127cfe961195f52907af8451026eaa20Chris Craik 69e4db79de127cfe961195f52907af8451026eaa20Chris Craik // Since the op doesn't have known bounds, we conservatively set the mapped bounds 70e4db79de127cfe961195f52907af8451026eaa20Chris Craik // to the current clipRect, and clipSideFlags to Full. 71e4db79de127cfe961195f52907af8451026eaa20Chris Craik clipState = snapshot.mutateClipArea().serializeClip(allocator); 72e4db79de127cfe961195f52907af8451026eaa20Chris Craik LOG_ALWAYS_FATAL_IF(!clipState, "clipState required"); 73e4db79de127cfe961195f52907af8451026eaa20Chris Craik clippedBounds = clipState->rect; 74e4db79de127cfe961195f52907af8451026eaa20Chris Craik transform.mapRect(clippedBounds); 75e4db79de127cfe961195f52907af8451026eaa20Chris Craik clipSideFlags = OpClipSideFlags::Full; 76e4db79de127cfe961195f52907af8451026eaa20Chris Craik} 77e4db79de127cfe961195f52907af8451026eaa20Chris Craik 78b87eadda1818034ce03d85f30388384d1ac65916Chris CraikResolvedRenderState::ResolvedRenderState(const Rect& dstRect) 79b87eadda1818034ce03d85f30388384d1ac65916Chris Craik : transform(Matrix4::identity()) 80b87eadda1818034ce03d85f30388384d1ac65916Chris Craik , clipState(nullptr) 81b87eadda1818034ce03d85f30388384d1ac65916Chris Craik , clippedBounds(dstRect) 82b87eadda1818034ce03d85f30388384d1ac65916Chris Craik , clipSideFlags(OpClipSideFlags::None) {} 83b87eadda1818034ce03d85f30388384d1ac65916Chris Craik 84e4db79de127cfe961195f52907af8451026eaa20Chris Craik} // namespace uirenderer 85e4db79de127cfe961195f52907af8451026eaa20Chris Craik} // namespace android 86