RecordingCanvas.cpp revision aed7f58fb05a25ce2112829e77c0eb5dd268e8a7
1b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik/* 2b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Copyright (C) 2015 The Android Open Source Project 3b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * 4b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Licensed under the Apache License, Version 2.0 (the "License"); 5b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * you may not use this file except in compliance with the License. 6b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * You may obtain a copy of the License at 7b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * 8b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * http://www.apache.org/licenses/LICENSE-2.0 9b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * 10b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Unless required by applicable law or agreed to in writing, software 11b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * distributed under the License is distributed on an "AS IS" BASIS, 12b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * See the License for the specific language governing permissions and 14b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * limitations under the License. 15b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik */ 16b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 17b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include "RecordingCanvas.h" 18b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 19d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik#include "DeferredLayerUpdater.h" 20b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include "RecordedOp.h" 21b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include "RenderNode.h" 22766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu#include "VectorDrawable.h" 23afc221499d943386256feb9db46c119ff834bf79Yuqian Li#include "hwui/MinikinUtils.h" 24aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv#include "hwui/Bitmap.h" 25b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 26b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craiknamespace android { 27b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craiknamespace uirenderer { 28b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 29b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris CraikRecordingCanvas::RecordingCanvas(size_t width, size_t height) 30b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik : mState(*this) 31b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik , mResourceCache(ResourceCache::getInstance()) { 326f485569fa3d6047dcffd068aebf361e3598783cDerek Sollenberger resetRecording(width, height); 33b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 34b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 35b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris CraikRecordingCanvas::~RecordingCanvas() { 36003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik LOG_ALWAYS_FATAL_IF(mDisplayList, 37b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik "Destroyed a RecordingCanvas during a record!"); 38b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 39b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 40c0e7a90f1f5f98e85dbeda021fac0dff79725933Stan Ilievvoid RecordingCanvas::resetRecording(int width, int height, RenderNode* node) { 41003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik LOG_ALWAYS_FATAL_IF(mDisplayList, 42b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik "prepareDirty called a second time during a recording!"); 43003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik mDisplayList = new DisplayList(); 44b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 45e4db79de127cfe961195f52907af8451026eaa20Chris Craik mState.initializeRecordingSaveStack(width, height); 46b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 47161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik mDeferredBarrierType = DeferredBarrierType::InOrder; 48b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 49b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 50003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris CraikDisplayList* RecordingCanvas::finishRecording() { 51b87eadda1818034ce03d85f30388384d1ac65916Chris Craik restoreToCount(1); 52b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik mPaintMap.clear(); 53b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik mRegionMap.clear(); 54b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik mPathMap.clear(); 55003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik DisplayList* displayList = mDisplayList; 56003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik mDisplayList = nullptr; 57b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik mSkiaCanvasProxy.reset(nullptr); 58003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik return displayList; 59b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 60b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 61d645640180c25c2711e99aa82ec629155f8e91baChris Craikvoid RecordingCanvas::insertReorderBarrier(bool enableReorder) { 62d645640180c25c2711e99aa82ec629155f8e91baChris Craik if (enableReorder) { 63d645640180c25c2711e99aa82ec629155f8e91baChris Craik mDeferredBarrierType = DeferredBarrierType::OutOfOrder; 64d645640180c25c2711e99aa82ec629155f8e91baChris Craik mDeferredBarrierClip = getRecordedClip(); 65d645640180c25c2711e99aa82ec629155f8e91baChris Craik } else { 66d645640180c25c2711e99aa82ec629155f8e91baChris Craik mDeferredBarrierType = DeferredBarrierType::InOrder; 67d645640180c25c2711e99aa82ec629155f8e91baChris Craik mDeferredBarrierClip = nullptr; 68d645640180c25c2711e99aa82ec629155f8e91baChris Craik } 69d645640180c25c2711e99aa82ec629155f8e91baChris Craik} 70d645640180c25c2711e99aa82ec629155f8e91baChris Craik 71b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris CraikSkCanvas* RecordingCanvas::asSkCanvas() { 72003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik LOG_ALWAYS_FATAL_IF(!mDisplayList, 73b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik "attempting to get an SkCanvas when we are not recording!"); 74b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (!mSkiaCanvasProxy) { 75b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik mSkiaCanvasProxy.reset(new SkiaCanvasProxy(this)); 76b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 77b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 78b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik // SkCanvas instances default to identity transform, but should inherit 79b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik // the state of this Canvas; if this code was in the SkiaCanvasProxy 80b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik // constructor, we couldn't cache mSkiaCanvasProxy. 81b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik SkMatrix parentTransform; 82b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik getMatrix(&parentTransform); 83b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik mSkiaCanvasProxy.get()->setMatrix(parentTransform); 84b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 85b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return mSkiaCanvasProxy.get(); 86b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 87b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 88b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik// ---------------------------------------------------------------------------- 896fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik// CanvasStateClient implementation 906fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik// ---------------------------------------------------------------------------- 916fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 926fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craikvoid RecordingCanvas::onViewportInitialized() { 936fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik} 946fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 956fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craikvoid RecordingCanvas::onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) { 966fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik if (removed.flags & Snapshot::kFlagIsFboLayer) { 977df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck addOp(alloc().create_trivial<EndLayerOp>()); 98b87eadda1818034ce03d85f30388384d1ac65916Chris Craik } else if (removed.flags & Snapshot::kFlagIsLayer) { 997df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck addOp(alloc().create_trivial<EndUnclippedLayerOp>()); 1006fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik } 1016fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik} 1026fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 1036fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik// ---------------------------------------------------------------------------- 104b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik// android/graphics/Canvas state operations 105b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik// ---------------------------------------------------------------------------- 106b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik// Save (layer) 107eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malitaint RecordingCanvas::save(SaveFlags::Flags flags) { 108b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return mState.save((int) flags); 109b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 110b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 111b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikvoid RecordingCanvas::RecordingCanvas::restore() { 112b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik mState.restore(); 113b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 114b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 115b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikvoid RecordingCanvas::restoreToCount(int saveCount) { 116b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik mState.restoreToCount(saveCount); 117b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 118b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 119b87eadda1818034ce03d85f30388384d1ac65916Chris Craikint RecordingCanvas::saveLayer(float left, float top, float right, float bottom, 120eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita const SkPaint* paint, SaveFlags::Flags flags) { 1216fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik // force matrix/clip isolation for layer 122eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita flags |= SaveFlags::MatrixClip; 123eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita bool clippedLayer = flags & SaveFlags::ClipToLayer; 1246fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 1256fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik const Snapshot& previous = *mState.currentSnapshot(); 1266fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 1276fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik // initialize the snapshot as though it almost represents an FBO layer so deferred draw 1286fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik // operations will be able to store and restore the current clip and transform info, and 1296fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik // quick rejection will be correct (for display lists) 1306fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 131e4f6d968f51ba3bb867e8e124dca97b7e9c3fea5Chris Craik Rect unmappedBounds(left, top, right, bottom); 132e4f6d968f51ba3bb867e8e124dca97b7e9c3fea5Chris Craik unmappedBounds.roundOut(); 1336fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 1346fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik // determine clipped bounds relative to previous viewport. 135b87eadda1818034ce03d85f30388384d1ac65916Chris Craik Rect visibleBounds = unmappedBounds; 1366fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik previous.transform->mapRect(visibleBounds); 1376fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 138b87eadda1818034ce03d85f30388384d1ac65916Chris Craik if (CC_UNLIKELY(!clippedLayer 139b87eadda1818034ce03d85f30388384d1ac65916Chris Craik && previous.transform->rectToRect() 140b87eadda1818034ce03d85f30388384d1ac65916Chris Craik && visibleBounds.contains(previous.getRenderTargetClip()))) { 141b87eadda1818034ce03d85f30388384d1ac65916Chris Craik // unlikely case where an unclipped savelayer is recorded with a clip it can use, 142b87eadda1818034ce03d85f30388384d1ac65916Chris Craik // as none of its unaffected/unclipped area is visible 143b87eadda1818034ce03d85f30388384d1ac65916Chris Craik clippedLayer = true; 144eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita flags |= SaveFlags::ClipToLayer; 145b87eadda1818034ce03d85f30388384d1ac65916Chris Craik } 1466fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 1476fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik visibleBounds.doIntersect(previous.getRenderTargetClip()); 1486fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik visibleBounds.snapToPixelBoundaries(); 149b87eadda1818034ce03d85f30388384d1ac65916Chris Craik visibleBounds.doIntersect(Rect(previous.getViewportWidth(), previous.getViewportHeight())); 1506fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 1516fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik // Map visible bounds back to layer space, and intersect with parameter bounds 1526fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik Rect layerBounds = visibleBounds; 1533c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik if (CC_LIKELY(!layerBounds.isEmpty())) { 1543c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik // if non-empty, can safely map by the inverse transform 1553c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik Matrix4 inverse; 1563c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik inverse.loadInverse(*previous.transform); 1573c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik inverse.mapRect(layerBounds); 1583c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik layerBounds.doIntersect(unmappedBounds); 1593c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik } 1606fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 1616fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik int saveValue = mState.save((int) flags); 1626fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik Snapshot& snapshot = *mState.writableSnapshot(); 1636fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 164b87eadda1818034ce03d85f30388384d1ac65916Chris Craik // layerBounds is in original bounds space, but clipped by current recording clip 1653c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik if (!layerBounds.isEmpty() && !unmappedBounds.isEmpty()) { 166b87eadda1818034ce03d85f30388384d1ac65916Chris Craik if (CC_LIKELY(clippedLayer)) { 1673c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik auto previousClip = getRecordedClip(); // capture before new snapshot clip has changed 1683c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik if (addOp(alloc().create_trivial<BeginLayerOp>( 1693c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik unmappedBounds, 1703c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik *previous.transform, // transform to *draw* with 1713c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik previousClip, // clip to *draw* with 1723c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik refPaint(paint))) >= 0) { 1733c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik snapshot.flags |= Snapshot::kFlagIsLayer | Snapshot::kFlagIsFboLayer; 1743c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik snapshot.initializeViewport(unmappedBounds.getWidth(), unmappedBounds.getHeight()); 1753c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik snapshot.transform->loadTranslate(-unmappedBounds.left, -unmappedBounds.top, 0.0f); 1763c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik 1773c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik Rect clip = layerBounds; 1783c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik clip.translate(-unmappedBounds.left, -unmappedBounds.top); 1793c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik snapshot.resetClip(clip.left, clip.top, clip.right, clip.bottom); 1803c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik snapshot.roundRectClipState = nullptr; 1813c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik return saveValue; 1823c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik } 1833c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik } else { 1843c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik if (addOp(alloc().create_trivial<BeginUnclippedLayerOp>( 1853c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik unmappedBounds, 1863c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik *mState.currentSnapshot()->transform, 1873c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik getRecordedClip(), 1883c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik refPaint(paint))) >= 0) { 1893c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik snapshot.flags |= Snapshot::kFlagIsLayer; 1903c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik return saveValue; 1913c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik } 192b87eadda1818034ce03d85f30388384d1ac65916Chris Craik } 1936fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik } 1946fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 1953c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik // Layer not needed, so skip recording it... 196b87eadda1818034ce03d85f30388384d1ac65916Chris Craik if (CC_LIKELY(clippedLayer)) { 1973c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik // ... and set empty clip to reject inner content, if possible 1983c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craik snapshot.resetClip(0, 0, 0, 0); 199b87eadda1818034ce03d85f30388384d1ac65916Chris Craik } 2006fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik return saveValue; 201b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 202b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 203b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik// Matrix 204b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikvoid RecordingCanvas::rotate(float degrees) { 205b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (degrees == 0) return; 206b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 207b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik mState.rotate(degrees); 208b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 209b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 210b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikvoid RecordingCanvas::scale(float sx, float sy) { 211b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (sx == 1 && sy == 1) return; 212b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 213b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik mState.scale(sx, sy); 214b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 215b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 216b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikvoid RecordingCanvas::skew(float sx, float sy) { 217b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik mState.skew(sx, sy); 218b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 219b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 220b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikvoid RecordingCanvas::translate(float dx, float dy) { 221b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (dx == 0 && dy == 0) return; 222b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 223b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik mState.translate(dx, dy, 0); 224b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 225b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 226b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik// Clip 227b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikbool RecordingCanvas::getClipBounds(SkRect* outRect) const { 228e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik *outRect = mState.getLocalClipBounds().toSkRect(); 229b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return !(outRect->isEmpty()); 230b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 231b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikbool RecordingCanvas::quickRejectRect(float left, float top, float right, float bottom) const { 232b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return mState.quickRejectConservative(left, top, right, bottom); 233b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 234b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikbool RecordingCanvas::quickRejectPath(const SkPath& path) const { 235b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik SkRect bounds = path.getBounds(); 236b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return mState.quickRejectConservative(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom); 237b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 238b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikbool RecordingCanvas::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) { 239b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return mState.clipRect(left, top, right, bottom, op); 240b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 241b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikbool RecordingCanvas::clipPath(const SkPath* path, SkRegion::Op op) { 242b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return mState.clipPath(path, op); 243b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 244b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikbool RecordingCanvas::clipRegion(const SkRegion* region, SkRegion::Op op) { 245b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return mState.clipRegion(region, op); 246b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 247b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 248b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik// ---------------------------------------------------------------------------- 249b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik// android/graphics/Canvas draw operations 250b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik// ---------------------------------------------------------------------------- 251260ab726486317496bc12a57d599ea96dcde3284Mike Reedvoid RecordingCanvas::drawColor(int color, SkBlendMode mode) { 252a204848b1dc63877a12e2d24108e9d8e1e691e28Chris Craik addOp(alloc().create_trivial<ColorOp>( 253a204848b1dc63877a12e2d24108e9d8e1e691e28Chris Craik getRecordedClip(), 254a204848b1dc63877a12e2d24108e9d8e1e691e28Chris Craik color, 255a204848b1dc63877a12e2d24108e9d8e1e691e28Chris Craik mode)); 256b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 257b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 258b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikvoid RecordingCanvas::drawPaint(const SkPaint& paint) { 2594c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik SkRect bounds; 2604c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik if (getClipBounds(&bounds)) { 2614c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik drawRect(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, paint); 2624c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik } 263b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 264b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 265386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craikstatic Rect calcBoundsOfPoints(const float* points, int floatCount) { 266386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik Rect unmappedBounds(points[0], points[1], points[0], points[1]); 267386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik for (int i = 2; i < floatCount; i += 2) { 268386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik unmappedBounds.expandToCover(points[i], points[i + 1]); 269386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik } 270386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik return unmappedBounds; 271386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik} 272386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik 273b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik// Geometry 274386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craikvoid RecordingCanvas::drawPoints(const float* points, int floatCount, const SkPaint& paint) { 275814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik if (CC_UNLIKELY(floatCount < 2 || PaintUtils::paintWillNotDraw(paint))) return; 276386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik floatCount &= ~0x1; // round down to nearest two 277386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik 2787df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck addOp(alloc().create_trivial<PointsOp>( 279386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik calcBoundsOfPoints(points, floatCount), 280386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik *mState.currentSnapshot()->transform, 281e4db79de127cfe961195f52907af8451026eaa20Chris Craik getRecordedClip(), 282386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik refPaint(&paint), refBuffer<float>(points, floatCount), floatCount)); 283b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 284a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik 285a1717271caac5e8ea3808c331d4141ac01a42134Chris Craikvoid RecordingCanvas::drawLines(const float* points, int floatCount, const SkPaint& paint) { 286814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik if (CC_UNLIKELY(floatCount < 4 || PaintUtils::paintWillNotDraw(paint))) return; 287a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik floatCount &= ~0x3; // round down to nearest four 288a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik 2897df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck addOp(alloc().create_trivial<LinesOp>( 290386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik calcBoundsOfPoints(points, floatCount), 291a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik *mState.currentSnapshot()->transform, 292e4db79de127cfe961195f52907af8451026eaa20Chris Craik getRecordedClip(), 293a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik refPaint(&paint), refBuffer<float>(points, floatCount), floatCount)); 294b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 295a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik 296b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikvoid RecordingCanvas::drawRect(float left, float top, float right, float bottom, const SkPaint& paint) { 297814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; 298814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik 2997df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck addOp(alloc().create_trivial<RectOp>( 300b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik Rect(left, top, right, bottom), 301b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik *(mState.currentSnapshot()->transform), 302e4db79de127cfe961195f52907af8451026eaa20Chris Craik getRecordedClip(), 303b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik refPaint(&paint))); 304b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 305b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 306b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikvoid RecordingCanvas::drawSimpleRects(const float* rects, int vertexCount, const SkPaint* paint) { 307b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (rects == nullptr) return; 308b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 3097a89600bac7ab889a5ba8a994c57d677de0e45d5Chris Craik Vertex* rectData = (Vertex*) mDisplayList->allocator.create_trivial_array<Vertex>(vertexCount); 310b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik Vertex* vertex = rectData; 311b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 312b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik float left = FLT_MAX; 313b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik float top = FLT_MAX; 314b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik float right = FLT_MIN; 315b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik float bottom = FLT_MIN; 316b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik for (int index = 0; index < vertexCount; index += 4) { 317b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik float l = rects[index + 0]; 318b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik float t = rects[index + 1]; 319b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik float r = rects[index + 2]; 320b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik float b = rects[index + 3]; 321b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 322b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik Vertex::set(vertex++, l, t); 323b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik Vertex::set(vertex++, r, t); 324b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik Vertex::set(vertex++, l, b); 325b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik Vertex::set(vertex++, r, b); 326b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 327b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik left = std::min(left, l); 328b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik top = std::min(top, t); 329b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik right = std::max(right, r); 330b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik bottom = std::max(bottom, b); 331b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 3327df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck addOp(alloc().create_trivial<SimpleRectsOp>( 333b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik Rect(left, top, right, bottom), 334b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik *(mState.currentSnapshot()->transform), 335e4db79de127cfe961195f52907af8451026eaa20Chris Craik getRecordedClip(), 336b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik refPaint(paint), rectData, vertexCount)); 337b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 338b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 339b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikvoid RecordingCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) { 340814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; 341814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik 342b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (paint.getStyle() == SkPaint::kFill_Style 343b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik && (!paint.isAntiAlias() || mState.currentTransform()->isSimple())) { 344b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik int count = 0; 345b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik Vector<float> rects; 346b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik SkRegion::Iterator it(region); 347b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik while (!it.done()) { 348b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik const SkIRect& r = it.rect(); 349b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik rects.push(r.fLeft); 350b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik rects.push(r.fTop); 351b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik rects.push(r.fRight); 352b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik rects.push(r.fBottom); 353b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik count += 4; 354b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik it.next(); 355b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 356b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik drawSimpleRects(rects.array(), count, &paint); 357b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } else { 358b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik SkRegion::Iterator it(region); 359b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik while (!it.done()) { 360b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik const SkIRect& r = it.rect(); 361b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik drawRect(r.fLeft, r.fTop, r.fRight, r.fBottom, paint); 362b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik it.next(); 363b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 364b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 365b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 366814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik 367b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikvoid RecordingCanvas::drawRoundRect(float left, float top, float right, float bottom, 368b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik float rx, float ry, const SkPaint& paint) { 369814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; 370814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik 3712dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik if (CC_LIKELY(MathUtils::isPositive(rx) || MathUtils::isPositive(ry))) { 3722dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik addOp(alloc().create_trivial<RoundRectOp>( 3732dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik Rect(left, top, right, bottom), 3742dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik *(mState.currentSnapshot()->transform), 3752dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik getRecordedClip(), 3762dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik refPaint(&paint), rx, ry)); 3772dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik } else { 3782dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik drawRect(left, top, right, bottom, paint); 3792dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik } 380b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 381386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik 382268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craikvoid RecordingCanvas::drawRoundRect( 383268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top, 384268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom, 385268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry, 386268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik CanvasPropertyPaint* paint) { 387268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik mDisplayList->ref(left); 388268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik mDisplayList->ref(top); 389268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik mDisplayList->ref(right); 390268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik mDisplayList->ref(bottom); 391268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik mDisplayList->ref(rx); 392268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik mDisplayList->ref(ry); 393268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik mDisplayList->ref(paint); 394268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik refBitmapsInShader(paint->value.getShader()); 3957df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck addOp(alloc().create_trivial<RoundRectPropsOp>( 396268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik *(mState.currentSnapshot()->transform), 397e4db79de127cfe961195f52907af8451026eaa20Chris Craik getRecordedClip(), 398268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik &paint->value, 399268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik &left->value, &top->value, &right->value, &bottom->value, 400268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik &rx->value, &ry->value)); 401268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik} 402268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik 403b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikvoid RecordingCanvas::drawCircle(float x, float y, float radius, const SkPaint& paint) { 404268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik // TODO: move to Canvas.h 405814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik if (CC_UNLIKELY(radius <= 0 || PaintUtils::paintWillNotDraw(paint))) return; 406814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik 407386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik drawOval(x - radius, y - radius, x + radius, y + radius, paint); 408b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 409386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik 410268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craikvoid RecordingCanvas::drawCircle( 411268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y, 412268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) { 413268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik mDisplayList->ref(x); 414268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik mDisplayList->ref(y); 415268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik mDisplayList->ref(radius); 416268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik mDisplayList->ref(paint); 417268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik refBitmapsInShader(paint->value.getShader()); 4187df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck addOp(alloc().create_trivial<CirclePropsOp>( 419268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik *(mState.currentSnapshot()->transform), 420e4db79de127cfe961195f52907af8451026eaa20Chris Craik getRecordedClip(), 421268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik &paint->value, 422268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik &x->value, &y->value, &radius->value)); 423268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik} 424268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik 425b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikvoid RecordingCanvas::drawOval(float left, float top, float right, float bottom, const SkPaint& paint) { 426814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; 427814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik 4287df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck addOp(alloc().create_trivial<OvalOp>( 429386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik Rect(left, top, right, bottom), 430386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik *(mState.currentSnapshot()->transform), 431e4db79de127cfe961195f52907af8451026eaa20Chris Craik getRecordedClip(), 432386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik refPaint(&paint))); 433b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 434386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik 435b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikvoid RecordingCanvas::drawArc(float left, float top, float right, float bottom, 436386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) { 437814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; 438814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik 439caa24184735a607e87077c73262a42acdea7b8fbChris Craik if (fabs(sweepAngle) >= 360.0f) { 440caa24184735a607e87077c73262a42acdea7b8fbChris Craik drawOval(left, top, right, bottom, paint); 441caa24184735a607e87077c73262a42acdea7b8fbChris Craik } else { 442caa24184735a607e87077c73262a42acdea7b8fbChris Craik addOp(alloc().create_trivial<ArcOp>( 443caa24184735a607e87077c73262a42acdea7b8fbChris Craik Rect(left, top, right, bottom), 444caa24184735a607e87077c73262a42acdea7b8fbChris Craik *(mState.currentSnapshot()->transform), 445caa24184735a607e87077c73262a42acdea7b8fbChris Craik getRecordedClip(), 446caa24184735a607e87077c73262a42acdea7b8fbChris Craik refPaint(&paint), 447caa24184735a607e87077c73262a42acdea7b8fbChris Craik startAngle, sweepAngle, useCenter)); 448caa24184735a607e87077c73262a42acdea7b8fbChris Craik } 449b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 450386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik 451b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikvoid RecordingCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 452814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik if (CC_UNLIKELY(PaintUtils::paintWillNotDraw(paint))) return; 453814ee6a9218aa339a4757b2c0ba1ad268f8dbc8aChris Craik 4547df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck addOp(alloc().create_trivial<PathOp>( 455386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik Rect(path.getBounds()), 456386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik *(mState.currentSnapshot()->transform), 457e4db79de127cfe961195f52907af8451026eaa20Chris Craik getRecordedClip(), 458386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik refPaint(&paint), refPath(&path))); 459b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 460b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 461766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liuvoid RecordingCanvas::drawVectorDrawable(VectorDrawableRoot* tree) { 462766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu mDisplayList->ref(tree); 463718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liu mDisplayList->vectorDrawables.push_back(tree); 4647df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck addOp(alloc().create_trivial<VectorDrawableOp>( 465766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu tree, 4661d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu Rect(tree->stagingProperties()->getBounds()), 467766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu *(mState.currentSnapshot()->transform), 468766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu getRecordedClip())); 469766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu} 470766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu 471b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik// Bitmap-based 472aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyvvoid RecordingCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) { 473aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv SkBitmap skBitmap; 474aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv bitmap.getSkBitmap(&skBitmap); 475eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita save(SaveFlags::Matrix); 476b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik translate(left, top); 477aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv drawBitmap(&skBitmap, paint); 478b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik restore(); 479b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 480b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 481b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikvoid RecordingCanvas::drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix, 482b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik const SkPaint* paint) { 483b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (matrix.isIdentity()) { 484b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik drawBitmap(&bitmap, paint); 485b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } else if (!(matrix.getType() & ~(SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask)) 486b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik && MathUtils::isPositive(matrix.getScaleX()) 487b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik && MathUtils::isPositive(matrix.getScaleY())) { 488b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik // SkMatrix::isScaleTranslate() not available in L 489b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik SkRect src; 490b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik SkRect dst; 491b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik bitmap.getBounds(&src); 492b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik matrix.mapRect(&dst, src); 493b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik drawBitmap(bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom, 494b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, paint); 495b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } else { 496eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita save(SaveFlags::Matrix); 497b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik concat(matrix); 498b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik drawBitmap(&bitmap, paint); 499b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik restore(); 500b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 501b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 502386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik 503b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikvoid RecordingCanvas::drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop, 504b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik float srcRight, float srcBottom, float dstLeft, float dstTop, 505b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik float dstRight, float dstBottom, const SkPaint* paint) { 506b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (srcLeft == 0 && srcTop == 0 507b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik && srcRight == bitmap.width() 508b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik && srcBottom == bitmap.height() 509b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik && (srcBottom - srcTop == dstBottom - dstTop) 510b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik && (srcRight - srcLeft == dstRight - dstLeft)) { 511b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik // transform simple rect to rect drawing case into position bitmap ops, since they merge 512eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita save(SaveFlags::Matrix); 513b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik translate(dstLeft, dstTop); 514b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik drawBitmap(&bitmap, paint); 515b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik restore(); 516b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } else { 5177df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck addOp(alloc().create_trivial<BitmapRectOp>( 518f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik Rect(dstLeft, dstTop, dstRight, dstBottom), 519f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik *(mState.currentSnapshot()->transform), 520e4db79de127cfe961195f52907af8451026eaa20Chris Craik getRecordedClip(), 521f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik refPaint(paint), refBitmap(bitmap), 522f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik Rect(srcLeft, srcTop, srcRight, srcBottom))); 523b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 524b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 525386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik 526b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikvoid RecordingCanvas::drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight, 527b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik const float* vertices, const int* colors, const SkPaint* paint) { 528f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik int vertexCount = (meshWidth + 1) * (meshHeight + 1); 5297df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck addOp(alloc().create_trivial<BitmapMeshOp>( 530f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik calcBoundsOfPoints(vertices, vertexCount * 2), 531f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik *(mState.currentSnapshot()->transform), 532e4db79de127cfe961195f52907af8451026eaa20Chris Craik getRecordedClip(), 533f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik refPaint(paint), refBitmap(bitmap), meshWidth, meshHeight, 534f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik refBuffer<float>(vertices, vertexCount * 2), // 2 floats per vertex 535f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik refBuffer<int>(colors, vertexCount))); // 1 color per vertex 536b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 537386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik 538f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craikvoid RecordingCanvas::drawNinePatch(const SkBitmap& bitmap, const android::Res_png_9patch& patch, 539b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik float dstLeft, float dstTop, float dstRight, float dstBottom, 540b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik const SkPaint* paint) { 5417df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck addOp(alloc().create_trivial<PatchOp>( 542f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik Rect(dstLeft, dstTop, dstRight, dstBottom), 543f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik *(mState.currentSnapshot()->transform), 544e4db79de127cfe961195f52907af8451026eaa20Chris Craik getRecordedClip(), 545f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik refPaint(paint), refBitmap(bitmap), refPatch(&patch))); 546b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 547b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 548b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik// Text 549dccca44ffda4836b56a21da95a046c9708ffd49csergeyvvoid RecordingCanvas::drawGlyphs(const uint16_t* glyphs, const float* positions, int glyphCount, 550b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop, 551b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik float boundsRight, float boundsBottom, float totalAdvance) { 552a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik if (!glyphs || !positions || glyphCount <= 0 || PaintUtils::paintWillNotDrawText(paint)) return; 553a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik glyphs = refBuffer<glyph_t>(glyphs, glyphCount); 554a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik positions = refBuffer<float>(positions, glyphCount * 2); 555a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik 55615c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik // TODO: either must account for text shadow in bounds, or record separate ops for text shadows 5577df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck addOp(alloc().create_trivial<TextOp>( 558a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik Rect(boundsLeft, boundsTop, boundsRight, boundsBottom), 559a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik *(mState.currentSnapshot()->transform), 560e4db79de127cfe961195f52907af8451026eaa20Chris Craik getRecordedClip(), 561a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik refPaint(&paint), glyphs, positions, glyphCount, x, y)); 562a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik drawTextDecorations(x, y, totalAdvance, paint); 563b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 564a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik 565afc221499d943386256feb9db46c119ff834bf79Yuqian Livoid RecordingCanvas::drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset, 566afc221499d943386256feb9db46c119ff834bf79Yuqian Li const SkPaint& paint, const SkPath& path, size_t start, size_t end) { 567afc221499d943386256feb9db46c119ff834bf79Yuqian Li uint16_t glyphs[1]; 568afc221499d943386256feb9db46c119ff834bf79Yuqian Li for (size_t i = start; i < end; i++) { 569afc221499d943386256feb9db46c119ff834bf79Yuqian Li glyphs[0] = layout.getGlyphId(i); 570afc221499d943386256feb9db46c119ff834bf79Yuqian Li float x = hOffset + layout.getX(i); 571afc221499d943386256feb9db46c119ff834bf79Yuqian Li float y = vOffset + layout.getY(i); 572afc221499d943386256feb9db46c119ff834bf79Yuqian Li if (PaintUtils::paintWillNotDrawText(paint)) return; 573afc221499d943386256feb9db46c119ff834bf79Yuqian Li const uint16_t* tempGlyphs = refBuffer<glyph_t>(glyphs, 1); 574afc221499d943386256feb9db46c119ff834bf79Yuqian Li addOp(alloc().create_trivial<TextOnPathOp>( 575afc221499d943386256feb9db46c119ff834bf79Yuqian Li *(mState.currentSnapshot()->transform), 576afc221499d943386256feb9db46c119ff834bf79Yuqian Li getRecordedClip(), 577afc221499d943386256feb9db46c119ff834bf79Yuqian Li refPaint(&paint), tempGlyphs, 1, refPath(&path), x, y)); 578afc221499d943386256feb9db46c119ff834bf79Yuqian Li } 579b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 580b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 581b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikvoid RecordingCanvas::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) { 5827df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck addOp(alloc().create_trivial<BitmapOp>( 5835430ab220b231a96b71c3e030d0303d9ce008b05Chris Craik Rect(bitmap->width(), bitmap->height()), 584b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik *(mState.currentSnapshot()->transform), 585e4db79de127cfe961195f52907af8451026eaa20Chris Craik getRecordedClip(), 586b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik refPaint(paint), refBitmap(*bitmap))); 587b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 588e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik 589b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikvoid RecordingCanvas::drawRenderNode(RenderNode* renderNode) { 59054fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik auto&& stagingProps = renderNode->stagingProperties(); 5917df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck RenderNodeOp* op = alloc().create_trivial<RenderNodeOp>( 59254fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik Rect(stagingProps.getWidth(), stagingProps.getHeight()), 593b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik *(mState.currentSnapshot()->transform), 594e4db79de127cfe961195f52907af8451026eaa20Chris Craik getRecordedClip(), 595b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik renderNode); 596b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik int opIndex = addOp(op); 5971367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik if (CC_LIKELY(opIndex >= 0)) { 5981367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik int childIndex = mDisplayList->addChild(op); 599b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 6001367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik // update the chunk's child indices 6011367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik DisplayList::Chunk& chunk = mDisplayList->chunks.back(); 6021367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik chunk.endChildIndex = childIndex + 1; 603b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 6041367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik if (renderNode->stagingProperties().isProjectionReceiver()) { 6051367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik // use staging property, since recording on UI thread 6061367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik mDisplayList->projectionReceiveIndex = opIndex; 6071367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik } 608b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 609b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 610b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 611d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craikvoid RecordingCanvas::drawLayer(DeferredLayerUpdater* layerHandle) { 612d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik // We ref the DeferredLayerUpdater due to its thread-safe ref-counting semantics. 613d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik mDisplayList->ref(layerHandle); 614d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik 615417ed6d4337e5409d52f58cc93677c8715193f32John Reck // Note that the backing layer has *not* yet been updated, so don't trust 616417ed6d4337e5409d52f58cc93677c8715193f32John Reck // its width, height, transform, etc...! 6177df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck addOp(alloc().create_trivial<TextureLayerOp>( 618417ed6d4337e5409d52f58cc93677c8715193f32John Reck Rect(layerHandle->getWidth(), layerHandle->getHeight()), 619aafb01d8ade0def3f51b74ae3bbc610c4ab33044Chris Craik *(mState.currentSnapshot()->transform), 620e4db79de127cfe961195f52907af8451026eaa20Chris Craik getRecordedClip(), 621417ed6d4337e5409d52f58cc93677c8715193f32John Reck layerHandle->backingLayer())); 622d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik} 623d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik 624cd1c3eba69d044b551cededad75474038f919890John Reckvoid RecordingCanvas::callDrawGLFunction(Functor* functor, 625cd1c3eba69d044b551cededad75474038f919890John Reck GlFunctorLifecycleListener* listener) { 626cd1c3eba69d044b551cededad75474038f919890John Reck mDisplayList->functors.push_back({functor, listener}); 627cd1c3eba69d044b551cededad75474038f919890John Reck mDisplayList->ref(listener); 6287df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck addOp(alloc().create_trivial<FunctorOp>( 629e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik *(mState.currentSnapshot()->transform), 6304c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik getRecordedClip(), 631e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik functor)); 632e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik} 633e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik 6343c53ec51efd4bbc3f06cc63dd8efe186e3fb168fChris Craikint RecordingCanvas::addOp(RecordedOp* op) { 635261725fdb2962271c222a049fcdf57bbdc8363c7Chris Craik // skip op with empty clip 636261725fdb2962271c222a049fcdf57bbdc8363c7Chris Craik if (op->localClip && op->localClip->rect.isEmpty()) { 637261725fdb2962271c222a049fcdf57bbdc8363c7Chris Craik // NOTE: this rejection happens after op construction/content ref-ing, so content ref'd 638261725fdb2962271c222a049fcdf57bbdc8363c7Chris Craik // and held by renderthread isn't affected by clip rejection. 639261725fdb2962271c222a049fcdf57bbdc8363c7Chris Craik // Could rewind alloc here if desired, but callers would have to not touch op afterwards. 640261725fdb2962271c222a049fcdf57bbdc8363c7Chris Craik return -1; 641261725fdb2962271c222a049fcdf57bbdc8363c7Chris Craik } 642261725fdb2962271c222a049fcdf57bbdc8363c7Chris Craik 643003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik int insertIndex = mDisplayList->ops.size(); 644003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik mDisplayList->ops.push_back(op); 645161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik if (mDeferredBarrierType != DeferredBarrierType::None) { 646b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik // op is first in new chunk 647003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik mDisplayList->chunks.emplace_back(); 648003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik DisplayList::Chunk& newChunk = mDisplayList->chunks.back(); 649b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik newChunk.beginOpIndex = insertIndex; 650b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik newChunk.endOpIndex = insertIndex + 1; 651161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik newChunk.reorderChildren = (mDeferredBarrierType == DeferredBarrierType::OutOfOrder); 652d645640180c25c2711e99aa82ec629155f8e91baChris Craik newChunk.reorderClip = mDeferredBarrierClip; 653b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 654b36af87f8275f4b982906f88193ec27600f2746aChris Craik int nextChildIndex = mDisplayList->children.size(); 655b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik newChunk.beginChildIndex = newChunk.endChildIndex = nextChildIndex; 656161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik mDeferredBarrierType = DeferredBarrierType::None; 657b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } else { 658b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik // standard case - append to existing chunk 659003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik mDisplayList->chunks.back().endOpIndex = insertIndex + 1; 660b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 661b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return insertIndex; 662b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 663b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 664b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikvoid RecordingCanvas::refBitmapsInShader(const SkShader* shader) { 665b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (!shader) return; 666b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 667b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik // If this paint has an SkShader that has an SkBitmap add 668b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik // it to the bitmap pile 669b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik SkBitmap bitmap; 670b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik SkShader::TileMode xy[2]; 671f35b989d26bb98900f6c5fa2e586326b30b6e161Leon Scroggins III if (shader->isABitmap(&bitmap, nullptr, xy)) { 672b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik refBitmap(bitmap); 673b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return; 674b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 675b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik SkShader::ComposeRec rec; 676b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (shader->asACompose(&rec)) { 677b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik refBitmapsInShader(rec.fShaderA); 678b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik refBitmapsInShader(rec.fShaderB); 679b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return; 680b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 681b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 682b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 683b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik}; // namespace uirenderer 684b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik}; // namespace android 685