1573ae01295241c156ff8548ded283d44864d22d2tomhudson/* 2573ae01295241c156ff8548ded283d44864d22d2tomhudson * Copyright 2015 Google Inc. 3573ae01295241c156ff8548ded283d44864d22d2tomhudson * 4573ae01295241c156ff8548ded283d44864d22d2tomhudson * Use of this source code is governed by a BSD-style license that can be 5573ae01295241c156ff8548ded283d44864d22d2tomhudson * found in the LICENSE file. 6573ae01295241c156ff8548ded283d44864d22d2tomhudson */ 7573ae01295241c156ff8548ded283d44864d22d2tomhudson 8573ae01295241c156ff8548ded283d44864d22d2tomhudson#include "SkHwuiRenderer.h" 9573ae01295241c156ff8548ded283d44864d22d2tomhudson 10573ae01295241c156ff8548ded283d44864d22d2tomhudson#include "AnimationContext.h" 11573ae01295241c156ff8548ded283d44864d22d2tomhudson#include "IContextFactory.h" 12573ae01295241c156ff8548ded283d44864d22d2tomhudson#include "SkBitmap.h" 13573ae01295241c156ff8548ded283d44864d22d2tomhudson#include "gui/BufferQueue.h" 14573ae01295241c156ff8548ded283d44864d22d2tomhudson 15573ae01295241c156ff8548ded283d44864d22d2tomhudsonnamespace { 16573ae01295241c156ff8548ded283d44864d22d2tomhudson 17573ae01295241c156ff8548ded283d44864d22d2tomhudson/** 18573ae01295241c156ff8548ded283d44864d22d2tomhudson * Helper class for setting up android::uirenderer::renderthread::RenderProxy. 19573ae01295241c156ff8548ded283d44864d22d2tomhudson */ 20573ae01295241c156ff8548ded283d44864d22d2tomhudsonclass ContextFactory : public android::uirenderer::IContextFactory { 21573ae01295241c156ff8548ded283d44864d22d2tomhudsonpublic: 22573ae01295241c156ff8548ded283d44864d22d2tomhudson android::uirenderer::AnimationContext* createAnimationContext 23573ae01295241c156ff8548ded283d44864d22d2tomhudson (android::uirenderer::renderthread::TimeLord& clock) override { 24573ae01295241c156ff8548ded283d44864d22d2tomhudson return new android::uirenderer::AnimationContext(clock); 25573ae01295241c156ff8548ded283d44864d22d2tomhudson } 26573ae01295241c156ff8548ded283d44864d22d2tomhudson}; 27573ae01295241c156ff8548ded283d44864d22d2tomhudson 28573ae01295241c156ff8548ded283d44864d22d2tomhudson} 29573ae01295241c156ff8548ded283d44864d22d2tomhudson 30573ae01295241c156ff8548ded283d44864d22d2tomhudsonvoid SkHwuiRenderer::initialize(SkISize size) { 31573ae01295241c156ff8548ded283d44864d22d2tomhudson this->size = size; 32573ae01295241c156ff8548ded283d44864d22d2tomhudson android::BufferQueue::createBufferQueue(&this->producer, &this->consumer); 33573ae01295241c156ff8548ded283d44864d22d2tomhudson this->cpuConsumer = new android::CpuConsumer(this->consumer, 1); 34573ae01295241c156ff8548ded283d44864d22d2tomhudson this->cpuConsumer->setName(android::String8("SkiaBenchmarkClient")); 35573ae01295241c156ff8548ded283d44864d22d2tomhudson this->cpuConsumer->setDefaultBufferSize(size.width(), size.height()); 36573ae01295241c156ff8548ded283d44864d22d2tomhudson this->androidSurface = new android::Surface(this->producer); 37573ae01295241c156ff8548ded283d44864d22d2tomhudson native_window_set_buffers_dimensions(this->androidSurface.get(), 38573ae01295241c156ff8548ded283d44864d22d2tomhudson size.width(), size.height()); 39573ae01295241c156ff8548ded283d44864d22d2tomhudson native_window_set_buffers_format(this->androidSurface.get(), 40573ae01295241c156ff8548ded283d44864d22d2tomhudson android::PIXEL_FORMAT_RGBA_8888); 41573ae01295241c156ff8548ded283d44864d22d2tomhudson native_window_set_usage(this->androidSurface.get(), GRALLOC_USAGE_SW_READ_OFTEN | 42573ae01295241c156ff8548ded283d44864d22d2tomhudson GRALLOC_USAGE_SW_WRITE_NEVER | 43573ae01295241c156ff8548ded283d44864d22d2tomhudson GRALLOC_USAGE_HW_RENDER); 44573ae01295241c156ff8548ded283d44864d22d2tomhudson this->rootNode.reset(new android::uirenderer::RenderNode()); 45573ae01295241c156ff8548ded283d44864d22d2tomhudson this->rootNode->incStrong(nullptr); 46573ae01295241c156ff8548ded283d44864d22d2tomhudson this->rootNode->mutateStagingProperties().setLeftTopRightBottom 47573ae01295241c156ff8548ded283d44864d22d2tomhudson (0, 0, size.width(), size.height()); 48573ae01295241c156ff8548ded283d44864d22d2tomhudson this->rootNode->mutateStagingProperties().setClipToBounds(false); 49573ae01295241c156ff8548ded283d44864d22d2tomhudson this->rootNode->setPropertyFieldsDirty(android::uirenderer::RenderNode::GENERIC); 50573ae01295241c156ff8548ded283d44864d22d2tomhudson ContextFactory factory; 51573ae01295241c156ff8548ded283d44864d22d2tomhudson this->proxy.reset 52573ae01295241c156ff8548ded283d44864d22d2tomhudson (new android::uirenderer::renderthread::RenderProxy(false, this->rootNode, &factory)); 53573ae01295241c156ff8548ded283d44864d22d2tomhudson this->proxy->loadSystemProperties(); 54573ae01295241c156ff8548ded283d44864d22d2tomhudson this->proxy->initialize(this->androidSurface.get()); 55573ae01295241c156ff8548ded283d44864d22d2tomhudson float lightX = size.width() / 2.0f; 56573ae01295241c156ff8548ded283d44864d22d2tomhudson android::uirenderer::Vector3 lightVector { lightX, -200.0f, 800.0f }; 57c8cae184262251418ca3f8a70952805980121d0cDerek Sollenberger this->proxy->setup(size.width(), size.height(), 800.0f, 58573ae01295241c156ff8548ded283d44864d22d2tomhudson 255 * 0.075f, 255 * 0.15f); 59c8cae184262251418ca3f8a70952805980121d0cDerek Sollenberger this->proxy->setLightCenter(lightVector); 60d7c677104a6847ca59d36a1103d57478399209cctomhudson this->canvas.reset(new android::uirenderer::DisplayListCanvas()); 61d7c677104a6847ca59d36a1103d57478399209cctomhudson this->canvas->setViewport(size.width(), size.height()); 62573ae01295241c156ff8548ded283d44864d22d2tomhudson} 63573ae01295241c156ff8548ded283d44864d22d2tomhudson 64573ae01295241c156ff8548ded283d44864d22d2tomhudsonSkCanvas* SkHwuiRenderer::prepareToDraw() { 65d7c677104a6847ca59d36a1103d57478399209cctomhudson this->canvas->prepare(); 66d7c677104a6847ca59d36a1103d57478399209cctomhudson this->canvas->clipRect(0, 0, this->size.width(), this->size.height(), 67d7c677104a6847ca59d36a1103d57478399209cctomhudson SkRegion::Op::kReplace_Op); 68d7c677104a6847ca59d36a1103d57478399209cctomhudson return this->canvas->asSkCanvas(); 69573ae01295241c156ff8548ded283d44864d22d2tomhudson} 70573ae01295241c156ff8548ded283d44864d22d2tomhudson 71573ae01295241c156ff8548ded283d44864d22d2tomhudsonvoid SkHwuiRenderer::finishDrawing() { 72d7c677104a6847ca59d36a1103d57478399209cctomhudson this->canvas->finish(); 73d7c677104a6847ca59d36a1103d57478399209cctomhudson this->rootNode->setStagingDisplayList(this->canvas->finishRecording()); 74573ae01295241c156ff8548ded283d44864d22d2tomhudson this->proxy->syncAndDrawFrame(); 75573ae01295241c156ff8548ded283d44864d22d2tomhudson // Surprisingly, calling this->proxy->fence() here appears to make no difference to 76573ae01295241c156ff8548ded283d44864d22d2tomhudson // the timings we record. 77573ae01295241c156ff8548ded283d44864d22d2tomhudson} 78573ae01295241c156ff8548ded283d44864d22d2tomhudson 79573ae01295241c156ff8548ded283d44864d22d2tomhudsonbool SkHwuiRenderer::capturePixels(SkBitmap* bmp) { 80573ae01295241c156ff8548ded283d44864d22d2tomhudson SkImageInfo destinationConfig = 81573ae01295241c156ff8548ded283d44864d22d2tomhudson SkImageInfo::Make(this->size.width(), this->size.height(), 82573ae01295241c156ff8548ded283d44864d22d2tomhudson kRGBA_8888_SkColorType, kPremul_SkAlphaType); 83573ae01295241c156ff8548ded283d44864d22d2tomhudson bmp->allocPixels(destinationConfig); 84573ae01295241c156ff8548ded283d44864d22d2tomhudson sk_memset32((uint32_t*) bmp->getPixels(), SK_ColorRED, 85573ae01295241c156ff8548ded283d44864d22d2tomhudson this->size.width() * this->size.height()); 86573ae01295241c156ff8548ded283d44864d22d2tomhudson 87573ae01295241c156ff8548ded283d44864d22d2tomhudson android::CpuConsumer::LockedBuffer nativeBuffer; 88573ae01295241c156ff8548ded283d44864d22d2tomhudson android::status_t retval = this->cpuConsumer->lockNextBuffer(&nativeBuffer); 89573ae01295241c156ff8548ded283d44864d22d2tomhudson if (retval == android::BAD_VALUE) { 90573ae01295241c156ff8548ded283d44864d22d2tomhudson SkDebugf("write_canvas_png() got no buffer; returning transparent"); 91573ae01295241c156ff8548ded283d44864d22d2tomhudson // No buffer ready to read - commonly triggered by dm sending us 92573ae01295241c156ff8548ded283d44864d22d2tomhudson // a no-op source, or calling code that doesn't do anything on this 93573ae01295241c156ff8548ded283d44864d22d2tomhudson // backend. 94573ae01295241c156ff8548ded283d44864d22d2tomhudson bmp->eraseColor(SK_ColorTRANSPARENT); 95573ae01295241c156ff8548ded283d44864d22d2tomhudson return false; 96573ae01295241c156ff8548ded283d44864d22d2tomhudson } else if (retval) { 97573ae01295241c156ff8548ded283d44864d22d2tomhudson SkDebugf("Failed to lock buffer to read pixels: %d.", retval); 98573ae01295241c156ff8548ded283d44864d22d2tomhudson return false; 99573ae01295241c156ff8548ded283d44864d22d2tomhudson } 100573ae01295241c156ff8548ded283d44864d22d2tomhudson 101573ae01295241c156ff8548ded283d44864d22d2tomhudson // Move the pixels into the destination SkBitmap 102573ae01295241c156ff8548ded283d44864d22d2tomhudson 103573ae01295241c156ff8548ded283d44864d22d2tomhudson SK_ALWAYSBREAK(nativeBuffer.format == android::PIXEL_FORMAT_RGBA_8888 && 104573ae01295241c156ff8548ded283d44864d22d2tomhudson "Native buffer not RGBA!"); 105573ae01295241c156ff8548ded283d44864d22d2tomhudson SkImageInfo nativeConfig = 106573ae01295241c156ff8548ded283d44864d22d2tomhudson SkImageInfo::Make(nativeBuffer.width, nativeBuffer.height, 107573ae01295241c156ff8548ded283d44864d22d2tomhudson kRGBA_8888_SkColorType, kPremul_SkAlphaType); 108573ae01295241c156ff8548ded283d44864d22d2tomhudson 109573ae01295241c156ff8548ded283d44864d22d2tomhudson // Android stride is in pixels, Skia stride is in bytes 110573ae01295241c156ff8548ded283d44864d22d2tomhudson SkBitmap nativeWrapper; 111573ae01295241c156ff8548ded283d44864d22d2tomhudson bool success = 112573ae01295241c156ff8548ded283d44864d22d2tomhudson nativeWrapper.installPixels(nativeConfig, nativeBuffer.data, nativeBuffer.stride * 4); 113573ae01295241c156ff8548ded283d44864d22d2tomhudson if (!success) { 114573ae01295241c156ff8548ded283d44864d22d2tomhudson SkDebugf("Failed to wrap HWUI buffer in a SkBitmap"); 115573ae01295241c156ff8548ded283d44864d22d2tomhudson return false; 116573ae01295241c156ff8548ded283d44864d22d2tomhudson } 117573ae01295241c156ff8548ded283d44864d22d2tomhudson 118573ae01295241c156ff8548ded283d44864d22d2tomhudson SK_ALWAYSBREAK(bmp->colorType() == kRGBA_8888_SkColorType && 119573ae01295241c156ff8548ded283d44864d22d2tomhudson "Destination buffer not RGBA!"); 120573ae01295241c156ff8548ded283d44864d22d2tomhudson success = 121573ae01295241c156ff8548ded283d44864d22d2tomhudson nativeWrapper.readPixels(destinationConfig, bmp->getPixels(), bmp->rowBytes(), 0, 0); 122573ae01295241c156ff8548ded283d44864d22d2tomhudson if (!success) { 123573ae01295241c156ff8548ded283d44864d22d2tomhudson SkDebugf("Failed to extract pixels from HWUI buffer"); 124573ae01295241c156ff8548ded283d44864d22d2tomhudson return false; 125573ae01295241c156ff8548ded283d44864d22d2tomhudson } 126573ae01295241c156ff8548ded283d44864d22d2tomhudson 127573ae01295241c156ff8548ded283d44864d22d2tomhudson this->cpuConsumer->unlockBuffer(nativeBuffer); 128573ae01295241c156ff8548ded283d44864d22d2tomhudson 129573ae01295241c156ff8548ded283d44864d22d2tomhudson return true; 130573ae01295241c156ff8548ded283d44864d22d2tomhudson} 131573ae01295241c156ff8548ded283d44864d22d2tomhudson 132