/*
 * Copyright (C) 2016 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 "vsoc_composer.h"

#include <algorithm>
#include <cstdlib>
#include <utility>
#include <vector>

#include <log/log.h>
#include <hardware/hwcomposer.h>
#include <hardware/hwcomposer_defs.h>
#include <libyuv.h>
#include <system/graphics.h>

#include "common/vsoc/lib/screen_region_view.h"

#include "geometry_utils.h"
#include "hwcomposer_common.h"

using vsoc::screen::ScreenRegionView;

namespace cvd {

namespace {

bool LayerNeedsScaling(const vsoc_hwc_layer& layer) {
  int from_w = layer.sourceCrop.right - layer.sourceCrop.left;
  int from_h = layer.sourceCrop.bottom - layer.sourceCrop.top;
  int to_w = layer.displayFrame.right - layer.displayFrame.left;
  int to_h = layer.displayFrame.bottom - layer.displayFrame.top;

  bool not_rot_scale = from_w != to_w || from_h != to_h;
  bool rot_scale = from_w != to_h || from_h != to_w;

  bool needs_rot = layer.transform & HAL_TRANSFORM_ROT_90;

  return needs_rot ? rot_scale : not_rot_scale;
}

bool LayerNeedsBlending(const vsoc_hwc_layer& layer) {
  return layer.blending != HWC_BLENDING_NONE;
}

bool LayerNeedsAttenuation(const vsoc_hwc_layer& layer) {
  return layer.blending == HWC_BLENDING_COVERAGE;
}

struct BufferSpec;
typedef int (*ConverterFunction)(const BufferSpec& src, const BufferSpec& dst,
                                 bool v_flip);
int DoCopy(const BufferSpec& src, const BufferSpec& dst, bool v_flip);
int ConvertFromYV12(const BufferSpec& src, const BufferSpec& dst, bool v_flip);
ConverterFunction GetConverter(uint32_t format) {
  switch (format) {
    case HAL_PIXEL_FORMAT_RGBA_8888:
    case HAL_PIXEL_FORMAT_RGBX_8888:
    case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
      return &DoCopy;

    case HAL_PIXEL_FORMAT_YV12:
      return &ConvertFromYV12;

    // Unsupported formats
    // TODO(jemoreira): Conversion from these formats should be implemented as
    // we find evidence of its usage.
    // case HAL_PIXEL_FORMAT_BGRA_8888:

    // case HAL_PIXEL_FORMAT_RGB_888:
    // case HAL_PIXEL_FORMAT_RGB_565:

    // case HAL_PIXEL_FORMAT_sRGB_A_8888:
    // case HAL_PIXEL_FORMAT_sRGB_X_8888:

    // case HAL_PIXEL_FORMAT_Y8:
    // case HAL_PIXEL_FORMAT_Y16:

    // case HAL_PIXEL_FORMAT_RAW_SENSOR:
    // case HAL_PIXEL_FORMAT_BLOB:

    // case HAL_PIXEL_FORMAT_YCbCr_420_888:
    // case HAL_PIXEL_FORMAT_YCbCr_422_SP:
    // case HAL_PIXEL_FORMAT_YCrCb_420_SP:
    // case HAL_PIXEL_FORMAT_YCbCr_422_I:
    default:
      ALOGW("Unsupported format: 0x%04x, returning null converter function",
            format);
  }
  return NULL;
}

// Whether we support a given format
bool IsFormatSupported(uint32_t format) { return GetConverter(format) != NULL; }

bool CanCompositeLayer(const vsoc_hwc_layer& layer) {
  if (layer.handle == NULL) {
    ALOGW("%s received a layer with a null handler", __FUNCTION__);
    return false;
  }
  int format = reinterpret_cast<const private_handle_t*>(layer.handle)->format;
  if (!IsFormatSupported(format)) {
    ALOGD("Unsupported pixel format: 0x%x, doing software composition instead",
          format);
    return false;
  }
  return true;
}

/*******************************************************************************
Libyuv's convert functions only allow the combination of any rotation (multiple
of 90 degrees) and a vertical flip, but not horizontal flips.
Surfaceflinger's transformations are expressed in terms of a vertical flip, a
horizontal flip and/or a single 90 degrees clockwise rotation (see
NATIVE_WINDOW_TRANSFORM_HINT documentation on system/window.h for more insight).
The following code allows to turn a horizontal flip into a 180 degrees rotation
and a vertical flip.
*******************************************************************************/
libyuv::RotationMode GetRotationFromTransform(uint32_t transform) {
  uint32_t rotation =
      (transform & HAL_TRANSFORM_ROT_90) ? 1 : 0;          // 1 * ROT90 bit
  rotation += (transform & HAL_TRANSFORM_FLIP_H) ? 2 : 0;  // 2 * VFLIP bit
  return static_cast<libyuv::RotationMode>(90 * rotation);
}

