Merge "Support render-ahead in vulkan" into qt-dev

This commit is contained in:
John Reck
2019-04-15 18:20:28 +00:00
committed by Android (Google) Code Review
25 changed files with 258 additions and 262 deletions

View File

@@ -17,8 +17,8 @@
#include "Properties.h"
#include "Debug.h"
#include "DeviceInfo.h"
#include "SkTraceEventCommon.h"
#include "HWUIProperties.sysprop.h"
#include "SkTraceEventCommon.h"
#include <algorithm>
#include <cstdlib>
@@ -67,7 +67,7 @@ bool Properties::debuggingEnabled = false;
bool Properties::isolatedProcess = false;
int Properties::contextPriority = 0;
int Properties::defaultRenderAhead = 0;
uint32_t Properties::defaultRenderAhead = 0;
static int property_get_int(const char* key, int defaultValue) {
char buf[PROPERTY_VALUE_MAX] = {
@@ -130,12 +130,9 @@ bool Properties::load() {
enableForceDarkSupport = property_get_bool(PROPERTY_ENABLE_FORCE_DARK, true);
defaultRenderAhead = std::max(0, std::min(2, property_get_int(PROPERTY_RENDERAHEAD,
render_ahead().value_or(0))));
if (defaultRenderAhead && sRenderPipelineType == RenderPipelineType::SkiaVulkan) {
ALOGW("hwui.render_ahead of %d ignored because pipeline is skiavk", defaultRenderAhead);
}
defaultRenderAhead =
std::max(0u, std::min(2u, static_cast<uint32_t>(property_get_int(
PROPERTY_RENDERAHEAD, render_ahead().value_or(0)))));
return (prevDebugLayersUpdates != debugLayersUpdates) || (prevDebugOverdraw != debugOverdraw);
}

View File

@@ -253,7 +253,7 @@ public:
ANDROID_API static int contextPriority;
static int defaultRenderAhead;
static uint32_t defaultRenderAhead;
private:
static ProfileType sProfileType;

View File

@@ -15,6 +15,7 @@
*/
#include "ShaderCache.h"
#include <GrContext.h>
#include <log/log.h>
#include <openssl/sha.h>
#include <algorithm>
@@ -23,7 +24,6 @@
#include "FileBlobCache.h"
#include "Properties.h"
#include "utils/TraceUtils.h"
#include <GrContext.h>
namespace android {
namespace uirenderer {

View File

@@ -101,7 +101,7 @@ bool SkiaOpenGLPipeline::draw(const Frame& frame, const SkRect& screenDirty, con
SkiaPipeline::updateLighting(lightGeometry, lightInfo);
renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface,
SkMatrix::I());
SkMatrix::I());
layerUpdateQueue->clear();
// Draw visual debugging features
@@ -156,8 +156,23 @@ void SkiaOpenGLPipeline::onStop() {
}
}
static void setBufferCount(ANativeWindow* window, uint32_t extraBuffers) {
int query_value;
int err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &query_value);
if (err != 0 || query_value < 0) {
ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err, query_value);
return;
}
auto min_undequeued_buffers = static_cast<uint32_t>(query_value);
int bufferCount = min_undequeued_buffers + 2 + extraBuffers;
ALOGD("Setting buffer count to %d, min_undequeued %u, extraBuffers %u",
bufferCount, min_undequeued_buffers, extraBuffers);
native_window_set_buffer_count(window, bufferCount);
}
bool SkiaOpenGLPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBehavior,
ColorMode colorMode) {
ColorMode colorMode, uint32_t extraBuffers) {
if (mEglSurface != EGL_NO_SURFACE) {
mEglManager.destroySurface(mEglSurface);
mEglSurface = EGL_NO_SURFACE;
@@ -177,6 +192,7 @@ bool SkiaOpenGLPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBeh
if (mEglSurface != EGL_NO_SURFACE) {
const bool preserveBuffer = (swapBehavior != SwapBehavior::kSwap_discardBuffer);
mBufferPreserved = mEglManager.setPreserveBuffer(mEglSurface, preserveBuffer);
setBufferCount(surface, extraBuffers);
return true;
}

View File

@@ -44,7 +44,7 @@ public:
FrameInfo* currentFrameInfo, bool* requireSwap) override;
DeferredLayerUpdater* createTextureLayer() override;
bool setSurface(ANativeWindow* surface, renderthread::SwapBehavior swapBehavior,
renderthread::ColorMode colorMode) override;
renderthread::ColorMode colorMode, uint32_t extraBuffers) override;
void onStop() override;
bool isSurfaceReady() override;
bool isContextReady() override;

View File

