Home | History | Annotate | Download | only in renderthread
      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 <system/graphics.h>
     19 #include <system/window.h>
     20 #include <vulkan/vulkan.h>
     21 
     22 #include <SkRefCnt.h>
     23 #include <SkSize.h>
     24 
     25 #include "IRenderPipeline.h"
     26 
     27 class SkSurface;
     28 
     29 namespace android {
     30 namespace uirenderer {
     31 namespace renderthread {
     32 
     33 class VulkanManager;
     34 
     35 class VulkanSurface {
     36 public:
     37     static VulkanSurface* Create(ANativeWindow* window, ColorMode colorMode, SkColorType colorType,
     38                                  sk_sp<SkColorSpace> colorSpace, GrContext* grContext,
     39                                  const VulkanManager& vkManager, uint32_t extraBuffers);
     40     ~VulkanSurface();
     41 
     42     sk_sp<SkSurface> getCurrentSkSurface() {
     43         return mCurrentBufferInfo ? mCurrentBufferInfo->skSurface : nullptr;
     44     }
     45     const SkMatrix& getCurrentPreTransform() { return mWindowInfo.preTransform; }
     46 
     47 private:
     48     /*
     49      * All structs/methods in this private section are specifically for use by the VulkanManager
     50      *
     51      */
     52     friend VulkanManager;
     53     struct NativeBufferInfo {
     54         sk_sp<SkSurface> skSurface;
     55         sp<ANativeWindowBuffer> buffer;
     56         // The fence is only valid when the buffer is dequeued, and should be
     57         // -1 any other time. When valid, we own the fd, and must ensure it is
     58         // closed: either by closing it explicitly when queueing the buffer,
     59         // or by passing ownership e.g. to ANativeWindow::cancelBuffer().
     60         int dequeue_fence = -1;
     61         bool dequeued = false;
     62         uint32_t lastPresentedCount = 0;
     63         bool hasValidContents = false;
     64     };
     65 
     66     NativeBufferInfo* dequeueNativeBuffer();
     67     NativeBufferInfo* getCurrentBufferInfo() { return mCurrentBufferInfo; }
     68     bool presentCurrentBuffer(const SkRect& dirtyRect, int semaphoreFd);
     69 
     70     // The width and height are are the logical width and height for when submitting draws to the
     71     // surface. In reality if the window is rotated the underlying window may have the width and
     72     // height swapped.
     73     int logicalWidth() const { return mWindowInfo.size.width(); }
     74     int logicalHeight() const { return mWindowInfo.size.height(); }
     75     int getCurrentBuffersAge();
     76 
     77 private:
     78     /*
     79      * All code below this line while logically available to VulkanManager should not be treated
     80      * as private to this class.
     81      *
     82      */
     83 
     84     // How many buffers we want to be able to use ourselves. We want 1 in active rendering with
     85     // 1 more queued, so 2. This will be added to NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, which is
     86     // how many buffers the consumer needs (eg, 1 for SurfaceFlinger), getting to a typically
     87     // triple-buffered queue as a result.
     88     static constexpr uint32_t sTargetBufferCount = 2;
     89 
     90     struct WindowInfo {
     91         SkISize size;
     92         PixelFormat pixelFormat;
     93         android_dataspace dataspace;
     94         int transform;
     95         size_t bufferCount;
     96         uint64_t windowUsageFlags;
     97 
     98         // size of the ANativeWindow if the inverse of transform requires us to swap width/height
     99         SkISize actualSize;
    100         // transform to be applied to the SkSurface to map the coordinates to the provided transform
    101         SkMatrix preTransform;
    102     };
    103 
    104     VulkanSurface(ANativeWindow* window, const WindowInfo& windowInfo, SkISize minWindowSize,
    105                   SkISize maxWindowSize, GrContext* grContext);
    106     static bool UpdateWindow(ANativeWindow* window, const WindowInfo& windowInfo);
    107     static void ComputeWindowSizeAndTransform(WindowInfo* windowInfo, const SkISize& minSize,
    108                                               const SkISize& maxSize);
    109     void releaseBuffers();
    110 
    111     // TODO: Just use a vector?
    112     NativeBufferInfo mNativeBuffers[android::BufferQueueDefs::NUM_BUFFER_SLOTS];
    113 
    114     sp<ANativeWindow> mNativeWindow;
    115     WindowInfo mWindowInfo;
    116     GrContext* mGrContext;
    117 
    118     uint32_t mPresentCount = 0;
    119     NativeBufferInfo* mCurrentBufferInfo = nullptr;
    120 
    121     const SkISize mMinWindowSize;
    122     const SkISize mMaxWindowSize;
    123 };
    124 
    125 } /* namespace renderthread */
    126 } /* namespace uirenderer */
    127 } /* namespace android */