bool GetVFlipFromTransform(uint32_t transform) {
  // vertical flip xor horizontal flip
  return ((transform & HAL_TRANSFORM_FLIP_V) >> 1) ^
         (transform & HAL_TRANSFORM_FLIP_H);
}

struct BufferSpec {
  uint8_t* buffer;
  size_t size;
  int width;
  int height;
  int stride;
  int crop_x;
  int crop_y;
  int crop_width;
  int crop_height;
  uint32_t format;

  BufferSpec(uint8_t* buffer, size_t size, int width, int height, int stride)
      : buffer(buffer),
        size(size),
        width(width),
        height(height),
        stride(stride),
        crop_x(0),
        crop_y(0),
        crop_width(width),
        crop_height(height),
        format(HAL_PIXEL_FORMAT_RGBA_8888) {}
};

int ConvertFromYV12(const BufferSpec& src, const BufferSpec& dst, bool v_flip) {
  // use the stride in pixels as the source width
  int stride_in_pixels = src.stride / formatToBytesPerPixel(src.format);

  // The following calculation of plane offsets and alignments are based on
  // swiftshader's Sampler::setTextureLevel() implementation
  // (Renderer/Sampler.cpp:225)
  uint8_t* src_y = src.buffer;
  int stride_y = stride_in_pixels;
  uint8_t* src_v = src_y + stride_y * src.height;
  int stride_v = ScreenRegionView::align(stride_y / 2, 16);
  uint8_t* src_u = src_v + stride_v *  src.height / 2;
  int stride_u = ScreenRegionView::align(stride_y / 2, 16);

  // Adjust for crop
  src_y += src.crop_y * stride_y + src.crop_x;
  src_v += (src.crop_y / 2) * stride_v + (src.crop_x / 2);
  src_u += (src.crop_y / 2) * stride_u + (src.crop_x / 2);
  uint8_t* dst_buffer = dst.buffer + dst.crop_y * dst.stride +
                        dst.crop_x * formatToBytesPerPixel(dst.format);

  // YV12 is the same as I420, with the U and V planes swapped
  return libyuv::I420ToARGB(src_y, stride_y, src_v, stride_v, src_u, stride_u,
                            dst_buffer, dst.stride, dst.crop_width,
                            v_flip ? -dst.crop_height : dst.crop_height);
}

int DoConversion(const BufferSpec& src, const BufferSpec& dst, bool v_flip) {
  return (*GetConverter(src.format))(src, dst, v_flip);
}

int DoCopy(const BufferSpec& src, const BufferSpec& dst, bool v_flip) {
  // Point to the upper left corner of the crop rectangle
  uint8_t* src_buffer = src.buffer + src.crop_y * src.stride +
                        src.crop_x * formatToBytesPerPixel(src.format);
  uint8_t* dst_buffer = dst.buffer + dst.crop_y * dst.stride +
                        dst.crop_x * formatToBytesPerPixel(dst.format);
  int width = src.crop_width;
  int height = src.crop_height;

  if (v_flip) {
    height = -height;
  }

  // HAL formats are named based on the order of the pixel componets on the
  // byte stream, while libyuv formats are named based on the order of those
  // pixel components in an integer written from left to right. So
  // libyuv::FOURCC_ARGB is equivalent to HAL_PIXEL_FORMAT_BGRA_8888.
  return libyuv::ARGBCopy(src_buffer, src.stride, dst_buffer, dst.stride, width,
                          height);
}