@@ -250,8 +250,9 @@ SkCanvas* SkiaPipeline::tryCapture(SkSurface* surface) {
}
if (mCaptureSequence > 0 || mPictureCapturedCallback) {
mRecorder.reset(new SkPictureRecorder());
SkCanvas* pictureCanvas = mRecorder->beginRecording(surface->width(), surface->height(), nullptr,
SkPictureRecorder::kPlaybackDrawPicture_RecordFlag);
SkCanvas* pictureCanvas =
mRecorder->beginRecording(surface->width(), surface->height(), nullptr,
SkPictureRecorder::kPlaybackDrawPicture_RecordFlag);
mNwayCanvas = std::make_unique<SkNWayCanvas>(surface->width(), surface->height());
mNwayCanvas->addCanvas(surface->getCanvas());
mNwayCanvas->addCanvas(pictureCanvas);
@@ -276,8 +277,7 @@ void SkiaPipeline::endCapture(SkSurface* surface) {
if (1 == mCaptureSequence) {
savePictureAsync(data, mCapturedFile);
} else {
savePictureAsync(data,
mCapturedFile + "_" + std::to_string(mCaptureSequence));
savePictureAsync(data, mCapturedFile + "_" + std::to_string(mCaptureSequence));
}
mCaptureSequence--;
}
@@ -327,7 +327,7 @@ static Rect nodeBounds(RenderNode& node) {
auto& props = node.properties();
return Rect(props.getLeft(), props.getTop(), props.getRight(), props.getBottom());
}
}
} // namespace
void SkiaPipeline::renderFrameImpl(const LayerUpdateQueue& layers, const SkRect& clip,
const std::vector<sp<RenderNode>>& nodes, bool opaque,
@@ -464,10 +464,20 @@ void SkiaPipeline::setSurfaceColorProperties(ColorMode colorMode) {
// (3) Requires RGBA colors (instead of BGRA).
static const uint32_t kOverdrawColors[2][6] = {
{
0x00000000, 0x00000000, 0x2f2f0000, 0x2f002f00, 0x3f00003f, 0x7f00007f,
0x00000000,
0x00000000,
0x2f2f0000,
0x2f002f00,
0x3f00003f,
0x7f00007f,
},
{
0x00000000, 0x00000000, 0x2f2f0000, 0x4f004f4f, 0x5f50335f, 0x7f00007f,
0x00000000,
0x00000000,
0x2f2f0000,
0x4f004f4f,
0x5f50335f,
0x7f00007f,
},
};

View File

@@ -142,8 +142,7 @@ void SkiaRecordingCanvas::callDrawGLFunction(Functor* functor,
void SkiaRecordingCanvas::drawWebViewFunctor(int functor) {
FunctorDrawable* functorDrawable;
if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
functorDrawable =
mDisplayList->allocateDrawable<VkFunctorDrawable>(functor, asSkCanvas());
functorDrawable = mDisplayList->allocateDrawable<VkFunctorDrawable>(functor, asSkCanvas());
} else {
functorDrawable = mDisplayList->allocateDrawable<GLFunctorDrawable>(functor, asSkCanvas());
}

View File

@@ -18,12 +18,12 @@
#include "DeferredLayerUpdater.h"
#include "Readback.h"
#include "ShaderCache.h"
#include "SkiaPipeline.h"
#include "SkiaProfileRenderer.h"
#include "VkInteropFunctorDrawable.h"
#include "renderstate/RenderState.h"
#include "renderthread/Frame.h"
#include "ShaderCache.h"
#include <SkSurface.h>
#include <SkTypes.h>
@@ -70,8 +70,8 @@ bool SkiaVulkanPipeline::draw(const Frame& frame, const SkRect& screenDirty, con
return false;
}
SkiaPipeline::updateLighting(lightGeometry, lightInfo);
renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds,
backBuffer, mVkSurface->getCurrentPreTransform());
renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, backBuffer,
mVkSurface->getCurrentPreTransform());
ShaderCache::get().onVkFrameFlushed(mRenderThread.getGrContext());
layerUpdateQueue->clear();
@@ -116,7 +116,7 @@ DeferredLayerUpdater* SkiaVulkanPipeline::createTextureLayer() {
void SkiaVulkanPipeline::onStop() {}
bool SkiaVulkanPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBehavior,
ColorMode colorMode) {
ColorMode colorMode, uint32_t extraBuffers) {
if (mVkSurface) {
mVkManager.destroySurface(mVkSurface);
mVkSurface = nullptr;
@@ -125,8 +125,9 @@ bool SkiaVulkanPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBeh
setSurfaceColorProperties(colorMode);
if (surface) {
mRenderThread.requireVkContext();
mVkSurface = mVkManager.createSurface(surface, colorMode, mSurfaceColorSpace,
mSurfaceColorType, mRenderThread.getGrContext());
mVkSurface =
mVkManager.createSurface(surface, colorMode, mSurfaceColorSpace, mSurfaceColorType,
mRenderThread.getGrContext(), extraBuffers);
}
return mVkSurface != nullptr;

View File

@@ -43,7 +43,7 @@ public:
FrameInfo* currentFrameInfo, bool* requireSwap) override;
DeferredLayerUpdater* createTextureLayer() override;
bool setSurface(ANativeWindow* surface, renderthread::SwapBehavior swapBehavior,
renderthread::ColorMode colorMode) override;
renderthread::ColorMode colorMode, uint32_t extraBuffers) override;
void onStop() override;
bool isSurfaceReady() override;
bool isContextReady() override;

View File

@@ -17,16 +17,16 @@
#include "VkFunctorDrawable.h"
#include <private/hwui/DrawVkInfo.h>
#include "renderthread/VulkanManager.h"
#include "renderthread/RenderThread.h"
#include <SkAndroidFrameworkUtils.h>
#include <GrBackendDrawableInfo.h>
#include <SkAndroidFrameworkUtils.h>
#include <SkImage.h>
#include <utils/Color.h>
#include <utils/Trace.h>
#include <utils/TraceUtils.h>
#include <vk/GrVkTypes.h>
#include <thread>
#include "renderthread/RenderThread.h"
#include "renderthread/VulkanManager.h"
#include "thread/ThreadBase.h"
#include "utils/TimeUtils.h"
@@ -64,13 +64,13 @@ void VkFunctorDrawHandler::draw(const GrBackendDrawableInfo& info) {
SkMatrix44 mat4(mMatrix);
VkFunctorDrawParams params{
.width = mImageInfo.width(),
.height = mImageInfo.height(),
.color_space_ptr = mImageInfo.colorSpace(),
.clip_left = mClip.fLeft,
.clip_top = mClip.fTop,
.clip_right = mClip.fRight,
.clip_bottom = mClip.fBottom,
.width = mImageInfo.width(),
.height = mImageInfo.height(),
.color_space_ptr = mImageInfo.colorSpace(),
.clip_left = mClip.fLeft,
.clip_top = mClip.fTop,
.clip_right = mClip.fRight,
.clip_bottom = mClip.fBottom,
};
mat4.asColMajorf(&params.transform[0]);
params.secondary_command_buffer = vulkan_info.fSecondaryCommandBuffer;
@@ -87,8 +87,7 @@ void VkFunctorDrawHandler::draw(const GrBackendDrawableInfo& info) {
vulkan_info.fDrawBounds->extent.height = mClip.fBottom - mClip.fTop;
}
VkFunctorDrawable::~VkFunctorDrawable() {
}
VkFunctorDrawable::~VkFunctorDrawable() {}
void VkFunctorDrawable::onDraw(SkCanvas* canvas) {
// "canvas" is either SkNWayCanvas created by SkiaPipeline::tryCapture (SKP capture use case) or
@@ -106,9 +105,8 @@ void VkFunctorDrawable::onDraw(SkCanvas* canvas) {
SkCanvas* gpuCanvas = SkAndroidFrameworkUtils::getBaseWrappedCanvas(canvas);
// Enforce "canvas" must be an AlphaFilterCanvas. For GPU canvas, the call should come from
// onSnapGpuDrawHandler.
LOG_ALWAYS_FATAL_IF(
gpuCanvas == canvas,
"VkFunctorDrawable::onDraw() should not be called with a GPU canvas!");
LOG_ALWAYS_FATAL_IF(gpuCanvas == canvas,
"VkFunctorDrawable::onDraw() should not be called with a GPU canvas!");
// This will invoke onSnapGpuDrawHandler and regular draw flow.
gpuCanvas->drawDrawable(this);

View File

@@ -21,17 +21,16 @@
#include "RenderThread.h"
#include "pipeline/skia/ShaderCache.h"
#include "pipeline/skia/SkiaMemoryTracer.h"
#include "Properties.h"
#include "renderstate/RenderState.h"
#include "thread/CommonPool.h"
#include <GrContextOptions.h>
#include <SkExecutor.h>
#include <SkGraphics.h>
#include <SkMathPriv.h>
#include <gui/Surface.h>
#include <math.h>
#include <set>
#include <SkMathPriv.h>
namespace android {
namespace uirenderer {
@@ -79,14 +78,13 @@ void CacheManager::updateContextCacheSizes() {
class CommonPoolExecutor : public SkExecutor {
public:
virtual void add(std::function<void(void)> func) override {
CommonPool::post(std::move(func));
}
virtual void add(std::function<void(void)> func) override { CommonPool::post(std::move(func)); }
};
static CommonPoolExecutor sDefaultExecutor;
void CacheManager::configureContext(GrContextOptions* contextOptions, const void* identity, ssize_t size) {
void CacheManager::configureContext(GrContextOptions* contextOptions, const void* identity,
ssize_t size) {
contextOptions->fAllowPathMaskCaching = true;
// This sets the maximum size for a single texture atlas in the GPU font cache. If necessary,
@@ -180,7 +178,8 @@ void CacheManager::dumpMemoryUsage(String8& log, const RenderState* renderState)
}
const char* layerType = Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL
? "GlLayer" : "VkLayer";
? "GlLayer"
: "VkLayer";
size_t layerMemoryTotal = 0;
for (std::set<Layer*>::iterator it = renderState->mActiveLayers.begin();
it != renderState->mActiveLayers.end(); it++) {

View File

@@ -17,6 +17,7 @@
#include "CanvasContext.h"
#include <GpuMemoryTracker.h>
#include "../Properties.h"
#include "AnimationContext.h"
#include "EglManager.h"
#include "Frame.h"
@@ -31,7 +32,6 @@
#include "utils/GLUtils.h"
#include "utils/TimeUtils.h"
#include "utils/TraceUtils.h"
#include "../Properties.h"
#include <cutils/properties.h>
#include <private/hwui/DrawGlInfo.h>
@@ -153,7 +153,8 @@ void CanvasContext::setSurface(sp<Surface>&& surface) {
}
ColorMode colorMode = mWideColorGamut ? ColorMode::WideColorGamut : ColorMode::SRGB;
bool hasSurface = mRenderPipeline->setSurface(mNativeSurface.get(), mSwapBehavior, colorMode);
bool hasSurface = mRenderPipeline->setSurface(mNativeSurface.get(), mSwapBehavior, colorMode,
mRenderAheadDepth);
mFrameNumber = -1;
@@ -298,7 +299,7 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, int64_t sy
mAnimationContext->startFrame(info.mode);
mRenderPipeline->onPrepareTree();
for (const sp<RenderNode> &node : mRenderNodes) {
for (const sp<RenderNode>& node : mRenderNodes) {
// Only the primary target node will be drawn full - all other nodes would get drawn in
// real time mode. In case of a window, the primary node is the window content and the other
// node(s) are non client / filler nodes.
@@ -322,7 +323,7 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, int64_t sy
if (CC_LIKELY(mSwapHistory.size() && !Properties::forceDrawFrame)) {
nsecs_t latestVsync = mRenderThread.timeLord().latestVsync();
SwapHistory &lastSwap = mSwapHistory.back();
SwapHistory& lastSwap = mSwapHistory.back();
nsecs_t vsyncDelta = std::abs(lastSwap.vsyncTime - latestVsync);
// The slight fudge-factor is to deal with cases where
// the vsync was estimated due to being slow handling the signal.
@@ -405,8 +406,7 @@ void CanvasContext::draw() {
SkRect dirty;
mDamageAccumulator.finish(&dirty);
if (dirty.isEmpty() && Properties::skipEmptyFrames
&& !surfaceRequiresRedraw()) {
if (dirty.isEmpty() && Properties::skipEmptyFrames && !surfaceRequiresRedraw()) {
mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame);
return;
}
@@ -416,21 +416,21 @@ void CanvasContext::draw() {
Frame frame = mRenderPipeline->getFrame();
SkRect windowDirty = computeDirtyRect(frame, &dirty);
if (mRenderAheadDepth) {
auto presentTime =
mCurrentFrameInfo->get(FrameInfoIndex::Vsync) +
(mRenderThread.timeLord().frameIntervalNanos() * (mRenderAheadDepth + 1));
native_window_set_buffers_timestamp(mNativeSurface.get(), presentTime);
}
bool drew = mRenderPipeline->draw(frame, windowDirty, dirty, mLightGeometry, &mLayerUpdateQueue,
mContentDrawBounds, mOpaque, mLightInfo,
mRenderNodes, &(profiler()));
mContentDrawBounds, mOpaque, mLightInfo, mRenderNodes,
&(profiler()));
int64_t frameCompleteNr = mFrameCompleteCallbacks.size() ? getFrameNumber() : -1;
waitOnFences();
if (mRenderAheadDepth) {
auto presentTime = mCurrentFrameInfo->get(FrameInfoIndex::Vsync) +
(mRenderThread.timeLord().frameIntervalNanos() * (mRenderAheadDepth + 1));
native_window_set_buffers_timestamp(mNativeSurface.get(), presentTime);
}
bool requireSwap = false;
bool didSwap =
mRenderPipeline->swapBuffers(frame, drew, windowDirty, mCurrentFrameInfo, &requireSwap);
@@ -645,21 +645,13 @@ bool CanvasContext::surfaceRequiresRedraw() {
}
void CanvasContext::applyRenderAheadSettings() {
if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
// TODO: Fix SkiaVulkan's assumptions on buffer counts. And SIGBUS crashes.
mRenderAheadDepth = 0;
return;
}
if (mNativeSurface) {
native_window_set_buffer_count(mNativeSurface.get(), 3 + mRenderAheadDepth);
if (!mRenderAheadDepth) {
native_window_set_buffers_timestamp(mNativeSurface.get(), NATIVE_WINDOW_TIMESTAMP_AUTO);
}
if (mNativeSurface && !mRenderAheadDepth) {
native_window_set_buffers_timestamp(mNativeSurface.get(), NATIVE_WINDOW_TIMESTAMP_AUTO);
}
}
void CanvasContext::setRenderAheadDepth(int renderAhead) {
if (renderAhead < 0 || renderAhead > 2 || renderAhead == mRenderAheadDepth) {
void CanvasContext::setRenderAheadDepth(uint32_t renderAhead) {
if (renderAhead > 2 || renderAhead == mRenderAheadDepth || mNativeSurface) {
return;
}
mRenderAheadDepth = renderAhead;

View File

@@ -17,15 +17,15 @@
#pragma once
#include "DamageAccumulator.h"
#include "Lighting.h"
#include "FrameInfo.h"
#include "FrameInfoVisualizer.h"
#include "FrameMetricsReporter.h"
#include "IContextFactory.h"
#include "IRenderPipeline.h"
#include "LayerUpdateQueue.h"
#include "RenderNode.h"
#include "Lighting.h"
#include "ReliableSurface.h"
#include "RenderNode.h"
#include "renderthread/RenderTask.h"
#include "renderthread/RenderThread.h"
@@ -37,10 +37,10 @@
#include <utils/Functor.h>
#include <functional>
#include <future>
#include <set>
#include <string>
#include <vector>
#include <future>
namespace android {
namespace uirenderer {
@@ -187,9 +187,7 @@ public:
mRenderPipeline->setPictureCapturedCallback(callback);
}
void setForceDark(bool enable) {
mUseForceDark = enable;
}
void setForceDark(bool enable) { mUseForceDark = enable; }
bool useForceDark() {
// The force-dark override has the highest priority, followed by the disable setting
@@ -204,7 +202,8 @@ public:
return mUseForceDark;
}
void setRenderAheadDepth(int renderAhead);
// Must be called before setSurface
void setRenderAheadDepth(uint32_t renderAhead);
private:
CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode,
@@ -238,7 +237,7 @@ private:
// painted onto its surface.
bool mIsDirty = false;
SwapBehavior mSwapBehavior = SwapBehavior::kSwap_default;
int mRenderAheadDepth = 0;
uint32_t mRenderAheadDepth = 0;
struct SwapHistory {
SkRect damage;
nsecs_t vsyncTime;

View File

@@ -109,9 +109,8 @@ void DrawFrameTask::run() {
// Even if we aren't drawing this vsync pulse the next frame number will still be accurate
if (CC_UNLIKELY(callback)) {
context->enqueueFrameWork([callback, frameNr = context->getFrameNumber()]() {
callback(frameNr);
});
context->enqueueFrameWork(
[callback, frameNr = context->getFrameNumber()]() { callback(frameNr); });
}
if (CC_LIKELY(canDrawThisFrame)) {

View File

@@ -29,10 +29,10 @@
#include <EGL/eglext.h>
#include <GLES/gl.h>
#include <gui/Surface.h>
#include <system/window.h>
#include <string>
#include <vector>
#include <system/window.h>
#include <gui/Surface.h>
#define GLES_VERSION 2
@@ -171,8 +171,7 @@ EGLConfig EglManager::load8BitsConfig(EGLDisplay display, EglManager::SwapBehavi
EGL_NONE};
EGLConfig config = EGL_NO_CONFIG_KHR;
EGLint numConfigs = 1;
if (!eglChooseConfig(display, attribs, &config, numConfigs, &numConfigs) ||
numConfigs != 1) {
if (!eglChooseConfig(display, attribs, &config, numConfigs, &numConfigs) || numConfigs != 1) {
return EGL_NO_CONFIG_KHR;
}
return config;
@@ -203,8 +202,7 @@ EGLConfig EglManager::loadFP16Config(EGLDisplay display, SwapBehavior swapBehavi
EGL_NONE};
EGLConfig config = EGL_NO_CONFIG_KHR;
EGLint numConfigs = 1;
if (!eglChooseConfig(display, attribs, &config, numConfigs, &numConfigs) ||
numConfigs != 1) {
if (!eglChooseConfig(display, attribs, &config, numConfigs, &numConfigs) || numConfigs != 1) {
return EGL_NO_CONFIG_KHR;
}
return config;
@@ -262,7 +260,7 @@ void EglManager::loadConfigs() {
mEglConfigWideGamut = loadFP16Config(mEglDisplay, mSwapBehavior);
if (mEglConfigWideGamut == EGL_NO_CONFIG_KHR) {
ALOGE("Device claims wide gamut support, cannot find matching config, error = %s",
eglErrorString());
eglErrorString());
EglExtensions.pixelFormatFloat = false;
}
} else if (wideColorType == SkColorType::kN32_SkColorType) {
@@ -350,7 +348,7 @@ Result<EGLSurface, EGLint> EglManager::createSurface(EGLNativeWindowType window,
EGLSurface surface = eglCreateWindowSurface(
mEglDisplay, wideColorGamut ? mEglConfigWideGamut : mEglConfig, window, attribs);
if (surface == EGL_NO_SURFACE) {
return Error<EGLint> { eglGetError() };
return Error<EGLint>{eglGetError()};
}
if (mSwapBehavior != SwapBehavior::Preserved) {
@@ -525,12 +523,8 @@ status_t EglManager::fenceWait(sp<Fence>& fence) {
ALOGE("EglManager::fenceWait: error dup'ing fence fd: %d", errno);
return -errno;
}
EGLint attribs[] = {
EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceFd,
EGL_NONE
};
EGLSyncKHR sync = eglCreateSyncKHR(mEglDisplay,
EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceFd, EGL_NONE};
EGLSyncKHR sync = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
if (sync == EGL_NO_SYNC_KHR) {
close(fenceFd);
ALOGE("EglManager::fenceWait: error creating EGL fence: %#x", eglGetError());
@@ -559,18 +553,16 @@ status_t EglManager::fenceWait(sp<Fence>& fence) {
}
status_t EglManager::createReleaseFence(bool useFenceSync, EGLSyncKHR* eglFence,
sp<Fence>& nativeFence) {
sp<Fence>& nativeFence) {
if (!hasEglContext()) {
ALOGE("EglManager::createReleaseFence: EGLDisplay not initialized");
return INVALID_OPERATION;
}
if (SyncFeatures::getInstance().useNativeFenceSync()) {
EGLSyncKHR sync = eglCreateSyncKHR(mEglDisplay,
EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
EGLSyncKHR sync = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
if (sync == EGL_NO_SYNC_KHR) {
ALOGE("EglManager::createReleaseFence: error creating EGL fence: %#x",
eglGetError());
ALOGE("EglManager::createReleaseFence: error creating EGL fence: %#x", eglGetError());
return UNKNOWN_ERROR;
}
glFlush();
@@ -578,7 +570,8 @@ status_t EglManager::createReleaseFence(bool useFenceSync, EGLSyncKHR* eglFence,
eglDestroySyncKHR(mEglDisplay, sync);
if (fenceFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
ALOGE("EglManager::createReleaseFence: error dup'ing native fence "
"fd: %#x", eglGetError());
"fd: %#x",
eglGetError());
return UNKNOWN_ERROR;
}
nativeFence = new Fence(fenceFd);
@@ -592,7 +585,7 @@ status_t EglManager::createReleaseFence(bool useFenceSync, EGLSyncKHR* eglFence,
EGLint result = eglClientWaitSyncKHR(mEglDisplay, *eglFence, 0, 1000000000);
if (result == EGL_FALSE) {
ALOGE("EglManager::createReleaseFence: error waiting for previous fence: %#x",
eglGetError());
eglGetError());
return UNKNOWN_ERROR;
} else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
ALOGE("EglManager::createReleaseFence: timeout waiting for previous fence");

View File

@@ -66,8 +66,8 @@ public:
virtual bool swapBuffers(const Frame& frame, bool drew, const SkRect& screenDirty,
FrameInfo* currentFrameInfo, bool* requireSwap) = 0;
virtual DeferredLayerUpdater* createTextureLayer() = 0;
virtual bool setSurface(ANativeWindow* window, SwapBehavior swapBehavior,
ColorMode colorMode) = 0;
virtual bool setSurface(ANativeWindow* window, SwapBehavior swapBehavior, ColorMode colorMode,
uint32_t extraBuffers) = 0;
virtual void onStop() = 0;
virtual bool isSurfaceReady() = 0;
virtual bool isContextReady() = 0;

View File

@@ -34,13 +34,13 @@ struct SurfaceExposer : Surface {
// Make warnings happy
SurfaceExposer() = delete;
using Surface::setBufferCount;
using Surface::setSwapInterval;
using Surface::dequeueBuffer;
using Surface::queueBuffer;
using Surface::cancelBuffer;
using Surface::dequeueBuffer;
using Surface::lockBuffer_DEPRECATED;
using Surface::perform;
using Surface::queueBuffer;
using Surface::setBufferCount;
using Surface::setSwapInterval;
};
#define callProtected(surface, func, ...) ((*surface).*&SurfaceExposer::func)(__VA_ARGS__)

View File

@@ -84,7 +84,7 @@ void RenderProxy::setName(const char* name) {
void RenderProxy::setSurface(const sp<Surface>& surface) {
mRenderThread.queue().post(
[ this, surf = surface ]() mutable { mContext->setSurface(std::move(surf)); });
[this, surf = surface]() mutable { mContext->setSurface(std::move(surf)); });
}
void RenderProxy::allocateBuffers() {
@@ -251,7 +251,7 @@ void RenderProxy::dumpGraphicsMemory(int fd) {
void RenderProxy::setProcessStatsBuffer(int fd) {
auto& rt = RenderThread::getInstance();
rt.queue().post([&rt, fd = dup(fd) ]() {
rt.queue().post([&rt, fd = dup(fd)]() {
rt.globalProfileData().switchStorageToAshmem(fd);
close(fd);
});
@@ -285,7 +285,7 @@ void RenderProxy::setContentDrawBounds(int left, int top, int right, int bottom)
void RenderProxy::setPictureCapturedCallback(
const std::function<void(sk_sp<SkPicture>&&)>& callback) {
mRenderThread.queue().post(
[ this, cb = callback ]() { mContext->setPictureCapturedCallback(cb); });
[this, cb = callback]() { mContext->setPictureCapturedCallback(cb); });
}
void RenderProxy::setFrameCallback(std::function<void(int64_t)>&& callback) {
@@ -297,13 +297,13 @@ void RenderProxy::setFrameCompleteCallback(std::function<void(int64_t)>&& callba
}
void RenderProxy::addFrameMetricsObserver(FrameMetricsObserver* observerPtr) {
mRenderThread.queue().post([ this, observer = sp{observerPtr} ]() {
mRenderThread.queue().post([this, observer = sp{observerPtr}]() {
mContext->addFrameMetricsObserver(observer.get());
});
}
void RenderProxy::removeFrameMetricsObserver(FrameMetricsObserver* observerPtr) {
mRenderThread.queue().post([ this, observer = sp{observerPtr} ]() {
mRenderThread.queue().post([this, observer = sp{observerPtr}]() {
mContext->removeFrameMetricsObserver(observer.get());
});
}
@@ -313,9 +313,8 @@ void RenderProxy::setForceDark(bool enable) {
}
void RenderProxy::setRenderAheadDepth(int renderAhead) {
mRenderThread.queue().post([ context = mContext, renderAhead ] {
context->setRenderAheadDepth(renderAhead);
});
mRenderThread.queue().post(
[context = mContext, renderAhead] { context->setRenderAheadDepth(renderAhead); });
}
int RenderProxy::copySurfaceInto(sp<Surface>& surface, int left, int top, int right, int bottom,
@@ -393,9 +392,7 @@ void RenderProxy::releaseVDAtlasEntries() {
void RenderProxy::preload() {
// Create RenderThread object and start the thread. Then preload Vulkan/EGL driver.
auto& thread = RenderThread::getInstance();
thread.queue().post([&thread]() {
thread.preload();
});
thread.queue().post([&thread]() { thread.preload(); });
}
} /* namespace renderthread */

View File

@@ -16,6 +16,7 @@
#include "RenderThread.h"
#include "../HardwareBitmapUploader.h"
#include "CanvasContext.h"
#include "DeviceInfo.h"
#include "EglManager.h"
@@ -29,7 +30,6 @@
#include "utils/FatVector.h"
#include "utils/TimeUtils.h"
#include "utils/TraceUtils.h"
#include "../HardwareBitmapUploader.h"
#ifdef HWUI_GLES_WRAP_ENABLED
#include "debug/GlesDriver.h"
@@ -410,9 +410,7 @@ bool RenderThread::isCurrent() {
void RenderThread::preload() {
// EGL driver is always preloaded only if HWUI renders with GL.
if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
std::thread eglInitThread([]() {
eglGetDisplay(EGL_DEFAULT_DISPLAY);
});
std::thread eglInitThread([]() { eglGetDisplay(EGL_DEFAULT_DISPLAY); });
eglInitThread.detach();
} else {
requireVkContext();

View File

@@ -22,8 +22,8 @@
#include "../JankTracker.h"
#include "CacheManager.h"
#include "TimeLord.h"
#include "thread/ThreadBase.h"
#include "WebViewFunctorManager.h"
#include "thread/ThreadBase.h"
#include "utils/TimeUtils.h"
#include <GrContext.h>

View File

@@ -29,7 +29,6 @@
#include <GrBackendSurface.h>
#include <GrContext.h>
#include <GrTypes.h>
#include <GrTypes.h>
#include <vk/GrVkExtensions.h>
#include <vk/GrVkTypes.h>
@@ -43,7 +42,7 @@ static void free_features_extensions_structs(const VkPhysicalDeviceFeatures2& fe
// so we can get access to the pNext for the next struct.
struct CommonVulkanHeader {
VkStructureType sType;
void* pNext;
void* pNext;
};
void* pNext = features.pNext;
@@ -94,13 +93,13 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe
VkResult err;
constexpr VkApplicationInfo app_info = {
VK_STRUCTURE_TYPE_APPLICATION_INFO, // sType
nullptr, // pNext
"android framework", // pApplicationName
0, // applicationVersion
"android framework", // pEngineName
0, // engineVerison
mAPIVersion, // apiVersion
VK_STRUCTURE_TYPE_APPLICATION_INFO, // sType
nullptr, // pNext
"android framework", // pApplicationName
0, // applicationVersion
"android framework", // pEngineName
0, // engineVerison
mAPIVersion, // apiVersion
};
{
@@ -128,14 +127,14 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe
}
const VkInstanceCreateInfo instance_create = {
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
nullptr, // pNext
0, // flags
&app_info, // pApplicationInfo
0, // enabledLayerNameCount
nullptr, // ppEnabledLayerNames
(uint32_t) mInstanceExtensions.size(), // enabledExtensionNameCount
mInstanceExtensions.data(), // ppEnabledExtensionNames
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
nullptr, // pNext
0, // flags
&app_info, // pApplicationInfo
0, // enabledLayerNameCount
nullptr, // ppEnabledLayerNames
(uint32_t)mInstanceExtensions.size(), // enabledExtensionNameCount
mInstanceExtensions.data(), // ppEnabledExtensionNames
};
GET_PROC(CreateInstance);
@@ -200,11 +199,11 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe
{
uint32_t extensionCount = 0;
err = mEnumerateDeviceExtensionProperties(mPhysicalDevice, nullptr, &extensionCount,
nullptr);
nullptr);
LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err);
mDeviceExtensionsOwner.resize(extensionCount);
err = mEnumerateDeviceExtensionProperties(mPhysicalDevice, nullptr, &extensionCount,
mDeviceExtensionsOwner.data());
mDeviceExtensionsOwner.data());
LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err);
bool hasKHRSwapchainExtension = false;
for (const VkExtensionProperties& extension : mDeviceExtensionsOwner) {
@@ -216,7 +215,7 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe
LOG_ALWAYS_FATAL_IF(!hasKHRSwapchainExtension);
}
auto getProc = [] (const char* proc_name, VkInstance instance, VkDevice device) {
auto getProc = [](const char* proc_name, VkInstance instance, VkDevice device) {
if (device != VK_NULL_HANDLE) {
return vkGetDeviceProcAddr(device, proc_name);
}
@@ -224,7 +223,8 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe
};
grExtensions.init(getProc, mInstance, mPhysicalDevice, mInstanceExtensions.size(),
mInstanceExtensions.data(), mDeviceExtensions.size(), mDeviceExtensions.data());
mInstanceExtensions.data(), mDeviceExtensions.size(),
mDeviceExtensions.data());
LOG_ALWAYS_FATAL_IF(!grExtensions.hasExtension(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, 1));
@@ -237,7 +237,7 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe
if (grExtensions.hasExtension(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME, 2)) {
VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT* blend;
blend = (VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT*) malloc(
blend = (VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT*)malloc(
sizeof(VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT));
LOG_ALWAYS_FATAL_IF(!blend);
blend->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT;
@@ -247,7 +247,7 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe
}
VkPhysicalDeviceSamplerYcbcrConversionFeatures* ycbcrFeature;
ycbcrFeature = (VkPhysicalDeviceSamplerYcbcrConversionFeatures*) malloc(
ycbcrFeature = (VkPhysicalDeviceSamplerYcbcrConversionFeatures*)malloc(
sizeof(VkPhysicalDeviceSamplerYcbcrConversionFeatures));
LOG_ALWAYS_FATAL_IF(!ycbcrFeature);
ycbcrFeature->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
@@ -261,17 +261,17 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe
// and we can't depend on it on all platforms
features.features.robustBufferAccess = VK_FALSE;
float queuePriorities[1] = { 0.0 };
float queuePriorities[1] = {0.0};
void* queueNextPtr = nullptr;
VkDeviceQueueGlobalPriorityCreateInfoEXT queuePriorityCreateInfo;
if (Properties::contextPriority != 0
&& grExtensions.hasExtension(VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME, 2)) {
if (Properties::contextPriority != 0 &&
grExtensions.hasExtension(VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME, 2)) {
memset(&queuePriorityCreateInfo, 0, sizeof(VkDeviceQueueGlobalPriorityCreateInfoEXT));
queuePriorityCreateInfo.sType =
VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT;
VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT;
queuePriorityCreateInfo.pNext = nullptr;
switch (Properties::contextPriority) {
case EGL_CONTEXT_PRIORITY_LOW_IMG:
@@ -285,41 +285,40 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe
break;
default:
LOG_ALWAYS_FATAL("Unsupported context priority");
}
queueNextPtr = &queuePriorityCreateInfo;
}
queueNextPtr = &queuePriorityCreateInfo;
}
const VkDeviceQueueCreateInfo queueInfo[2] = {
{
VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
queueNextPtr, // pNext
0, // VkDeviceQueueCreateFlags
mGraphicsQueueIndex, // queueFamilyIndex
1, // queueCount
queuePriorities, // pQueuePriorities
},
{
VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
queueNextPtr, // pNext
0, // VkDeviceQueueCreateFlags
mPresentQueueIndex, // queueFamilyIndex
1, // queueCount
queuePriorities, // pQueuePriorities
}
};
{
VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
queueNextPtr, // pNext
0, // VkDeviceQueueCreateFlags
mGraphicsQueueIndex, // queueFamilyIndex
1, // queueCount
queuePriorities, // pQueuePriorities
},
{
VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
queueNextPtr, // pNext
0, // VkDeviceQueueCreateFlags
mPresentQueueIndex, // queueFamilyIndex
1, // queueCount
queuePriorities, // pQueuePriorities
}};
uint32_t queueInfoCount = (mPresentQueueIndex != mGraphicsQueueIndex) ? 2 : 1;
const VkDeviceCreateInfo deviceInfo = {
VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
&features, // pNext
0, // VkDeviceCreateFlags
queueInfoCount, // queueCreateInfoCount
queueInfo, // pQueueCreateInfos
0, // layerCount
nullptr, // ppEnabledLayerNames
(uint32_t) mDeviceExtensions.size(), // extensionCount
mDeviceExtensions.data(), // ppEnabledExtensionNames
nullptr, // ppEnabledFeatures
VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
&features, // pNext
0, // VkDeviceCreateFlags
queueInfoCount, // queueCreateInfoCount
queueInfo, // pQueueCreateInfos
0, // layerCount
nullptr, // ppEnabledLayerNames
(uint32_t)mDeviceExtensions.size(), // extensionCount
mDeviceExtensions.data(), // ppEnabledExtensionNames
nullptr, // ppEnabledFeatures
};
LOG_ALWAYS_FATAL_IF(mCreateDevice(mPhysicalDevice, &deviceInfo, nullptr, &mDevice));
@@ -371,8 +370,8 @@ void VulkanManager::initialize() {
// this needs to be on the render queue
commandPoolInfo.queueFamilyIndex = mGraphicsQueueIndex;
commandPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
SkDEBUGCODE(VkResult res =) mCreateCommandPool(mDevice, &commandPoolInfo, nullptr,
&mCommandPool);
SkDEBUGCODE(VkResult res =)
mCreateCommandPool(mDevice, &commandPoolInfo, nullptr, &mCommandPool);
SkASSERT(VK_SUCCESS == res);
}
LOG_ALWAYS_FATAL_IF(mCommandPool == VK_NULL_HANDLE);
@@ -391,7 +390,7 @@ void VulkanManager::initialize() {
}
sk_sp<GrContext> VulkanManager::createContext(const GrContextOptions& options) {
auto getProc = [] (const char* proc_name, VkInstance instance, VkDevice device) {
auto getProc = [](const char* proc_name, VkInstance instance, VkDevice device) {
if (device != VK_NULL_HANDLE) {
return vkGetDeviceProcAddr(device, proc_name);
}
@@ -431,7 +430,6 @@ VkFunctorInitParams VulkanManager::getVkFunctorInitParams() const {
}
Frame VulkanManager::dequeueNextBuffer(VulkanSurface* surface) {
VulkanSurface::NativeBufferInfo* bufferInfo = surface->dequeueNativeBuffer();
if (bufferInfo == nullptr) {
@@ -480,7 +478,7 @@ Frame VulkanManager::dequeueNextBuffer(VulkanSurface* surface) {
bufferInfo->skSurface->wait(1, &backendSemaphore);
// The following flush blocks the GPU immediately instead of waiting for other
// drawing ops. It seems dequeue_fence is not respected otherwise.
//TODO: remove the flush after finding why backendSemaphore is not working.
// TODO: remove the flush after finding why backendSemaphore is not working.
bufferInfo->skSurface->flush();
}
}
@@ -557,15 +555,15 @@ void VulkanManager::destroySurface(VulkanSurface* surface) {
VulkanSurface* VulkanManager::createSurface(ANativeWindow* window, ColorMode colorMode,
sk_sp<SkColorSpace> surfaceColorSpace,
SkColorType surfaceColorType,
GrContext* grContext) {
SkColorType surfaceColorType, GrContext* grContext,
uint32_t extraBuffers) {
LOG_ALWAYS_FATAL_IF(!hasVkContext(), "Not initialized");
if (!window) {
return nullptr;
}
return VulkanSurface::Create(window, colorMode, surfaceColorType, surfaceColorSpace, grContext,
*this);
*this, extraBuffers);
}
bool VulkanManager::setupDummyCommandBuffer() {

View File

@@ -18,16 +18,16 @@
#define VULKANMANAGER_H
#if !defined(VK_USE_PLATFORM_ANDROID_KHR)
# define VK_USE_PLATFORM_ANDROID_KHR
#define VK_USE_PLATFORM_ANDROID_KHR
#endif
#include <vulkan/vulkan.h>
#include <GrContextOptions.h>
#include <vk/GrVkExtensions.h>
#include <SkSurface.h>
#include <ui/Fence.h>
#include <utils/StrongPointer.h>
#include <vk/GrVkBackendContext.h>
#include <vk/GrVkExtensions.h>
#include "Frame.h"
#include "IRenderPipeline.h"
#include "VulkanSurface.h"
@@ -59,8 +59,8 @@ public:
// Create and destroy functions for wrapping an ANativeWindow in a VulkanSurface
VulkanSurface* createSurface(ANativeWindow* window, ColorMode colorMode,
sk_sp<SkColorSpace> surfaceColorSpace,
SkColorType surfaceColorType,
GrContext* grContext);
SkColorType surfaceColorType, GrContext* grContext,
uint32_t extraBuffers);
void destroySurface(VulkanSurface* surface);
Frame dequeueNextBuffer(VulkanSurface* surface);

View File

@@ -16,12 +16,12 @@
#include "VulkanSurface.h"
#include <algorithm>
#include <SkSurface.h>
#include <algorithm>
#include "VulkanManager.h"
#include "utils/TraceUtils.h"
#include "utils/Color.h"
#include "utils/TraceUtils.h"
namespace android {
namespace uirenderer {
@@ -31,10 +31,9 @@ static bool IsTransformSupported(int transform) {
// For now, only support pure rotations, not flip or flip-and-rotate, until we have
// more time to test them and build sample code. As far as I know we never actually
// use anything besides pure rotations anyway.
return transform == 0
|| transform == NATIVE_WINDOW_TRANSFORM_ROT_90
|| transform == NATIVE_WINDOW_TRANSFORM_ROT_180
|| transform == NATIVE_WINDOW_TRANSFORM_ROT_270;
return transform == 0 || transform == NATIVE_WINDOW_TRANSFORM_ROT_90 ||
transform == NATIVE_WINDOW_TRANSFORM_ROT_180 ||
transform == NATIVE_WINDOW_TRANSFORM_ROT_270;
}
static int InvertTransform(int transform) {
@@ -85,16 +84,16 @@ static SkMatrix GetPreTransformMatrix(SkISize windowSize, int transform) {
}
void VulkanSurface::ComputeWindowSizeAndTransform(WindowInfo* windowInfo, const SkISize& minSize,
const SkISize& maxSize) {
const SkISize& maxSize) {
SkISize& windowSize = windowInfo->size;
// clamp width & height to handle currentExtent of -1 and protect us from broken hints
if (windowSize.width() < minSize.width() || windowSize.width() > maxSize.width()
|| windowSize.height() < minSize.height() || windowSize.height() > maxSize.height()) {
if (windowSize.width() < minSize.width() || windowSize.width() > maxSize.width() ||
windowSize.height() < minSize.height() || windowSize.height() > maxSize.height()) {
int width = std::min(maxSize.width(), std::max(minSize.width(), windowSize.width()));
int height = std::min(maxSize.height(), std::max(minSize.height(), windowSize.height()));
ALOGE("Invalid Window Dimensions [%d, %d]; clamping to [%d, %d]",
windowSize.width(), windowSize.height(), width, height);
ALOGE("Invalid Window Dimensions [%d, %d]; clamping to [%d, %d]", windowSize.width(),
windowSize.height(), width, height);
windowSize.set(width, height);
}
@@ -145,12 +144,8 @@ class VkSurfaceAutoDeleter {
public:
VkSurfaceAutoDeleter(VkInstance instance, VkSurfaceKHR surface,
PFN_vkDestroySurfaceKHR destroySurfaceKHR)
: mInstance(instance)
, mSurface(surface)
, mDestroySurfaceKHR(destroySurfaceKHR) {}
~VkSurfaceAutoDeleter() {
destroy();
}
: mInstance(instance), mSurface(surface), mDestroySurfaceKHR(destroySurfaceKHR) {}
~VkSurfaceAutoDeleter() { destroy(); }
void destroy() {
if (mSurface != VK_NULL_HANDLE) {
@@ -166,9 +161,9 @@ private:
};
VulkanSurface* VulkanSurface::Create(ANativeWindow* window, ColorMode colorMode,
SkColorType colorType, sk_sp<SkColorSpace> colorSpace,
GrContext* grContext, const VulkanManager& vkManager) {
SkColorType colorType, sk_sp<SkColorSpace> colorSpace,
GrContext* grContext, const VulkanManager& vkManager,
uint32_t extraBuffers) {
VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo;
memset(&surfaceCreateInfo, 0, sizeof(VkAndroidSurfaceCreateInfoKHR));
surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
@@ -188,10 +183,11 @@ VulkanSurface* VulkanSurface::Create(ANativeWindow* window, ColorMode colorMode,
vkManager.mDestroySurfaceKHR);
SkDEBUGCODE(VkBool32 supported; res = vkManager.mGetPhysicalDeviceSurfaceSupportKHR(
vkManager.mPhysicalDevice, vkManager.mPresentQueueIndex, vkSurface, &supported);
// All physical devices and queue families on Android must be capable of
// presentation with any native window.
SkASSERT(VK_SUCCESS == res && supported););
vkManager.mPhysicalDevice, vkManager.mPresentQueueIndex,
vkSurface, &supported);
// All physical devices and queue families on Android must be capable of
// presentation with any native window.
SkASSERT(VK_SUCCESS == res && supported););
// check for capabilities
VkSurfaceCapabilitiesKHR caps;
@@ -225,14 +221,13 @@ VulkanSurface* VulkanSurface::Create(ANativeWindow* window, ColorMode colorMode,
int query_value;
int err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &query_value);
if (err != 0 || query_value < 0) {
ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err,
query_value);
ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err, query_value);
return nullptr;
}
auto min_undequeued_buffers = static_cast<uint32_t>(query_value);
windowInfo.bufferCount = min_undequeued_buffers
+ std::max(VulkanSurface::sTargetBufferCount, caps.minImageCount);
windowInfo.bufferCount = min_undequeued_buffers +
std::max(sTargetBufferCount + extraBuffers, caps.minImageCount);
if (caps.maxImageCount > 0 && windowInfo.bufferCount > caps.maxImageCount) {
// Application must settle for fewer images than desired:
windowInfo.bufferCount = caps.maxImageCount;
@@ -241,8 +236,7 @@ VulkanSurface* VulkanSurface::Create(ANativeWindow* window, ColorMode colorMode,
// Currently Skia requires the images to be color attachments and support all transfer
// operations.
VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
VK_IMAGE_USAGE_SAMPLED_BIT |
VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
VK_IMAGE_USAGE_TRANSFER_DST_BIT;
LOG_ALWAYS_FATAL_IF((caps.supportedUsageFlags & usageFlags) != usageFlags);
@@ -336,7 +330,8 @@ bool VulkanSurface::UpdateWindow(ANativeWindow* window, const WindowInfo& window
err = native_window_set_buffers_data_space(window, windowInfo.dataspace);
if (err != 0) {
ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffers_data_space(%d) "
"failed: %s (%d)", windowInfo.dataspace, strerror(-err), err);
"failed: %s (%d)",
windowInfo.dataspace, strerror(-err), err);
return false;
}
@@ -344,7 +339,8 @@ bool VulkanSurface::UpdateWindow(ANativeWindow* window, const WindowInfo& window
err = native_window_set_buffers_dimensions(window, size.width(), size.height());
if (err != 0) {
ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffers_dimensions(%d,%d) "
"failed: %s (%d)", size.width(), size.height(), strerror(-err), err);
"failed: %s (%d)",
size.width(), size.height(), strerror(-err), err);
return false;
}
@@ -357,7 +353,8 @@ bool VulkanSurface::UpdateWindow(ANativeWindow* window, const WindowInfo& window
err = native_window_set_buffers_transform(window, InvertTransform(windowInfo.transform));
if (err != 0) {
ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffers_transform(%d) "
"failed: %s (%d)", windowInfo.transform, strerror(-err), err);
"failed: %s (%d)",
windowInfo.transform, strerror(-err), err);
return false;
}
@@ -366,7 +363,8 @@ bool VulkanSurface::UpdateWindow(ANativeWindow* window, const WindowInfo& window
err = native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_FREEZE);
if (err != 0) {
ALOGE("VulkanSurface::UpdateWindow() native_window_set_scaling_mode(SCALE_TO_WINDOW) "
"failed: %s (%d)", strerror(-err), err);
"failed: %s (%d)",
strerror(-err), err);
return false;
}
@@ -388,12 +386,12 @@ bool VulkanSurface::UpdateWindow(ANativeWindow* window, const WindowInfo& window
}
VulkanSurface::VulkanSurface(ANativeWindow* window, const WindowInfo& windowInfo,
SkISize minWindowSize, SkISize maxWindowSize, GrContext* grContext)
SkISize minWindowSize, SkISize maxWindowSize, GrContext* grContext)
: mNativeWindow(window)
, mWindowInfo(windowInfo)
, mGrContext(grContext)
, mMinWindowSize(minWindowSize)
, mMaxWindowSize(maxWindowSize) { }
, mMaxWindowSize(maxWindowSize) {}
VulkanSurface::~VulkanSurface() {
releaseBuffers();
@@ -436,8 +434,7 @@ VulkanSurface::NativeBufferInfo* VulkanSurface::dequeueNativeBuffer() {
// value at the end of the function if everything dequeued correctly.
mCurrentBufferInfo = nullptr;
//check if the native window has been resized or rotated and update accordingly
// check if the native window has been resized or rotated and update accordingly
SkISize newSize = SkISize::MakeEmpty();
int transformHint = 0;
mNativeWindow->query(mNativeWindow.get(), NATIVE_WINDOW_WIDTH, &newSize.fWidth);
@@ -457,8 +454,8 @@ VulkanSurface::NativeBufferInfo* VulkanSurface::dequeueNativeBuffer() {
newWindowInfo.actualSize.height());
if (err != 0) {
ALOGE("native_window_set_buffers_dimensions(%d,%d) failed: %s (%d)",
newWindowInfo.actualSize.width(),
newWindowInfo.actualSize.height(), strerror(-err), err);
newWindowInfo.actualSize.width(), newWindowInfo.actualSize.height(),
strerror(-err), err);
return nullptr;
}
// reset the NativeBufferInfo (including SkSurface) associated with the old buffers. The
@@ -469,7 +466,7 @@ VulkanSurface::NativeBufferInfo* VulkanSurface::dequeueNativeBuffer() {
if (newWindowInfo.transform != mWindowInfo.transform) {
err = native_window_set_buffers_transform(mNativeWindow.get(),
InvertTransform(newWindowInfo.transform));
InvertTransform(newWindowInfo.transform));
if (err != 0) {
ALOGE("native_window_set_buffers_transform(%d) failed: %s (%d)",
newWindowInfo.transform, strerror(-err), err);
@@ -512,11 +509,9 @@ VulkanSurface::NativeBufferInfo* VulkanSurface::dequeueNativeBuffer() {
VulkanSurface::NativeBufferInfo* bufferInfo = &mNativeBuffers[idx];
if (bufferInfo->skSurface.get() == nullptr) {
bufferInfo->skSurface =
SkSurface::MakeFromAHardwareBuffer(mGrContext,
ANativeWindowBuffer_getHardwareBuffer(bufferInfo->buffer.get()),
kTopLeft_GrSurfaceOrigin, DataSpaceToColorSpace(mWindowInfo.dataspace),
nullptr);
bufferInfo->skSurface = SkSurface::MakeFromAHardwareBuffer(
mGrContext, ANativeWindowBuffer_getHardwareBuffer(bufferInfo->buffer.get()),
kTopLeft_GrSurfaceOrigin, DataSpaceToColorSpace(mWindowInfo.dataspace), nullptr);
if (bufferInfo->skSurface.get() == nullptr) {
ALOGE("SkSurface::MakeFromAHardwareBuffer failed");
mNativeWindow->cancelBuffer(mNativeWindow.get(), buffer, fence_fd);

View File

@@ -19,8 +19,8 @@
#include <system/window.h>
#include <vulkan/vulkan.h>
#include <SkSize.h>
#include <SkRefCnt.h>
#include <SkSize.h>
#include "IRenderPipeline.h"
@@ -34,12 +34,9 @@ class VulkanManager;
class VulkanSurface {
public:
static VulkanSurface* Create(ANativeWindow* window,
ColorMode colorMode,
SkColorType colorType,
sk_sp<SkColorSpace> colorSpace,
GrContext* grContext,
const VulkanManager& vkManager);
static VulkanSurface* Create(ANativeWindow* window, ColorMode colorMode, SkColorType colorType,
sk_sp<SkColorSpace> colorSpace, GrContext* grContext,
const VulkanManager& vkManager, uint32_t extraBuffers);
~VulkanSurface();
sk_sp<SkSurface> getCurrentSkSurface() {
@@ -104,15 +101,10 @@ private:
SkMatrix preTransform;
};
VulkanSurface(ANativeWindow* window,
const WindowInfo& windowInfo,
SkISize minWindowSize,
SkISize maxWindowSize,
GrContext* grContext);
static bool UpdateWindow(ANativeWindow* window,
const WindowInfo& windowInfo);
static void ComputeWindowSizeAndTransform(WindowInfo* windowInfo,
const SkISize& minSize,
VulkanSurface(ANativeWindow* window, const WindowInfo& windowInfo, SkISize minWindowSize,
SkISize maxWindowSize, GrContext* grContext);
static bool UpdateWindow(ANativeWindow* window, const WindowInfo& windowInfo);
static void ComputeWindowSizeAndTransform(WindowInfo* windowInfo, const SkISize& minSize,
const SkISize& maxSize);
void releaseBuffers();

View File

@@ -31,6 +31,9 @@
#include "renderthread/CanvasContext.h"
#include "tests/common/TestUtils.h"
#include <gui/BufferItemConsumer.h>
#include <gui/Surface.h>
using namespace android;
using namespace android::uirenderer;
using namespace android::uirenderer::renderthread;
@@ -421,10 +424,20 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, clip_replace) {
EXPECT_EQ(1, surface->canvas()->mDrawCounter);
}
static sp<Surface> createDummySurface() {
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer);
producer->setMaxDequeuedBufferCount(1);
producer->setAsyncMode(true);
return new Surface(producer);
}
RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, context_lost) {
auto surface = createDummySurface();
auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
EXPECT_FALSE(pipeline->isSurfaceReady());
EXPECT_TRUE(pipeline->setSurface((Surface*)0x01, SwapBehavior::kSwap_default, ColorMode::SRGB));
EXPECT_TRUE(pipeline->setSurface(surface.get(), SwapBehavior::kSwap_default, ColorMode::SRGB, 0));
EXPECT_TRUE(pipeline->isSurfaceReady());
renderThread.destroyRenderingContext();
EXPECT_FALSE(pipeline->isSurfaceReady());