1ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/* 2ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * Copyright (C) 2012 The Android Open Source Project 3ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * 4ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 5ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * you may not use this file except in compliance with the License. 6ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * You may obtain a copy of the License at 7ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * 8ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * http://www.apache.org/licenses/LICENSE-2.0 9ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * 10ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * Unless required by applicable law or agreed to in writing, software 11ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * distributed under the License is distributed on an "AS IS" BASIS, 12ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * See the License for the specific language governing permissions and 14ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * limitations under the License. 15ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy */ 16ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 17ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy#include "Snapshot.h" 18ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 19dccca44ffda4836b56a21da95a046c9708ffd49csergeyv#include "hwui/Canvas.h" 20ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 21ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guynamespace android { 22ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guynamespace uirenderer { 23ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 24ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/////////////////////////////////////////////////////////////////////////////// 25ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy// Constructors 26ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/////////////////////////////////////////////////////////////////////////////// 27ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 28e4aa95e3627226bcb0d8cc3e42dca6e4df8f421cChris CraikSnapshot::Snapshot() 29e4aa95e3627226bcb0d8cc3e42dca6e4df8f421cChris Craik : flags(0) 30d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik , previous(nullptr) 31d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik , layer(nullptr) 32e4aa95e3627226bcb0d8cc3e42dca6e4df8f421cChris Craik , fbo(0) 33e4aa95e3627226bcb0d8cc3e42dca6e4df8f421cChris Craik , invisible(false) 34e4aa95e3627226bcb0d8cc3e42dca6e4df8f421cChris Craik , empty(false) 35deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik , alpha(1.0f) 36487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk , roundRectClipState(nullptr) 37fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik , projectionPathMask(nullptr) 38487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk , mClipArea(&mClipAreaRoot) { 39ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy transform = &mTransformRoot; 40d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik region = nullptr; 41ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 42ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 43ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/** 44ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * Copies the specified snapshot/ The specified snapshot is stored as 45ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy * the previous snapshot. 46ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy */ 47d9ee550888011a64fa3f35e666360ec8278597d8John ReckSnapshot::Snapshot(Snapshot* s, int saveFlags) 48e4aa95e3627226bcb0d8cc3e42dca6e4df8f421cChris Craik : flags(0) 49e4aa95e3627226bcb0d8cc3e42dca6e4df8f421cChris Craik , previous(s) 50e4aa95e3627226bcb0d8cc3e42dca6e4df8f421cChris Craik , layer(s->layer) 51e4aa95e3627226bcb0d8cc3e42dca6e4df8f421cChris Craik , fbo(s->fbo) 52e4aa95e3627226bcb0d8cc3e42dca6e4df8f421cChris Craik , invisible(s->invisible) 53e4aa95e3627226bcb0d8cc3e42dca6e4df8f421cChris Craik , empty(false) 54a64a2bef1048db5a742843f1e3bea9e80d0defc5Chris Craik , alpha(s->alpha) 55deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik , roundRectClipState(s->roundRectClipState) 56fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik , projectionPathMask(s->projectionPathMask) 57487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk , mClipArea(nullptr) 5869e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik , mViewportData(s->mViewportData) 5969e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik , mRelativeLightCenter(s->mRelativeLightCenter) { 60eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita if (saveFlags & SaveFlags::Matrix) { 617c85c54499994c687a833644f7f213e747fadb98Chris Craik mTransformRoot = *s->transform; 62ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy transform = &mTransformRoot; 63ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy } else { 64ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy transform = s->transform; 65ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy } 66ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 67eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita if (saveFlags & SaveFlags::Clip) { 68487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk mClipAreaRoot = s->getClipArea(); 69487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk mClipArea = &mClipAreaRoot; 70ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy } else { 71487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk mClipArea = s->mClipArea; 72ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy } 73ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 74ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy if (s->flags & Snapshot::kFlagFboTarget) { 75ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy flags |= Snapshot::kFlagFboTarget; 76ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy region = s->region; 77ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy } else { 78d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik region = nullptr; 79ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy } 80ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 81ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 82ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/////////////////////////////////////////////////////////////////////////////// 83ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy// Clipping 84ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/////////////////////////////////////////////////////////////////////////////// 85ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 864d3e704b04c6abd7995df640d12662b0271f6c7bChris Craikvoid Snapshot::clipRegionTransformed(const SkRegion& region, SkRegion::Op op) { 878ce00301a023eecaeb8891ce906f67b513ebb42aRomain Guy flags |= Snapshot::kFlagClipSet; 884d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik mClipArea->clipRegion(region, op); 89967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy} 90967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy 91a2a70723b8cbda4354d23f901f995623e819012cChris Craikvoid Snapshot::clip(const Rect& localClip, SkRegion::Op op) { 92487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk flags |= Snapshot::kFlagClipSet; 93a2a70723b8cbda4354d23f901f995623e819012cChris Craik mClipArea->clipRectWithTransform(localClip, transform, op); 94ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 95ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 964d3e704b04c6abd7995df640d12662b0271f6c7bChris Craikvoid Snapshot::clipPath(const SkPath& path, SkRegion::Op op) { 97487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk flags |= Snapshot::kFlagClipSet; 984d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik mClipArea->clipPathWithTransform(path, transform, op); 99ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 100ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 101ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guyvoid Snapshot::setClip(float left, float top, float right, float bottom) { 102ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy flags |= Snapshot::kFlagClipSet; 1034d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik mClipArea->setClip(left, top, right, bottom); 104ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 105ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 106a3dc55f83ab583e0a66b893c71b849afa046770aRomain Guybool Snapshot::hasPerspectiveTransform() const { 107a3dc55f83ab583e0a66b893c71b849afa046770aRomain Guy return transform->isPerspective(); 108a3dc55f83ab583e0a66b893c71b849afa046770aRomain Guy} 109a3dc55f83ab583e0a66b893c71b849afa046770aRomain Guy 110ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guyconst Rect& Snapshot::getLocalClip() { 111ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy mat4 inverse; 112ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy inverse.loadInverse(*transform); 113ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 114487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk mLocalClip.set(mClipArea->getClipRect()); 115ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy inverse.mapRect(mLocalClip); 116ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 117ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy return mLocalClip; 118ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 119ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 120ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guyvoid Snapshot::resetClip(float left, float top, float right, float bottom) { 1213bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy // TODO: This is incorrect, when we start rendering into a new layer, 1223bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy // we may have to modify the previous snapshot's clip rect and clip 1233bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy // region if the previous restore() call did not restore the clip 124487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk mClipArea = &mClipAreaRoot; 125967e2bf3ac8943a8e8a374bf86021915445cda67Romain Guy setClip(left, top, right, bottom); 126ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 127ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 128ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/////////////////////////////////////////////////////////////////////////////// 129ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy// Transforms 130ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/////////////////////////////////////////////////////////////////////////////// 131ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 132ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guyvoid Snapshot::resetTransform(float x, float y, float z) { 13398787e6c9b2c10b1ab7820bdac168686025b924aChris Craik#if HWUI_NEW_OPS 13498787e6c9b2c10b1ab7820bdac168686025b924aChris Craik LOG_ALWAYS_FATAL("not supported - light center managed differently"); 13598787e6c9b2c10b1ab7820bdac168686025b924aChris Craik#else 13669e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik // before resetting, map current light pos with inverse of current transform 13769e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik Vector3 center = mRelativeLightCenter; 13869e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik mat4 inverse; 13969e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik inverse.loadInverse(*transform); 14069e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik inverse.mapPoint3d(center); 14169e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik mRelativeLightCenter = center; 14269e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik 143ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy transform = &mTransformRoot; 144ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy transform->loadTranslate(x, y, z); 14598787e6c9b2c10b1ab7820bdac168686025b924aChris Craik#endif 146ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 147ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 148fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craikvoid Snapshot::buildScreenSpaceTransform(Matrix4* outTransform) const { 149678ff81105753656aa4822f4f675ef96dc9d2b83Chris Craik#if HWUI_NEW_OPS 150678ff81105753656aa4822f4f675ef96dc9d2b83Chris Craik LOG_ALWAYS_FATAL("not supported - not needed by new ops"); 151678ff81105753656aa4822f4f675ef96dc9d2b83Chris Craik#else 152fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik // build (reverse ordered) list of the stack of snapshots, terminated with a NULL 153fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik Vector<const Snapshot*> snapshotList; 154fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik snapshotList.push(nullptr); 155fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik const Snapshot* current = this; 156fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik do { 157fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik snapshotList.push(current); 158d9ee550888011a64fa3f35e666360ec8278597d8John Reck current = current->previous; 159fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik } while (current); 160fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik 161fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik // traverse the list, adding in each transform that contributes to the total transform 162fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik outTransform->loadIdentity(); 163fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik for (size_t i = snapshotList.size() - 1; i > 0; i--) { 164fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik // iterate down the stack 165fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik const Snapshot* current = snapshotList[i]; 166fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik const Snapshot* next = snapshotList[i - 1]; 167fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik if (current->flags & kFlagIsFboLayer) { 168fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik // if we've hit a layer, translate by the layer's draw offset 169fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik outTransform->translate(current->layer->layer.left, current->layer->layer.top); 170fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik } 171fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik if (!next || (next->flags & kFlagIsFboLayer)) { 172fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik // if this snapshot is last, or if this snapshot is last before an 173fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik // FBO layer (which reset the transform), apply it 174fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik outTransform->multiply(*(current->transform)); 175fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik } 176fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik } 177678ff81105753656aa4822f4f675ef96dc9d2b83Chris Craik#endif 178fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik} 179fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik 180ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/////////////////////////////////////////////////////////////////////////////// 181af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik// Clipping round rect 182deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik/////////////////////////////////////////////////////////////////////////////// 183deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik 184e83cbd451868a734bfac07ccd680d5617080b579Chris Craikvoid Snapshot::setClippingRoundRect(LinearAllocator& allocator, const Rect& bounds, 185e83cbd451868a734bfac07ccd680d5617080b579Chris Craik float radius, bool highPriority) { 186af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik if (bounds.isEmpty()) { 187487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk mClipArea->setEmpty(); 188af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik return; 189af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik } 190deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik 191e83cbd451868a734bfac07ccd680d5617080b579Chris Craik if (roundRectClipState && roundRectClipState->highPriority) { 192e83cbd451868a734bfac07ccd680d5617080b579Chris Craik // ignore, don't replace, already have a high priority clip 193e83cbd451868a734bfac07ccd680d5617080b579Chris Craik return; 194e83cbd451868a734bfac07ccd680d5617080b579Chris Craik } 195e83cbd451868a734bfac07ccd680d5617080b579Chris Craik 196deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik RoundRectClipState* state = new (allocator) RoundRectClipState; 197deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik 198e83cbd451868a734bfac07ccd680d5617080b579Chris Craik state->highPriority = highPriority; 199e83cbd451868a734bfac07ccd680d5617080b579Chris Craik 200deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik // store the inverse drawing matrix 2017c85c54499994c687a833644f7f213e747fadb98Chris Craik Matrix4 roundRectDrawingMatrix = getOrthoMatrix(); 202af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik roundRectDrawingMatrix.multiply(*transform); 203af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik state->matrix.loadInverse(roundRectDrawingMatrix); 204deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik 205deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik // compute area under rounded corners - only draws overlapping these rects need to be clipped 206deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik for (int i = 0 ; i < 4; i++) { 207deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik state->dangerRects[i] = bounds; 208deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik } 209deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik state->dangerRects[0].bottom = state->dangerRects[1].bottom = bounds.top + radius; 210deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik state->dangerRects[0].right = state->dangerRects[2].right = bounds.left + radius; 211deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik state->dangerRects[1].left = state->dangerRects[3].left = bounds.right - radius; 212deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik state->dangerRects[2].top = state->dangerRects[3].top = bounds.bottom - radius; 213deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik for (int i = 0; i < 4; i++) { 214deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik transform->mapRect(state->dangerRects[i]); 215deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik 216deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik // round danger rects out as though they are AA geometry (since they essentially are) 217deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik state->dangerRects[i].snapGeometryToPixelBoundaries(true); 218deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik } 219deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik 220deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik // store RR area 221af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik state->innerRect = bounds; 222af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik state->innerRect.inset(radius); 223af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik state->radius = radius; 224deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik 225deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik // store as immutable so, for this frame, pointer uniquely identifies this bundle of shader info 226deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik roundRectClipState = state; 227deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik} 228deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik 229fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craikvoid Snapshot::setProjectionPathMask(LinearAllocator& allocator, const SkPath* path) { 230678ff81105753656aa4822f4f675ef96dc9d2b83Chris Craik#if HWUI_NEW_OPS 231678ff81105753656aa4822f4f675ef96dc9d2b83Chris Craik // TODO: remove allocator param for HWUI_NEW_OPS 232678ff81105753656aa4822f4f675ef96dc9d2b83Chris Craik projectionPathMask = path; 233678ff81105753656aa4822f4f675ef96dc9d2b83Chris Craik#else 234fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik if (path) { 235fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik ProjectionPathMask* mask = new (allocator) ProjectionPathMask; 236fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik mask->projectionMask = path; 237fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik buildScreenSpaceTransform(&(mask->projectionMaskTransform)); 238fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik projectionPathMask = mask; 239fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik } else { 240fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik projectionPathMask = nullptr; 241fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik } 242678ff81105753656aa4822f4f675ef96dc9d2b83Chris Craik#endif 243fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik} 244fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik 24504d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craikstatic Snapshot* getClipRoot(Snapshot* target) { 24604d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik while (target->previous && target->previous->previous) { 24704d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik target = target->previous; 24804d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik } 24904d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik return target; 25004d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik} 25104d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik 25204d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craikconst ClipBase* Snapshot::serializeIntersectedClip(LinearAllocator& allocator, 25304d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik const ClipBase* recordedClip, const Matrix4& recordedClipTransform) { 25404d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik auto target = this; 25504d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik if (CC_UNLIKELY(recordedClip && recordedClip->intersectWithRoot)) { 25604d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik // Clip must be intersected with root, instead of current clip. 25704d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik target = getClipRoot(this); 25804d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik } 25904d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik 26004d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik return target->mClipArea->serializeIntersectedClip(allocator, 26104d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik recordedClip, recordedClipTransform); 26204d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik} 26304d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik 26404d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craikvoid Snapshot::applyClip(const ClipBase* recordedClip, const Matrix4& transform) { 26504d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik if (CC_UNLIKELY(recordedClip && recordedClip->intersectWithRoot)) { 26604d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik // current clip is being replaced, but must intersect with clip root 26704d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik *mClipArea = *(getClipRoot(this)->mClipArea); 26804d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik } 26904d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik mClipArea->applyClip(recordedClip, transform); 27004d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik} 27104d46eb69fb4f4c4c332c36c6ae845da3b2ae848Chris Craik 272deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik/////////////////////////////////////////////////////////////////////////////// 273ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy// Queries 274ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy/////////////////////////////////////////////////////////////////////////////// 275ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 276ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guybool Snapshot::isIgnored() const { 277ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy return invisible || empty; 278ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy} 279ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy 2805f803623559aab395a29d575c37c4e39c23a4b4eChris Craikvoid Snapshot::dump() const { 2815f803623559aab395a29d575c37c4e39c23a4b4eChris Craik ALOGD("Snapshot %p, flags %x, prev %p, height %d, ignored %d, hasComplexClip %d", 282d9ee550888011a64fa3f35e666360ec8278597d8John Reck this, flags, previous, getViewportHeight(), isIgnored(), !mClipArea->isSimple()); 283487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk const Rect& clipRect(mClipArea->getClipRect()); 284e9c01a40a2f0f0da195dfbb2909aaee5c005d1c6Chris Craik ALOGD(" ClipRect %.1f %.1f %.1f %.1f, clip simple %d", 285e9c01a40a2f0f0da195dfbb2909aaee5c005d1c6Chris Craik clipRect.left, clipRect.top, clipRect.right, clipRect.bottom, mClipArea->isSimple()); 286e9c01a40a2f0f0da195dfbb2909aaee5c005d1c6Chris Craik 2875f803623559aab395a29d575c37c4e39c23a4b4eChris Craik ALOGD(" Transform (at %p):", transform); 2885f803623559aab395a29d575c37c4e39c23a4b4eChris Craik transform->dump(); 2895f803623559aab395a29d575c37c4e39c23a4b4eChris Craik} 2905f803623559aab395a29d575c37c4e39c23a4b4eChris Craik 291ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}; // namespace uirenderer 292ada4d53d50dc869b8278573ad640dc44118d3bcfRomain Guy}; // namespace android 293