int DoRotation(const BufferSpec& src, const BufferSpec& dst,
               libyuv::RotationMode rotation, bool v_flip) {
  // Point to the upper left corner of the crop rectangles
  uint8_t* src_buffer = src.buffer + src.crop_y * src.stride +
                        src.crop_x * formatToBytesPerPixel(src.format);
  uint8_t* dst_buffer = dst.buffer + dst.crop_y * dst.stride +
                        dst.crop_x * formatToBytesPerPixel(dst.format);
  int width = src.crop_width;
  int height = src.crop_height;

  if (v_flip) {
    height = -height;
  }

  return libyuv::ARGBRotate(src_buffer, src.stride, dst_buffer, dst.stride,
                            width, height, rotation);
}

int DoScaling(const BufferSpec& src, const BufferSpec& dst, bool v_flip) {
  // Point to the upper left corner of the crop rectangles
  uint8_t* src_buffer = src.buffer + src.crop_y * src.stride +
                        src.crop_x * formatToBytesPerPixel(src.format);
  uint8_t* dst_buffer = dst.buffer + dst.crop_y * dst.stride +
                        dst.crop_x * formatToBytesPerPixel(dst.format);
  int src_width = src.crop_width;
  int src_height = src.crop_height;
  int dst_width = dst.crop_width;
  int dst_height = dst.crop_height;

  if (v_flip) {
    src_height = -src_height;
  }

  return libyuv::ARGBScale(src_buffer, src.stride, src_width, src_height,
                           dst_buffer, dst.stride, dst_width, dst_height,
                           libyuv::kFilterBilinear);
}

int DoAttenuation(const BufferSpec& src, const BufferSpec& dest, bool v_flip) {
  // Point to the upper left corner of the crop rectangles
  uint8_t* src_buffer = src.buffer + src.crop_y * src.stride +
                        src.crop_x * formatToBytesPerPixel(src.format);
  uint8_t* dst_buffer = dest.buffer + dest.crop_y * dest.stride +
                        dest.crop_x * formatToBytesPerPixel(dest.format);
  int width = dest.crop_width;
  int height = dest.crop_height;

  if (v_flip) {
    height = -height;
  }

  return libyuv::ARGBAttenuate(src_buffer, src.stride, dst_buffer, dest.stride,
                               width, height);
}

int DoBlending(const BufferSpec& src, const BufferSpec& dest, bool v_flip) {
  // Point to the upper left corner of the crop rectangles
  uint8_t* src_buffer = src.buffer + src.crop_y * src.stride +
                        src.crop_x * formatToBytesPerPixel(src.format);
  uint8_t* dst_buffer = dest.buffer + dest.crop_y * dest.stride +
                        dest.crop_x * formatToBytesPerPixel(dest.format);
  int width = dest.crop_width;
  int height = dest.crop_height;

  if (v_flip) {
    height = -height;
  }

  // libyuv's ARGB format is hwcomposer's BGRA format, since blending only cares
  // for the position of alpha in the pixel and not the position of the colors
  // this function is perfectly usable.
  return libyuv::ARGBBlend(src_buffer, src.stride, dst_buffer, dest.stride,
                           dst_buffer, dest.stride, width, height);
}

}  // namespace

