// Copyright 2016 The Cobalt Authors. All Rights Reserved.
//
// 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 <directfb.h>

#include "starboard/blitter.h"
#include "starboard/log.h"
#include "starboard/memory.h"
#include "starboard/shared/directfb/blitter_internal.h"

namespace {
int WordToByteOrder(int bytes_per_pixel, int byte_index) {
// Since DirectFB stores color in word-order but we wish to output in
// byte-order fomat, we perform that conversion here.
#if SB_IS_LITTLE_ENDIAN
  return bytes_per_pixel - 1 - byte_index;
#else
  return byte_index;
#endif
}

void SwizzlePixels(void* in_data,
                   void* out_data,
                   int width,
                   int height,
                   int in_bytes_per_pixel,
                   int in_pitch_in_bytes,
                   int out_pitch_in_bytes,
                   int channel_1,
                   int channel_2,
                   int channel_3,
                   int channel_4) {
  uint8_t* in_data_bytes = static_cast<uint8_t*>(in_data);
  uint8_t* out_data_bytes = static_cast<uint8_t*>(out_data);

  bool needs_swizzle = true;
  if (WordToByteOrder(in_bytes_per_pixel, channel_1) == 0 &&
      WordToByteOrder(in_bytes_per_pixel, channel_2) == 1 &&
      WordToByteOrder(in_bytes_per_pixel, channel_3) == 2 &&
      WordToByteOrder(in_bytes_per_pixel, channel_4) == 3) {
    SB_DCHECK(in_bytes_per_pixel == 4);
    needs_swizzle = false;
  }

  for (int y = 0; y < height; ++y) {
    if (needs_swizzle) {
      for (int x = 0; x < width; ++x) {
        out_data_bytes[0] =
            in_data_bytes[WordToByteOrder(in_bytes_per_pixel, channel_1)];
        out_data_bytes[1] =
            in_data_bytes[WordToByteOrder(in_bytes_per_pixel, channel_2)];
        out_data_bytes[2] =
            in_data_bytes[WordToByteOrder(in_bytes_per_pixel, channel_3)];
        out_data_bytes[3] =
            in_data_bytes[WordToByteOrder(in_bytes_per_pixel, channel_4)];

        out_data_bytes += 4;
        in_data_bytes += in_bytes_per_pixel;
      }

      // Increment through the gab between the input data pitch and its
      // width * bpp.
      in_data_bytes += in_pitch_in_bytes - width * in_bytes_per_pixel;
      out_data_bytes += out_pitch_in_bytes - width * 4;
    } else {
      SbMemoryCopy(out_data_bytes, in_data_bytes, width * 4);
      in_data_bytes += in_pitch_in_bytes;
      out_data_bytes += out_pitch_in_bytes;
    }
  }
}
}  // namespace

bool SbBlitterDownloadSurfacePixels(SbBlitterSurface surface,
                                    SbBlitterPixelDataFormat pixel_format,
                                    int pitch_in_bytes,
                                    void* out_pixel_data) {
  if (!SbBlitterIsSurfaceValid(surface)) {
    SB_DLOG(ERROR) << __FUNCTION__ << ": Invalid surface.";
    return false;
  }
  if (out_pixel_data == NULL) {
    SB_DLOG(ERROR) << __FUNCTION__ << ": |out_pixel_data| cannot be NULL.";
    return false;
  }
  if (!SbBlitterIsPixelFormatSupportedByDownloadSurfacePixels(surface,
                                                              pixel_format)) {
    SB_DLOG(ERROR) << __FUNCTION__ << ": Unsupported pixel format.";
    return false;
  }
  if (pitch_in_bytes <
      surface->info.width * SbBlitterBytesPerPixelForFormat(pixel_format)) {
    SB_DLOG(ERROR)
        << __FUNCTION__
        << ": Output pitch must be at least as large as (width * BPP).";
    return false;
  }

  {
    // Wait for all previously flushed draw calls to be executed.
    starboard::ScopedLock lock(surface->device->mutex);
    if (surface->device->dfb->WaitIdle(surface->device->dfb) != DFB_OK) {
      SB_DLOG(ERROR) << __FUNCTION__ << ": WaitIdle() failed.";
      return false;
    }
  }

  IDirectFBSurface* dfb_surface = surface->surface;

  DFBSurfacePixelFormat surface_pixel_format;
  dfb_surface->GetPixelFormat(dfb_surface, &surface_pixel_format);

  // Lock the surface's pixels and then copy them out into the user's provided
  // memory.  Swizzel the pixel's bytes as we copy them out, if necessary.
  void* data;
  int surface_pitch_in_bytes;
  if (dfb_surface->Lock(dfb_surface, DSLF_READ, &data,
                        &surface_pitch_in_bytes) != DFB_OK) {
    SB_DLOG(ERROR) << __FUNCTION__ << ": Error calling Lock().";
    return false;
  }

  switch (DFB_PIXELFORMAT_INDEX(surface_pixel_format)) {
    case DFB_PIXELFORMAT_INDEX(DSPF_ARGB): {
      switch (pixel_format) {
        case kSbBlitterPixelDataFormatARGB8: {
          SwizzlePixels(data, out_pixel_data, surface->info.width,
                        surface->info.height, 4, surface_pitch_in_bytes,
                        pitch_in_bytes, 0, 1, 2, 3);
        } break;
        case kSbBlitterPixelDataFormatBGRA8: {
          SwizzlePixels(data, out_pixel_data, surface->info.width,
                        surface->info.height, 4, surface_pitch_in_bytes,
                        pitch_in_bytes, 3, 2, 1, 0);
        } break;
        case kSbBlitterPixelDataFormatRGBA8: {
          SwizzlePixels(data, out_pixel_data, surface->info.width,
                        surface->info.height, 4, surface_pitch_in_bytes,
                        pitch_in_bytes, 1, 2, 3, 0);
        } break;
        default: { SB_NOTREACHED(); }
      }
    } break;

    case DFB_PIXELFORMAT_INDEX(DSPF_A8): {
      // Convert A8 to either ARGB, BGRA, or RGBA.
      SwizzlePixels(data, out_pixel_data, surface->info.width,
                    surface->info.height, 1, surface_pitch_in_bytes,
                    pitch_in_bytes, 0, 0, 0, 0);
    } break;

    default: {
      SB_DLOG(ERROR) << __FUNCTION__ << ": Unsupported pixel format index ("
                     << DFB_PIXELFORMAT_INDEX(surface_pixel_format) << ").";
      dfb_surface->Unlock(dfb_surface);
      return false;
    }
  }

  // Okay the copy is complete, unlock the pixels and carry on.
  dfb_surface->Unlock(dfb_surface);

  return true;
}
