Add non-interop Vulkan functor

An interop Vulkan functor already exists. It will call the OpenGL
functor and use AHardwareBuffer to translate the OpenGL textures into
something which can be used in Vulkan.

This CL adds the frameworks for a non-interop Vulkan functor. This
functor is not yet complete (and as a result cannot yet be tested). This
is just setting the stage for future work.

Test: This is dead code and cannot yet be tested.
BUG=115613038

Change-Id: I2b87c86cb511abb961c31c17c2fbbc085b07ca4a
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index da77b99..ed7d5e5 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -171,6 +171,7 @@
         "pipeline/skia/SkiaRecordingCanvas.cpp",
         "pipeline/skia/SkiaVulkanPipeline.cpp",
         "pipeline/skia/VectorDrawableAtlas.cpp",
+        "pipeline/skia/VkFunctorDrawable.cpp",
         "pipeline/skia/VkInteropFunctorDrawable.cpp",
         "renderstate/RenderState.cpp",
         "renderthread/CacheManager.cpp",
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index b682ab0..b56c3ef 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -25,6 +25,7 @@
 #include "pipeline/skia/AnimatedDrawables.h"
 #include "pipeline/skia/GLFunctorDrawable.h"
 #include "pipeline/skia/VkInteropFunctorDrawable.h"
