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