void VSoCComposer::CompositeLayer(vsoc_hwc_layer* src_layer,
                                  int buffer_idx) {
  libyuv::RotationMode rotation =
      GetRotationFromTransform(src_layer->transform);

  const private_handle_t* src_priv_handle =
      reinterpret_cast<const private_handle_t*>(src_layer->handle);

  // TODO(jemoreira): Remove the hardcoded fomat.
  bool needs_conversion = src_priv_handle->format != HAL_PIXEL_FORMAT_RGBX_8888;
  bool needs_scaling = LayerNeedsScaling(*src_layer);
  bool needs_rotation = rotation != libyuv::kRotate0;
  bool needs_transpose = needs_rotation && rotation != libyuv::kRotate180;
  bool needs_vflip = GetVFlipFromTransform(src_layer->transform);
  bool needs_attenuation = LayerNeedsAttenuation(*src_layer);
  bool needs_blending = LayerNeedsBlending(*src_layer);
  bool needs_copy = !(needs_conversion || needs_scaling || needs_rotation ||
                      needs_vflip || needs_attenuation || needs_blending);

  uint8_t* src_buffer;
  uint8_t* dst_buffer = reinterpret_cast<uint8_t*>(
      ScreenRegionView::GetInstance()->GetBuffer(buffer_idx));
  int retval = gralloc_module_->lock(
      gralloc_module_, src_layer->handle, GRALLOC_USAGE_SW_READ_OFTEN, 0, 0,
      src_priv_handle->x_res, src_priv_handle->y_res,
      reinterpret_cast<void**>(&src_buffer));
  if (retval) {
    ALOGE("Got error code %d from lock function", retval);
    return;
  }
  if (retval) {
    ALOGE("Got error code %d from lock function", retval);
    // TODO(jemoreira): Use a lock_guard-like object.
    gralloc_module_->unlock(gralloc_module_, src_priv_handle);
    return;
  }

  BufferSpec src_layer_spec(src_buffer, src_priv_handle->total_size,
                            src_priv_handle->x_res, src_priv_handle->y_res,
                            src_priv_handle->stride_in_pixels *
                                formatToBytesPerPixel(src_priv_handle->format));
  src_layer_spec.crop_x = src_layer->sourceCrop.left;
  src_layer_spec.crop_y = src_layer->sourceCrop.top;
  src_layer_spec.crop_width =
      src_layer->sourceCrop.right - src_layer->sourceCrop.left;
  src_layer_spec.crop_height =
      src_layer->sourceCrop.bottom - src_layer->sourceCrop.top;
  src_layer_spec.format = src_priv_handle->format;

  auto screen_view = ScreenRegionView::GetInstance();
  BufferSpec dst_layer_spec(dst_buffer, screen_view->buffer_size(),
                            screen_view->x_res(), screen_view->y_res(),
                            screen_view->line_length());
  dst_layer_spec.crop_x = src_layer->displayFrame.left;
  dst_layer_spec.crop_y = src_layer->displayFrame.top;
  dst_layer_spec.crop_width =
      src_layer->displayFrame.right - src_layer->displayFrame.left;
  dst_layer_spec.crop_height =
      src_layer->displayFrame.bottom - src_layer->displayFrame.top;
  // TODO(jemoreira): Remove the hardcoded fomat.
  dst_layer_spec.format = HAL_PIXEL_FORMAT_RGBX_8888;

  // Add the destination layer to the bottom of the buffer stack
  std::vector<BufferSpec> dest_buffer_stack(1, dst_layer_spec);

  // If more than operation is to be performed, a temporary buffer is needed for
  // each additional operation

  // N operations need N destination buffers, the destination layer (the
  // framebuffer) is one of them, so only N-1 temporary buffers are needed.
  // Vertical flip is not taken into account because it can be done together
  // with any other operation.
  int needed_tmp_buffers = (needs_conversion ? 1 : 0) +
                           (needs_scaling ? 1 : 0) + (needs_rotation ? 1 : 0) +
                           (needs_attenuation ? 1 : 0) +
                           (needs_blending ? 1 : 0) + (needs_copy ? 1 : 0) - 1;

  int x_res = src_layer->displayFrame.right - src_layer->displayFrame.left;
  int y_res = src_layer->displayFrame.bottom - src_layer->displayFrame.top;
  size_t output_frame_size =
      x_res *
    ScreenRegionView::align(y_res * screen_view->bytes_per_pixel(), 16);
  while (needed_tmp_buffers > 0) {
    BufferSpec tmp(RotateTmpBuffer(needed_tmp_buffers), output_frame_size,
                   x_res, y_res,
                   ScreenRegionView::align(
                       x_res * screen_view->bytes_per_pixel(), 16));
    dest_buffer_stack.push_back(tmp);
    needed_tmp_buffers--;
  }

  // Conversion and scaling should always be the first operations, so that every
  // other operation works on equally sized frames (garanteed to fit in the tmp
  // buffers)

  // TODO(jemoreira): We are converting to ARGB as the first step under the
  // assumption that scaling ARGB is faster than scaling I420 (the most common).
  // This should be confirmed with testing.
  if (needs_conversion) {
    BufferSpec& dst_buffer_spec = dest_buffer_stack.back();
    if (needs_scaling || needs_transpose) {
      // If a rotation or a scaling operation are needed the dimensions at the
      // top of the buffer stack are wrong (wrong sizes for scaling, swapped
      // width and height for 90 and 270 rotations).
      // Make width and height match the crop sizes on the source
      int src_width = src_layer_spec.crop_width;
      int src_height = src_layer_spec.crop_height;
      int dst_stride = ScreenRegionView::align(
          src_width * screen_view->bytes_per_pixel(), 16);
      size_t needed_size = dst_stride * src_height;
      dst_buffer_spec.width = src_width;
      dst_buffer_spec.height = src_height;
      // Ajust the stride accordingly
      dst_buffer_spec.stride = dst_stride;
      // Crop sizes also need to be adjusted
      dst_buffer_spec.crop_width = src_width;
      dst_buffer_spec.crop_height = src_height;
      dst_buffer_spec.size = needed_size;
      // crop_x and y are fine at 0, format is already set to match destination

      // In case of a scale, the source frame may be bigger than the default tmp
      // buffer size
      if (needed_size > tmp_buffer_.size() / kNumTmpBufferPieces) {
        dst_buffer_spec.buffer = GetSpecialTmpBuffer(needed_size);
      }
    }
    retval = DoConversion(src_layer_spec, dst_buffer_spec, needs_vflip);
    if (retval) {
      ALOGE("Got error code %d from DoConversion function", retval);
    }
    needs_vflip = false;
    src_layer_spec = dst_buffer_spec;
    dest_buffer_stack.pop_back();
  }

  if (needs_scaling) {
    BufferSpec& dst_buffer_spec = dest_buffer_stack.back();
    if (needs_transpose) {
      // If a rotation is needed, the temporary buffer has the correct size but
      // needs to be transposed and have its stride updated accordingly. The
      // crop sizes also needs to be transposed, but not the x and y since they
      // are both zero in a temporary buffer (and it is a temporary buffer
      // because a rotation will be performed next).
      std::swap(dst_buffer_spec.width, dst_buffer_spec.height);
      std::swap(dst_buffer_spec.crop_width, dst_buffer_spec.crop_height);
      // TODO (jemoreira): Aligment (To align here may cause the needed size to
      // be bigger than the buffer, so care should be taken)
      dst_buffer_spec.stride =
          dst_buffer_spec.width * screen_view->bytes_per_pixel();
    }
    retval = DoScaling(src_layer_spec, dst_buffer_spec, needs_vflip);
    needs_vflip = false;
    if (retval) {
      ALOGE("Got error code %d from DoScaling function", retval);
    }
    src_layer_spec = dst_buffer_spec;
    dest_buffer_stack.pop_back();
  }

  if (needs_rotation) {
    retval = DoRotation(src_layer_spec, dest_buffer_stack.back(), rotation,
                        needs_vflip);
    needs_vflip = false;
    if (retval) {
      ALOGE("Got error code %d from DoTransform function", retval);
    }
    src_layer_spec = dest_buffer_stack.back();
    dest_buffer_stack.pop_back();
  }

  if (needs_attenuation) {
    retval =
        DoAttenuation(src_layer_spec, dest_buffer_stack.back(), needs_vflip);
    needs_vflip = false;
    if (retval) {
      ALOGE("Got error code %d from DoBlending function", retval);
    }
    src_layer_spec = dest_buffer_stack.back();
    dest_buffer_stack.pop_back();
  }

  if (needs_copy) {
    retval = DoCopy(src_layer_spec, dest_buffer_stack.back(), needs_vflip);
    needs_vflip = false;
    if (retval) {
      ALOGE("Got error code %d from DoBlending function", retval);
    }
    src_layer_spec = dest_buffer_stack.back();
    dest_buffer_stack.pop_back();
  }

  // Blending (if needed) should always be the last operation, so that it reads
  // and writes in the destination layer and not some temporary buffer.
  if (needs_blending) {
    retval = DoBlending(src_layer_spec, dest_buffer_stack.back(), needs_vflip);
    needs_vflip = false;
    if (retval) {
      ALOGE("Got error code %d from DoBlending function", retval);
    }
    // Don't need to assign destination to source in the last one
    dest_buffer_stack.pop_back();
  }

  gralloc_module_->unlock(gralloc_module_, src_priv_handle);
}

