// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

library fuchsia.hardware.ge2d;
using zx;
using fuchsia.hardware.camera;
using fuchsia.hardware.camerahwaccel;
using fuchsia.sysmem;

enum Ge2dRotation : uint8 {
    ROTATION_0 = 0;
    ROTATION_90 = 1;
    ROTATION_180 = 2;
    ROTATION_270 = 3;
    MAX = 4;
};

struct ResizeInfo {
    // TODO (jsasinowski): Determine if this is a src or dst rect & document accordingly.
    fuchsia.hardware.camera.Rect crop; // Initially this will be the same size as the canvas.
    // Rotation is needed for video playback
    Ge2dRotation output_rotation;
};

resource struct WaterMarkInfo {
    // Where to place WaterMark on the input image
    uint32 loc_x;
    uint32 loc_y;
    // Watermark Image Format - must be R8G8B8A8
    fuchsia.sysmem.ImageFormat_2 wm_image_format;
    // Watermark VMO must have non-premultiplied alpha.
    zx.handle:VMO watermark_vmo;
    // The global alpha is multiplied with the input watermark per-pixel alpha to get the
    // watermark's actual alpha value.
    float32 global_alpha;
};

[Transport = "Banjo", BanjoLayout = "ddk-protocol"]
protocol Ge2d {
    // Registers the buffer collections and configuration which the GE2D will be using
    // for this task and also the callback functions for a particular task and
    // returns a task index.
    // |input_buffer_collection| : Pool of VMOs as input to the GE2D.
    // |output_buffer_collection| : Pool of VMOs as output to the GE2D.
    // [info] : Resize Info
    // [input_image_format] : Input Image format
    // [output_image_format_table] : Output Image format
    // [output_image_format_index] : Initialize with this output image format.
    // |frame_callback| : Called when GE2D is done processing the frame.
    // |res_callback|   : Called when GE2D is done changing the resoultion.
    // |task_remove_callback| : Called when GE2D is done removing a task.
    // @Returns: |task_index| : Task ID for this task.
    //
    // The resize task only supports dynamically changing the output resolution
    // (not the input resolution). Since the input resolution never changes after
    // Init, we just pass a single input ImageFormat.
    InitTaskResize(fuchsia.sysmem.BufferCollectionInfo_2 input_buffer_collection,
                   fuchsia.sysmem.BufferCollectionInfo_2 output_buffer_collection,
                   ResizeInfo info,
                   fuchsia.sysmem.ImageFormat_2 image_format,
                   vector<fuchsia.sysmem.ImageFormat_2>:MAX output_image_format_table,
                   uint32 output_image_format_index,
                   fuchsia.hardware.camerahwaccel.HwAccelFrameCallback frame_callback,
                   fuchsia.hardware.camerahwaccel.HwAccelResChangeCallback res_callback,
                   fuchsia.hardware.camerahwaccel.HwAccelRemoveTaskCallback task_remove_callback)
        -> (zx.status s, uint32 task_index);

    // The WaterMark task only supports changing the Input And Output resolution
    // together. Moreover this operation changes both the input and output
    // resolution, setting them to the same new resolution. Therefore we pass
    // a single ImageFormat table, with a single ImageFormat table index, which
    // applies to both input and output frames. Watermark info is per-resolution.
    InitTaskWaterMark(fuchsia.sysmem.BufferCollectionInfo_2 input_buffer_collection,
                      fuchsia.sysmem.BufferCollectionInfo_2 output_buffer_collection,
                      vector<WaterMarkInfo>:MAX info,
                      vector<fuchsia.sysmem.ImageFormat_2>:MAX image_format_table,
                      uint32 image_format_index,
                      fuchsia.hardware.camerahwaccel.HwAccelFrameCallback frame_callback,
                      fuchsia.hardware.camerahwaccel.HwAccelResChangeCallback res_callback,
                      fuchsia.hardware.camerahwaccel.HwAccelRemoveTaskCallback task_remove_callback)
        -> (zx.status s, uint32 task_index);

    // This watermark task modifies the images in the input buffer collection.  The output image
    // index will be identical with the input image index, so the caller must manage the output
    // buffer lifetimes.  Watermark info is per-resolution.
    InitTaskInPlaceWaterMark(fuchsia.sysmem.BufferCollectionInfo_2 buffer_collection,
                             vector<WaterMarkInfo>:MAX info,
                             vector<fuchsia.sysmem.ImageFormat_2>:MAX image_format_table,
                             uint32 image_format_index,
                             fuchsia.hardware.camerahwaccel.HwAccelFrameCallback frame_callback,
                             fuchsia.hardware.camerahwaccel.HwAccelResChangeCallback res_callback,
                             fuchsia.hardware.camerahwaccel.HwAccelRemoveTaskCallback task_remove_callback)
        -> (zx.status s, uint32 task_index);

    // De-registers the task.
    RemoveTask(uint32 task_index);

    // Processes the frame at |input_buffer_index| within |input_buffer_collection|
    // in the task corresponding to |task_index| and stores the ouput in the
    // |output_buffer_collection| after applying the correct configuration.
    // After processing we call the callback registered for this task with the
    // output buffer index. |capture_timestamp| is forwarded to derived frames.
    ProcessFrame(uint32 task_index, uint32 input_buffer_index, uint64 capture_timestamp) -> (zx.status s);

    // Releases the frame |buffer_index| from the |output_buffer_collection| to be
    // used again by the GE2D driver again. Not valid for in-place watermark tasks.
    ReleaseFrame(uint32 task_index, uint32 buffer_index);

    // Set the output resolution. This call sets the resolution on all the output canvas
    // ids, for the specified task. This operation is queued to the worker thread to be
    // performed in sequence.
    SetOutputResolution(uint32 task_index, uint32 new_output_image_format_index) -> (zx.status s);

    // Similar to SetOutputResolution, this call sets the input and output resolution on all
    // input and output canvas ids.
    SetInputAndOutputResolution(uint32 task_index, uint32 new_image_format_index) -> (zx.status s);

    // Sets/Changes the crop rectangle (on a Resize Task). Typically called when
    // the camera controller is notified by Smart Framing to crop and resize.
    SetCropRect(uint32 task_index, fuchsia.hardware.camera.Rect crop);
};
