Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright 2018 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  */
     17 #include <jni.h>
     18 #include <set>
     19 #include <unistd.h>
     20 
     21 #include "CameraTestHelpers.h"
     22 #include "ImageReaderTestHelpers.h"
     23 #include "NativeTestHelpers.h"
     24 #include "VulkanTestHelpers.h"
     25 
     26 namespace {
     27 
     28 // Constants used to control test execution.
     29 static constexpr uint32_t kTestImageWidth = 640;
     30 static constexpr uint32_t kTestImageHeight = 480;
     31 static constexpr uint32_t kTestImageFormat = AIMAGE_FORMAT_PRIVATE;
     32 static constexpr uint64_t kTestImageUsage =
     33     AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
     34 static constexpr uint32_t kTestImageCount = 3;
     35 
     36 // Checks if a vector has more than 10 unique values, in which case we consider
     37 // it noisy.
     38 bool isNoisy(const std::vector<uint32_t> &data) {
     39   std::set<uint32_t> values_seen;
     40   for (uint32_t value : data) {
     41     values_seen.insert(value);
     42   }
     43   return values_seen.size() > 10;
     44 }
     45 
     46 } // namespace
     47 
     48 // A basic test which does the following:
     49 // 1) Reads a Camera frame into an AHardwareBuffer.
     50 // 2) Creates a VkImage from this AHardwareBuffer.
     51 // 3) Renders the AHardwareBuffer to a Vulkan RGBA intermediate.
     52 // 4) Reads back the intermediate into a CPU accessible VkBuffer.
     53 // 5) Validates that there is noise in the buffer.
     54 static void loadCameraAndVerifyFrameImport(JNIEnv *env, jclass,
     55                                            jobject assetMgr) {
     56   // Initialize Vulkan.
     57   VkInit init;
     58   if (!init.init()) {
     59     // Could not initialize Vulkan due to lack of device support, skip test.
     60     return;
     61   }
     62   VkImageRenderer renderer(&init, kTestImageWidth, kTestImageHeight,
     63                            VK_FORMAT_R8G8B8A8_UNORM, 4);
     64   ASSERT(renderer.init(env, assetMgr), "Could not init VkImageRenderer.");
     65 
     66   // Initialize image reader and camera helpers.
     67   ImageReaderHelper imageReader(kTestImageWidth, kTestImageHeight,
     68                                 kTestImageFormat, kTestImageUsage,
     69                                 kTestImageCount);
     70   CameraHelper camera;
     71   ASSERT(imageReader.initImageReader() >= 0,
     72          "Failed to initialize image reader.");
     73   ASSERT(camera.initCamera(imageReader.getNativeWindow()) >= 0,
     74          "Failed to initialize camera.");
     75   ASSERT(camera.isCameraReady(), "Camera is not ready.");
     76 
     77   // Acquire an AHardwareBuffer from the camera.
     78   ASSERT(camera.takePicture() >= 0, "Camera failed to take picture.");
     79   AHardwareBuffer *buffer;
     80   int ret = imageReader.getBufferFromCurrentImage(&buffer);
     81   while (ret != 0) {
     82     usleep(1000);
     83     ret = imageReader.getBufferFromCurrentImage(&buffer);
     84   }
     85 
     86   // Impor the AHardwareBuffer into Vulkan.
     87   VkAHardwareBufferImage vkImage(&init);
     88   ASSERT(vkImage.init(buffer, true /* useExternalFormat */), "Could not initialize VkAHardwareBufferImage.");
     89 
     90   // Render the AHardwareBuffer using Vulkan and read back the result.
     91   std::vector<uint32_t> imageData;
     92   ASSERT(renderer.renderImageAndReadback(
     93              vkImage.image(), vkImage.sampler(), vkImage.view(),
     94              vkImage.semaphore(), vkImage.isSamplerImmutable(), &imageData),
     95          "Could not render/read-back Vulkan pixels.");
     96 
     97   // Ensure that we see noise.
     98   ASSERT(isNoisy(imageData), "Camera data should be noisy.");
     99 }
    100 
    101 static JNINativeMethod gMethods[] = {
    102     {"loadCameraAndVerifyFrameImport", "(Landroid/content/res/AssetManager;)V",
    103      (void *)loadCameraAndVerifyFrameImport},
    104 };
    105 
    106 int register_android_graphics_cts_CameraVulkanGpuTest(JNIEnv *env) {
    107   jclass clazz = env->FindClass("android/graphics/cts/CameraVulkanGpuTest");
    108   return env->RegisterNatives(clazz, gMethods,
    109                               sizeof(gMethods) / sizeof(JNINativeMethod));
    110 }
    111