+#include "pipeline/skia/VkFunctorDrawable.h"
 
 namespace android {
 namespace uirenderer {
@@ -124,6 +125,8 @@
                                              uirenderer::GlFunctorLifecycleListener* listener) {
     FunctorDrawable* functorDrawable;
     if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
+        // TODO(cblume) use VkFunctorDrawable instead of VkInteropFunctorDrawable here when the
+        // interop is disabled/moved.
         functorDrawable = mDisplayList->allocateDrawable<VkInteropFunctorDrawable>(functor,
                 listener, asSkCanvas());
     } else {
diff --git a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
new file mode 100644
index 0000000..71ad5e1
--- /dev/null
+++ b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "VkFunctorDrawable.h"
+#include <private/hwui/DrawVkInfo.h>
+
+#include "thread/ThreadBase.h"
+#include "utils/TimeUtils.h"
+#include <GrBackendDrawableInfo.h>
+#include <thread>
+#include <utils/Color.h>
+#include <utils/Trace.h>
+#include <utils/TraceUtils.h>
+#include <SkImage.h>
+#include <vk/GrVkTypes.h>
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+VkFunctorDrawHandler::VkFunctorDrawHandler(Functor *functor)
+    : INHERITED()
+    , mFunctor(functor) {}
+
+VkFunctorDrawHandler::~VkFunctorDrawHandler() {
+    // TODO(cblume) Fill in the DrawVkInfo parameters.
+    (*mFunctor)(DrawVkInfo::kModePostComposite, nullptr);
+}
+
+void VkFunctorDrawHandler::draw(const GrBackendDrawableInfo& info) {
+    ATRACE_CALL();
+
+    GrVkDrawableInfo vulkan_info;
+    if (!info.getVkDrawableInfo(&vulkan_info)) {
+        return;
+    }
+
+    DrawVkInfo draw_vk_info;
+    // TODO(cblume) Fill in the rest of the parameters and test the actual call.
+    draw_vk_info.isLayer = true;
+
+    (*mFunctor)(DrawVkInfo::kModeComposite, &draw_vk_info);
+}
+
+VkFunctorDrawable::VkFunctorDrawable(Functor* functor, GlFunctorLifecycleListener* listener,
+                                     SkCanvas* canvas)
+    : FunctorDrawable(functor, listener, canvas) {}
+
+VkFunctorDrawable::~VkFunctorDrawable() = default;
+
+void VkFunctorDrawable::syncFunctor() const {
+    (*mFunctor)(DrawVkInfo::kModeSync, nullptr);
+}
+
+void VkFunctorDrawable::onDraw(SkCanvas* /*canvas*/) {
+    LOG_ALWAYS_FATAL("VkFunctorDrawable::onDraw() should never be called.");
+    // Instead of calling onDraw(), the call should come from onSnapGpuDrawHandler.
+}
+
+std::unique_ptr<FunctorDrawable::GpuDrawHandler> VkFunctorDrawable::onSnapGpuDrawHandler(
+    GrBackendApi backendApi, const SkMatrix& matrix) {
+    if (backendApi != GrBackendApi::kVulkan) {
+        return nullptr;
+    }
+    std::unique_ptr<VkFunctorDrawHandler> draw(new VkFunctorDrawHandler(mFunctor));
+    return std::move(draw);
+}
+
+}  // namespace skiapipeline
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/pipeline/skia/VkFunctorDrawable.h b/libs/hwui/pipeline/skia/VkFunctorDrawable.h
new file mode 100644
index 0000000..5cd1314
--- /dev/null
+++ b/libs/hwui/pipeline/skia/VkFunctorDrawable.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "FunctorDrawable.h"
+
+#include <utils/RefBase.h>
+#include <ui/GraphicBuffer.h>
+#include <SkImageInfo.h>
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+/**
+ * This draw handler will be returned by VkFunctorDrawable's onSnapGpuDrawHandler. It allows us to
+ * issue Vulkan commands while the command buffer is being flushed.
+ */
+class VkFunctorDrawHandler : public FunctorDrawable::GpuDrawHandler {
+public:
+    explicit VkFunctorDrawHandler(Functor* functor);
+    ~VkFunctorDrawHandler() override;
+
+    void draw(const GrBackendDrawableInfo& info) override;
+private:
+    typedef GpuDrawHandler INHERITED;
+
+    Functor* mFunctor;
+};
+
+/**
+ * This drawable wraps a Vulkan functor enabling it to be recorded into a list of Skia drawing
+ * commands.
+ */
+class VkFunctorDrawable : public FunctorDrawable {
+public:
+    VkFunctorDrawable(Functor* functor, GlFunctorLifecycleListener* listener,
+            SkCanvas* canvas);
+    ~VkFunctorDrawable() override;
+
+    void syncFunctor() const override;
+
+protected:
+    // SkDrawable functions:
+    void onDraw(SkCanvas* canvas) override;
+    std::unique_ptr<FunctorDrawable::GpuDrawHandler> onSnapGpuDrawHandler(GrBackendApi backendApi,
+            const SkMatrix& matrix) override;
+};
+
+}  // namespace skiapipeline
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/private/hwui/DrawVkInfo.h b/libs/hwui/private/hwui/DrawVkInfo.h
new file mode 100644
index 0000000..019950f
--- /dev/null
+++ b/libs/hwui/private/hwui/DrawVkInfo.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HWUI_DRAW_VK_INFO_H
+#define ANDROID_HWUI_DRAW_VK_INFO_H
+
+#include <vulkan/vulkan.h>
+
+namespace android {
+namespace uirenderer {
+
+/**
+ * Structure used by VulkanRenderer::callDrawVKFunction() to pass and receive data from Vulkan
+ * functors.
+ */
+struct DrawVkInfo {
+    // Input: current width/height of destination surface
+    int width;
+    int height;
+
+    // Input: is the render target an FBO
+    bool isLayer;
+
+    // Input: current transform matrix, in OpenGL format
+    float transform[16];
+
+    // Input: WebView should do its main compositing draws into this. It cannot do anything that
+    // would require stopping the render pass.
+    VkCommandBuffer secondaryCommandBuffer;
+
+    // Input: The main color attachment index where secondaryCommandBuffer will eventually be
+    // submitted.
+    uint32_t colorAttachmentIndex;
+
+    // Input: A render pass which will be compatible to the one which the secondaryCommandBuffer
+    // will be submitted into.
+    VkRenderPass compatibleRenderPass;
+
+    // Input: Format of the destination surface.
+    VkFormat format;
+
+    // Input: Color space transfer params
+    float G;
+    float A;
+    float B;
+    float C;
+    float D;
+    float E;
+    float F;
+
+    // Input: Color space transformation from linear RGB to D50-adapted XYZ
+    float matrix[9];
+
+    // Input: current clip rect
+    int clipLeft;
+    int clipTop;
+    int clipRight;
+    int clipBottom;
+
+    /**
+     * Values used as the "what" parameter of the functor.
+     */
+    enum Mode {
+        // Called once at WebView start
+        kModeInit,
+        // Called when things need to be re-created
+        kModeReInit,
+        // Notifies the app that the composite functor will be called soon. This allows WebView to
+        // begin work early.
+        kModePreComposite,
+        // Do the actual composite work
+        kModeComposite,
+        // This allows WebView to begin using the previously submitted objects in future work.
+        kModePostComposite,
+        // Invoked every time the UI thread pushes over a frame to the render thread and the owning
+        // view has a dirty display list*. This is a signal to sync any data that needs to be
+        // shared between the UI thread and the render thread. During this time the UI thread is
+        // blocked.
+        kModeSync
+    };
+
+    /**
+     * Values used by Vulkan functors to tell the framework what to do next.
+     */
+    enum Status {
+        // The functor is done
+        kStatusDone = 0x0,
+    };
+};  // struct DrawVkInfo
+
+}  // namespace uirenderer
+}  // namespace android
+
+#endif  // ANDROID_HWUI_DRAW_VK_INFO_H