/* static */ const int VSoCComposer::kNumTmpBufferPieces = 2;

VSoCComposer::VSoCComposer(int64_t vsync_base_timestamp,
                           int32_t vsync_period_ns)
    : BaseComposer(vsync_base_timestamp, vsync_period_ns),
      tmp_buffer_(kNumTmpBufferPieces *
                  ScreenRegionView::GetInstance()->buffer_size()) {}

VSoCComposer::~VSoCComposer() {}

int VSoCComposer::PrepareLayers(size_t num_layers, vsoc_hwc_layer* layers) {
  int composited_layers_count = 0;

  // Loop over layers in inverse order of z-index
  for (size_t layer_index = num_layers; layer_index > 0;) {
    // Decrement here to be able to compare unsigned integer with 0 in the
    // loop condition
    --layer_index;
    if (IS_TARGET_FRAMEBUFFER(layers[layer_index].compositionType)) {
      continue;
    }
    if (layers[layer_index].flags & HWC_SKIP_LAYER) {
      continue;
    }
    if (layers[layer_index].compositionType == HWC_BACKGROUND) {
      layers[layer_index].compositionType = HWC_FRAMEBUFFER;
      continue;
    }
    layers[layer_index].compositionType = HWC_OVERLAY;
    // Hwcomposer cannot draw below software-composed layers, so we need
    // to mark those HWC_FRAMEBUFFER as well.
    for (size_t top_idx = layer_index + 1; top_idx < num_layers; ++top_idx) {
      // layers marked as skip are in a state that makes them unreliable to
      // read, so it's best to assume they cover the whole screen
      if (layers[top_idx].flags & HWC_SKIP_LAYER ||
          (layers[top_idx].compositionType == HWC_FRAMEBUFFER &&
           LayersOverlap(layers[layer_index], layers[top_idx]))) {
        layers[layer_index].compositionType = HWC_FRAMEBUFFER;
        break;
      }
    }
    if (layers[layer_index].compositionType == HWC_OVERLAY &&
        !CanCompositeLayer(layers[layer_index])) {
      layers[layer_index].compositionType = HWC_FRAMEBUFFER;
    }
    if (layers[layer_index].compositionType == HWC_OVERLAY) {
      ++composited_layers_count;
    }
  }
  return composited_layers_count;
}

