| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "DMSrcSink.h" | 8 #include "DMSrcSink.h" |
| 9 #include "DMSrcSinkAndroid.h" | 9 #include "DMSrcSinkAndroid.h" |
| 10 | 10 |
| 11 #include "AnimationContext.h" | |
| 12 #include "DisplayListRenderer.h" | |
| 13 #include "IContextFactory.h" | |
| 14 #include "RenderNode.h" | |
| 15 #include "SkAndroidSDKCanvas.h" | 11 #include "SkAndroidSDKCanvas.h" |
| 16 #include "SkCanvas.h" | 12 #include "SkCanvas.h" |
| 13 #include "SkHwuiRenderer.h" |
| 17 #include "SkiaCanvasProxy.h" | 14 #include "SkiaCanvasProxy.h" |
| 18 #include "SkTLazy.h" | |
| 19 #include "SkMaskFilter.h" | |
| 20 #include "SkPictureRecorder.h" | |
| 21 #include "SkStream.h" | 15 #include "SkStream.h" |
| 22 #include "android/rect.h" | |
| 23 #include "android/native_window.h" | |
| 24 #include "gui/BufferQueue.h" | |
| 25 #include "gui/CpuConsumer.h" | |
| 26 #include "gui/IGraphicBufferConsumer.h" | |
| 27 #include "gui/IGraphicBufferProducer.h" | |
| 28 #include "gui/Surface.h" | |
| 29 #include "renderthread/RenderProxy.h" | |
| 30 #include "renderthread/TimeLord.h" | |
| 31 | 16 |
| 32 /* These functions are only compiled in the Android Framework. */ | 17 /* These functions are only compiled in the Android Framework. */ |
| 33 | 18 |
| 34 namespace { | |
| 35 | |
| 36 /** | |
| 37 * Helper class for setting up android::uirenderer::renderthread::RenderProxy. | |
| 38 */ | |
| 39 class ContextFactory : public android::uirenderer::IContextFactory { | |
| 40 public: | |
| 41 android::uirenderer::AnimationContext* createAnimationContext | |
| 42 (android::uirenderer::renderthread::TimeLord& clock) override { | |
| 43 return new android::uirenderer::AnimationContext(clock); | |
| 44 } | |
| 45 }; | |
| 46 | |
| 47 } // namespace | |
| 48 | |
| 49 namespace DM { | 19 namespace DM { |
| 50 | 20 |
| 51 Error HWUISink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString*) const
{ | 21 Error HWUISink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString*) const
{ |
| 52 // Do all setup in this function because we don't know the size | 22 SkHwuiRenderer renderer; |
| 53 // for the RenderNode and RenderProxy during the constructor. | 23 renderer.initialize(src.size()); |
| 54 // In practice this doesn't seem too expensive. | 24 SkCanvas* canvas = renderer.prepareToDraw(); |
| 55 const SkISize size = src.size(); | 25 Error err = src.draw(canvas); |
| 56 | |
| 57 // Based on android::SurfaceTexture_init() | |
| 58 android::sp<android::IGraphicBufferProducer> producer; | |
| 59 android::sp<android::IGraphicBufferConsumer> consumer; | |
| 60 android::BufferQueue::createBufferQueue(&producer, &consumer); | |
| 61 | |
| 62 // Consumer setup | |
| 63 | |
| 64 android::sp<android::CpuConsumer> cpuConsumer = | |
| 65 new android::CpuConsumer(consumer, 1); | |
| 66 cpuConsumer->setName(android::String8("SkiaTestClient")); | |
| 67 cpuConsumer->setDefaultBufferSize(size.width(), size.height()); | |
| 68 | |
| 69 // Producer setup | |
| 70 | |
| 71 android::sp<android::Surface> surface = new android::Surface(producer); | |
| 72 native_window_set_buffers_dimensions(surface.get(), size.width(), size.heigh
t()); | |
| 73 native_window_set_buffers_format(surface.get(), android::PIXEL_FORMAT_RGBA_8
888); | |
| 74 native_window_set_usage(surface.get(), GRALLOC_USAGE_SW_READ_OFTEN | | |
| 75 GRALLOC_USAGE_SW_WRITE_NEVER | | |
| 76 GRALLOC_USAGE_HW_RENDER); | |
| 77 | |
| 78 // RenderNode setup based on hwui/tests/main.cpp:TreeContentAnimation | |
| 79 SkAutoTDelete<android::uirenderer::RenderNode> rootNode | |
| 80 (new android::uirenderer::RenderNode()); | |
| 81 rootNode->incStrong(nullptr); | |
| 82 | |
| 83 // Values set here won't be applied until the framework has called | |
| 84 // RenderNode::pushStagingPropertiesChanges() during RenderProxy::syncAndDra
wFrame(). | |
| 85 rootNode->mutateStagingProperties().setLeftTopRightBottom(0, 0, size.width()
, size.height()); | |
| 86 rootNode->setPropertyFieldsDirty(android::uirenderer::RenderNode::X | | |
| 87 android::uirenderer::RenderNode::Y); | |
| 88 rootNode->mutateStagingProperties().setClipToBounds(false); | |
| 89 rootNode->setPropertyFieldsDirty(android::uirenderer::RenderNode::GENERIC); | |
| 90 | |
| 91 // RenderProxy setup based on hwui/tests/main.cpp:TreeContentAnimation | |
| 92 ContextFactory factory; | |
| 93 SkAutoTDelete<android::uirenderer::renderthread::RenderProxy> proxy | |
| 94 (new android::uirenderer::renderthread::RenderProxy(false, rootNode, &fa
ctory)); | |
| 95 proxy->loadSystemProperties(); | |
| 96 | |
| 97 proxy->initialize(surface.get()); | |
| 98 | |
| 99 float lightX = size.width() / 2.0f; | |
| 100 android::uirenderer::Vector3 lightVector { lightX, -200.0f, 800.0f }; | |
| 101 proxy->setup(size.width(), size.height(), lightVector, 800.0f, 255 * 0.075f,
255 * 0.15f); | |
| 102 | |
| 103 // Do the draw | |
| 104 | |
| 105 SkAutoTDelete<android::uirenderer::DisplayListRenderer> renderer | |
| 106 (new android::uirenderer::DisplayListRenderer()); | |
| 107 renderer->setViewport(size.width(), size.height()); | |
| 108 renderer->prepare(); | |
| 109 renderer->clipRect(0, 0, size.width(), size.height(), SkRegion::Op::kReplace
_Op); | |
| 110 | |
| 111 Error err = src.draw(renderer->asSkCanvas()); | |
| 112 if (!err.isEmpty()) { | 26 if (!err.isEmpty()) { |
| 113 return err; | 27 return err; |
| 114 } | 28 } |
| 115 | 29 renderer.finishDrawing(); |
| 116 renderer->finish(); | 30 renderer.proxy->fence(); |
| 117 rootNode->setStagingDisplayList(renderer->finishRecording()); | 31 renderer.capturePixels(dst); |
| 118 | |
| 119 proxy->syncAndDrawFrame(); | |
| 120 proxy->fence(); | |
| 121 | |
| 122 // Capture pixels | |
| 123 | |
| 124 SkImageInfo destinationConfig = | |
| 125 SkImageInfo::Make(size.width(), size.height(), | |
| 126 kRGBA_8888_SkColorType, kPremul_SkAlphaType); | |
| 127 dst->allocPixels(destinationConfig); | |
| 128 sk_memset32((uint32_t*) dst->getPixels(), SK_ColorRED, size.width() * size.h
eight()); | |
| 129 | |
| 130 android::CpuConsumer::LockedBuffer nativeBuffer; | |
| 131 android::status_t retval = cpuConsumer->lockNextBuffer(&nativeBuffer); | |
| 132 if (retval == android::BAD_VALUE) { | |
| 133 SkDebugf("HWUISink::draw() got no buffer; returning transparent"); | |
| 134 // No buffer ready to read - commonly triggered by dm sending us | |
| 135 // a no-op source, or calling code that doesn't do anything on this | |
| 136 // backend. | |
| 137 dst->eraseColor(SK_ColorTRANSPARENT); | |
| 138 return ""; | |
| 139 } else if (retval) { | |
| 140 return SkStringPrintf("Failed to lock buffer to read pixels: %d.", retva
l); | |
| 141 } | |
| 142 | |
| 143 // Move the pixels into the destination SkBitmap | |
| 144 | |
| 145 SK_ALWAYSBREAK(nativeBuffer.format == android::PIXEL_FORMAT_RGBA_8888 && | |
| 146 "Native buffer not RGBA!"); | |
| 147 SkImageInfo nativeConfig = | |
| 148 SkImageInfo::Make(nativeBuffer.width, nativeBuffer.height, | |
| 149 kRGBA_8888_SkColorType, kPremul_SkAlphaType); | |
| 150 | |
| 151 // Android stride is in pixels, Skia stride is in bytes | |
| 152 SkBitmap nativeWrapper; | |
| 153 bool success = | |
| 154 nativeWrapper.installPixels(nativeConfig, nativeBuffer.data, nativeBuffe
r.stride * 4); | |
| 155 if (!success) { | |
| 156 return "Failed to wrap HWUI buffer in a SkBitmap"; | |
| 157 } | |
| 158 | |
| 159 SK_ALWAYSBREAK(dst->colorType() == kRGBA_8888_SkColorType && | |
| 160 "Destination buffer not RGBA!"); | |
| 161 success = | |
| 162 nativeWrapper.readPixels(destinationConfig, dst->getPixels(), dst->rowBy
tes(), 0, 0); | |
| 163 if (!success) { | |
| 164 return "Failed to extract pixels from HWUI buffer"; | |
| 165 } | |
| 166 | |
| 167 cpuConsumer->unlockBuffer(nativeBuffer); | |
| 168 return ""; | 32 return ""; |
| 169 } | 33 } |
| 170 | 34 |
| 171 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ | 35 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ |
| 172 | 36 |
| 173 ViaAndroidSDK::ViaAndroidSDK(Sink* sink) : fSink(sink) { } | 37 ViaAndroidSDK::ViaAndroidSDK(Sink* sink) : fSink(sink) { } |
| 174 | 38 |
| 175 Error ViaAndroidSDK::draw(const Src& src, | 39 Error ViaAndroidSDK::draw(const Src& src, |
| 176 SkBitmap* bitmap, | 40 SkBitmap* bitmap, |
| 177 SkWStream* stream, | 41 SkWStream* stream, |
| (...skipping 18 matching lines...) Expand all Loading... |
| 196 return ""; | 60 return ""; |
| 197 } | 61 } |
| 198 SkISize size() const override { return fSrc.size(); } | 62 SkISize size() const override { return fSrc.size(); } |
| 199 Name name() const override { sk_throw(); return ""; } | 63 Name name() const override { sk_throw(); return ""; } |
| 200 } proxy(src); | 64 } proxy(src); |
| 201 | 65 |
| 202 return fSink->draw(proxy, bitmap, stream, log); | 66 return fSink->draw(proxy, bitmap, stream, log); |
| 203 } | 67 } |
| 204 | 68 |
| 205 } // namespace DM | 69 } // namespace DM |
| OLD | NEW |