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 |