int VSoCComposer::SetLayers(size_t num_layers, vsoc_hwc_layer* layers) {
  int targetFbs = 0;
  int buffer_idx = NextScreenBuffer();

  // The framebuffer target layer should be composed if at least one layers was
  // marked HWC_FRAMEBUFFER or if it's the only layer in the composition
  // (unlikely)
  bool fb_target = true;
  for (size_t idx = 0; idx < num_layers; idx++) {
    if (layers[idx].compositionType == HWC_FRAMEBUFFER) {
      // At least one was found
      fb_target = true;
      break;
    }
    if (layers[idx].compositionType == HWC_OVERLAY) {
      // Not the only layer in the composition
      fb_target = false;
    }
  }

  // When the framebuffer target needs to be composed, it has to go first.
  if (fb_target) {
    for (size_t idx = 0; idx < num_layers; idx++) {
      if (IS_TARGET_FRAMEBUFFER(layers[idx].compositionType)) {
        CompositeLayer(&layers[idx], buffer_idx);
        break;
      }
    }
  }

  for (size_t idx = 0; idx < num_layers; idx++) {
    if (IS_TARGET_FRAMEBUFFER(layers[idx].compositionType)) {
      ++targetFbs;
    }
    if (layers[idx].compositionType == HWC_OVERLAY &&
        !(layers[idx].flags & HWC_SKIP_LAYER)) {
      CompositeLayer(&layers[idx], buffer_idx);
    }
  }
  if (targetFbs != 1) {
    ALOGW("Saw %zu layers, posted=%d", num_layers, targetFbs);
  }
  Broadcast(buffer_idx);
  return 0;
}

uint8_t* VSoCComposer::RotateTmpBuffer(unsigned int order) {
  return &tmp_buffer_[(order % kNumTmpBufferPieces) * tmp_buffer_.size() /
                      kNumTmpBufferPieces];
}

uint8_t* VSoCComposer::GetSpecialTmpBuffer(size_t needed_size) {
  special_tmp_buffer_.resize(needed_size);
  return &special_tmp_buffer_[0];
}

}  // namespace cvd
