1*d57664e9SAndroid Build Coastguard Worker /* 2*d57664e9SAndroid Build Coastguard Worker * Copyright (C) 2019 The Android Open Source Project 3*d57664e9SAndroid Build Coastguard Worker * 4*d57664e9SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*d57664e9SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*d57664e9SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*d57664e9SAndroid Build Coastguard Worker * 8*d57664e9SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*d57664e9SAndroid Build Coastguard Worker * 10*d57664e9SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*d57664e9SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*d57664e9SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*d57664e9SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*d57664e9SAndroid Build Coastguard Worker * limitations under the License. 15*d57664e9SAndroid Build Coastguard Worker */ 16*d57664e9SAndroid Build Coastguard Worker #pragma once 17*d57664e9SAndroid Build Coastguard Worker 18*d57664e9SAndroid Build Coastguard Worker #include <android-base/unique_fd.h> 19*d57664e9SAndroid Build Coastguard Worker #include <system/graphics.h> 20*d57664e9SAndroid Build Coastguard Worker #include <system/window.h> 21*d57664e9SAndroid Build Coastguard Worker #include <vulkan/vulkan.h> 22*d57664e9SAndroid Build Coastguard Worker 23*d57664e9SAndroid Build Coastguard Worker #include <SkColorSpace.h> 24*d57664e9SAndroid Build Coastguard Worker #include <SkRefCnt.h> 25*d57664e9SAndroid Build Coastguard Worker #include <SkSize.h> 26*d57664e9SAndroid Build Coastguard Worker 27*d57664e9SAndroid Build Coastguard Worker #include "IRenderPipeline.h" 28*d57664e9SAndroid Build Coastguard Worker 29*d57664e9SAndroid Build Coastguard Worker class SkSurface; 30*d57664e9SAndroid Build Coastguard Worker 31*d57664e9SAndroid Build Coastguard Worker namespace android { 32*d57664e9SAndroid Build Coastguard Worker namespace uirenderer { 33*d57664e9SAndroid Build Coastguard Worker namespace renderthread { 34*d57664e9SAndroid Build Coastguard Worker 35*d57664e9SAndroid Build Coastguard Worker class VulkanManager; 36*d57664e9SAndroid Build Coastguard Worker 37*d57664e9SAndroid Build Coastguard Worker class VulkanSurface { 38*d57664e9SAndroid Build Coastguard Worker public: 39*d57664e9SAndroid Build Coastguard Worker static VulkanSurface* Create(ANativeWindow* window, ColorMode colorMode, SkColorType colorType, 40*d57664e9SAndroid Build Coastguard Worker sk_sp<SkColorSpace> colorSpace, GrDirectContext* grContext, 41*d57664e9SAndroid Build Coastguard Worker const VulkanManager& vkManager, uint32_t extraBuffers); 42*d57664e9SAndroid Build Coastguard Worker ~VulkanSurface(); 43*d57664e9SAndroid Build Coastguard Worker getCurrentSkSurface()44*d57664e9SAndroid Build Coastguard Worker sk_sp<SkSurface> getCurrentSkSurface() { 45*d57664e9SAndroid Build Coastguard Worker return mCurrentBufferInfo ? mCurrentBufferInfo->skSurface : nullptr; 46*d57664e9SAndroid Build Coastguard Worker } getCurrentPreTransform()47*d57664e9SAndroid Build Coastguard Worker const SkMatrix& getCurrentPreTransform() { return mWindowInfo.preTransform; } 48*d57664e9SAndroid Build Coastguard Worker 49*d57664e9SAndroid Build Coastguard Worker void setColorSpace(sk_sp<SkColorSpace> colorSpace); getPixelSnapMatrix()50*d57664e9SAndroid Build Coastguard Worker const SkM44& getPixelSnapMatrix() const { return mWindowInfo.pixelSnapMatrix; } 51*d57664e9SAndroid Build Coastguard Worker 52*d57664e9SAndroid Build Coastguard Worker private: 53*d57664e9SAndroid Build Coastguard Worker /* 54*d57664e9SAndroid Build Coastguard Worker * All structs/methods in this private section are specifically for use by the VulkanManager 55*d57664e9SAndroid Build Coastguard Worker * 56*d57664e9SAndroid Build Coastguard Worker */ 57*d57664e9SAndroid Build Coastguard Worker friend VulkanManager; 58*d57664e9SAndroid Build Coastguard Worker struct NativeBufferInfo { 59*d57664e9SAndroid Build Coastguard Worker sk_sp<SkSurface> skSurface; 60*d57664e9SAndroid Build Coastguard Worker sp<ANativeWindowBuffer> buffer; 61*d57664e9SAndroid Build Coastguard Worker // The fence is only valid when the buffer is dequeued, and should be 62*d57664e9SAndroid Build Coastguard Worker // -1 any other time. When valid, we own the fd, and must ensure it is 63*d57664e9SAndroid Build Coastguard Worker // closed: either by closing it explicitly when queueing the buffer, 64*d57664e9SAndroid Build Coastguard Worker // or by passing ownership e.g. to ANativeWindow::cancelBuffer(). 65*d57664e9SAndroid Build Coastguard Worker base::unique_fd dequeue_fence; 66*d57664e9SAndroid Build Coastguard Worker bool dequeued = false; 67*d57664e9SAndroid Build Coastguard Worker uint32_t lastPresentedCount = 0; 68*d57664e9SAndroid Build Coastguard Worker bool hasValidContents = false; 69*d57664e9SAndroid Build Coastguard Worker }; 70*d57664e9SAndroid Build Coastguard Worker 71*d57664e9SAndroid Build Coastguard Worker NativeBufferInfo* dequeueNativeBuffer(); getCurrentBufferInfo()72*d57664e9SAndroid Build Coastguard Worker NativeBufferInfo* getCurrentBufferInfo() { return mCurrentBufferInfo; } 73*d57664e9SAndroid Build Coastguard Worker bool presentCurrentBuffer(const SkRect& dirtyRect, int semaphoreFd); 74*d57664e9SAndroid Build Coastguard Worker 75*d57664e9SAndroid Build Coastguard Worker // The width and height are are the logical width and height for when submitting draws to the 76*d57664e9SAndroid Build Coastguard Worker // surface. In reality if the window is rotated the underlying window may have the width and 77*d57664e9SAndroid Build Coastguard Worker // height swapped. logicalWidth()78*d57664e9SAndroid Build Coastguard Worker int logicalWidth() const { return mWindowInfo.size.width(); } logicalHeight()79*d57664e9SAndroid Build Coastguard Worker int logicalHeight() const { return mWindowInfo.size.height(); } 80*d57664e9SAndroid Build Coastguard Worker int getCurrentBuffersAge(); 81*d57664e9SAndroid Build Coastguard Worker 82*d57664e9SAndroid Build Coastguard Worker private: 83*d57664e9SAndroid Build Coastguard Worker /* 84*d57664e9SAndroid Build Coastguard Worker * All code below this line while logically available to VulkanManager should not be treated 85*d57664e9SAndroid Build Coastguard Worker * as private to this class. 86*d57664e9SAndroid Build Coastguard Worker * 87*d57664e9SAndroid Build Coastguard Worker */ 88*d57664e9SAndroid Build Coastguard Worker 89*d57664e9SAndroid Build Coastguard Worker // How many buffers we want to be able to use ourselves. We want 1 in active rendering with 90*d57664e9SAndroid Build Coastguard Worker // 1 more queued, so 2. This will be added to NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, which is 91*d57664e9SAndroid Build Coastguard Worker // how many buffers the consumer needs (eg, 1 for SurfaceFlinger), getting to a typically 92*d57664e9SAndroid Build Coastguard Worker // triple-buffered queue as a result. 93*d57664e9SAndroid Build Coastguard Worker static constexpr uint32_t sTargetBufferCount = 2; 94*d57664e9SAndroid Build Coastguard Worker 95*d57664e9SAndroid Build Coastguard Worker struct WindowInfo { 96*d57664e9SAndroid Build Coastguard Worker SkISize size; 97*d57664e9SAndroid Build Coastguard Worker uint32_t bufferFormat; 98*d57664e9SAndroid Build Coastguard Worker android_dataspace dataspace; 99*d57664e9SAndroid Build Coastguard Worker sk_sp<SkColorSpace> colorspace; 100*d57664e9SAndroid Build Coastguard Worker ColorMode colorMode; 101*d57664e9SAndroid Build Coastguard Worker int transform; 102*d57664e9SAndroid Build Coastguard Worker size_t bufferCount; 103*d57664e9SAndroid Build Coastguard Worker uint64_t windowUsageFlags; 104*d57664e9SAndroid Build Coastguard Worker 105*d57664e9SAndroid Build Coastguard Worker // size of the ANativeWindow if the inverse of transform requires us to swap width/height 106*d57664e9SAndroid Build Coastguard Worker SkISize actualSize; 107*d57664e9SAndroid Build Coastguard Worker // transform to be applied to the SkSurface to map the coordinates to the provided transform 108*d57664e9SAndroid Build Coastguard Worker SkMatrix preTransform; 109*d57664e9SAndroid Build Coastguard Worker SkM44 pixelSnapMatrix; 110*d57664e9SAndroid Build Coastguard Worker }; 111*d57664e9SAndroid Build Coastguard Worker 112*d57664e9SAndroid Build Coastguard Worker VulkanSurface(ANativeWindow* window, const WindowInfo& windowInfo, GrDirectContext* grContext); 113*d57664e9SAndroid Build Coastguard Worker static bool InitializeWindowInfoStruct(ANativeWindow* window, ColorMode colorMode, 114*d57664e9SAndroid Build Coastguard Worker SkColorType colorType, sk_sp<SkColorSpace> colorSpace, 115*d57664e9SAndroid Build Coastguard Worker const VulkanManager& vkManager, uint32_t extraBuffers, 116*d57664e9SAndroid Build Coastguard Worker WindowInfo* outWindowInfo); 117*d57664e9SAndroid Build Coastguard Worker static bool UpdateWindow(ANativeWindow* window, const WindowInfo& windowInfo); 118*d57664e9SAndroid Build Coastguard Worker void releaseBuffers(); 119*d57664e9SAndroid Build Coastguard Worker void invalidateBuffers(); 120*d57664e9SAndroid Build Coastguard Worker 121*d57664e9SAndroid Build Coastguard Worker // TODO: This number comes from ui/BufferQueueDefs. We're not pulling the 122*d57664e9SAndroid Build Coastguard Worker // header in so that we don't need to depend on libui, but we should share 123*d57664e9SAndroid Build Coastguard Worker // this constant somewhere. But right now it's okay to keep here because we 124*d57664e9SAndroid Build Coastguard Worker // can't safely change the slot count anyways. 125*d57664e9SAndroid Build Coastguard Worker static constexpr size_t kNumBufferSlots = 64; 126*d57664e9SAndroid Build Coastguard Worker // TODO: Just use a vector? 127*d57664e9SAndroid Build Coastguard Worker NativeBufferInfo mNativeBuffers[kNumBufferSlots]; 128*d57664e9SAndroid Build Coastguard Worker 129*d57664e9SAndroid Build Coastguard Worker sp<ANativeWindow> mNativeWindow; 130*d57664e9SAndroid Build Coastguard Worker WindowInfo mWindowInfo; 131*d57664e9SAndroid Build Coastguard Worker GrDirectContext* mGrContext; 132*d57664e9SAndroid Build Coastguard Worker 133*d57664e9SAndroid Build Coastguard Worker uint32_t mPresentCount = 0; 134*d57664e9SAndroid Build Coastguard Worker NativeBufferInfo* mCurrentBufferInfo = nullptr; 135*d57664e9SAndroid Build Coastguard Worker }; 136*d57664e9SAndroid Build Coastguard Worker 137*d57664e9SAndroid Build Coastguard Worker } /* namespace renderthread */ 138*d57664e9SAndroid Build Coastguard Worker } /* namespace uirenderer */ 139*d57664e9SAndroid Build Coastguard Worker } /* namespace android */ 140