/*
 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/desktop_capture/linux/x_server_pixel_buffer.h"

#include <X11/Xutil.h>
#include <stdint.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#include "modules/desktop_capture/desktop_frame.h"
#include "modules/desktop_capture/linux/window_list_utils.h"
#include "modules/desktop_capture/linux/x_error_trap.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"

namespace webrtc {

namespace {

// Returns the number of bits |mask| has to be shifted left so its last
// (most-significant) bit set becomes the most-significant bit of the word.
// When |mask| is 0 the function returns 31.
uint32_t MaskToShift(uint32_t mask) {
  int shift = 0;
  if ((mask & 0xffff0000u) == 0) {
    mask <<= 16;
    shift += 16;
  }
  if ((mask & 0xff000000u) == 0) {
    mask <<= 8;
    shift += 8;
  }
  if ((mask & 0xf0000000u) == 0) {
    mask <<= 4;
    shift += 4;
  }
  if ((mask & 0xc0000000u) == 0) {
    mask <<= 2;
    shift += 2;
  }
  if ((mask & 0x80000000u) == 0)
    shift += 1;

  return shift;
}

// Returns true if |image| is in RGB format.
bool IsXImageRGBFormat(XImage* image) {
  return image->bits_per_pixel == 32 && image->red_mask == 0xff0000 &&
         image->green_mask == 0xff00 && image->blue_mask == 0xff;
}

// We expose two forms of blitting to handle variations in the pixel format.
// In FastBlit(), the operation is effectively a memcpy.
void FastBlit(XImage* x_image,
              uint8_t* src_pos,
              const DesktopRect& rect,
              DesktopFrame* frame) {
  int src_stride = x_image->bytes_per_line;
  int dst_x = rect.left(), dst_y = rect.top();

  uint8_t* dst_pos = frame->data() + frame->stride() * dst_y;
  dst_pos += dst_x * DesktopFrame::kBytesPerPixel;

  int height = rect.height();
  int row_bytes = rect.width() * DesktopFrame::kBytesPerPixel;
  for (int y = 0; y < height; ++y) {
    memcpy(dst_pos, src_pos, row_bytes);
    src_pos += src_stride;
    dst_pos += frame->stride();
  }
}

void SlowBlit(XImage* x_image,
              uint8_t* src_pos,
              const DesktopRect& rect,
              DesktopFrame* frame) {
  int src_stride = x_image->bytes_per_line;
  int dst_x = rect.left(), dst_y = rect.top();
  int width = rect.width(), height = rect.height();

  uint32_t red_mask = x_image->red_mask;
  uint32_t green_mask = x_image->red_mask;
  uint32_t blue_mask = x_image->blue_mask;

  uint32_t red_shift = MaskToShift(red_mask);
  uint32_t green_shift = MaskToShift(green_mask);
  uint32_t blue_shift = MaskToShift(blue_mask);

  int bits_per_pixel = x_image->bits_per_pixel;

  uint8_t* dst_pos = frame->data() + frame->stride() * dst_y;
  dst_pos += dst_x * DesktopFrame::kBytesPerPixel;
  // TODO(hclam): Optimize, perhaps using MMX code or by converting to
  // YUV directly.
  // TODO(sergeyu): This code doesn't handle XImage byte order properly and
  // won't work with 24bpp images. Fix it.
  for (int y = 0; y < height; y++) {
    uint32_t* dst_pos_32 = reinterpret_cast<uint32_t*>(dst_pos);
    uint32_t* src_pos_32 = reinterpret_cast<uint32_t*>(src_pos);
    uint16_t* src_pos_16 = reinterpret_cast<uint16_t*>(src_pos);
    for (int x = 0; x < width; x++) {
      // Dereference through an appropriately-aligned pointer.
      uint32_t pixel;
      if (bits_per_pixel == 32) {
        pixel = src_pos_32[x];
      } else if (bits_per_pixel == 16) {
        pixel = src_pos_16[x];
      } else {
        pixel = src_pos[x];
      }
      uint32_t r = (pixel & red_mask) << red_shift;
      uint32_t g = (pixel & green_mask) << green_shift;
      uint32_t b = (pixel & blue_mask) << blue_shift;
      // Write as 32-bit RGB.
      dst_pos_32[x] =
          ((r >> 8) & 0xff0000) | ((g >> 16) & 0xff00) | ((b >> 24) & 0xff);
    }
    dst_pos += frame->stride();
    src_pos += src_stride;
  }
}

}  // namespace

XServerPixelBuffer::XServerPixelBuffer() {}

XServerPixelBuffer::~XServerPixelBuffer() {
  Release();
}

void XServerPixelBuffer::Release() {
  if (x_image_) {
    XDestroyImage(x_image_);
    x_image_ = nullptr;
  }
  if (x_shm_image_) {
    XDestroyImage(x_shm_image_);
    x_shm_image_ = nullptr;
  }
  if (shm_pixmap_) {
    XFreePixmap(display_, shm_pixmap_);
    shm_pixmap_ = 0;
  }
  if (shm_gc_) {
    XFreeGC(display_, shm_gc_);
    shm_gc_ = nullptr;
  }

  ReleaseSharedMemorySegment();

  window_ = 0;
}

void XServerPixelBuffer::ReleaseSharedMemorySegment() {
  if (!shm_segment_info_)
    return;
  if (shm_segment_info_->shmaddr != nullptr)
    shmdt(shm_segment_info_->shmaddr);
  if (shm_segment_info_->shmid != -1)
    shmctl(shm_segment_info_->shmid, IPC_RMID, 0);
  delete shm_segment_info_;
  shm_segment_info_ = nullptr;
}

bool XServerPixelBuffer::Init(Display* display, Window window) {
  Release();
  display_ = display;

  XWindowAttributes attributes;
  if (!GetWindowRect(display_, window, &window_rect_, &attributes)) {
    return false;
  }

  window_ = window;
  InitShm(attributes);

  return true;
}

void XServerPixelBuffer::InitShm(const XWindowAttributes& attributes) {
  Visual* default_visual = attributes.visual;
  int default_depth = attributes.depth;

  int major, minor;
  Bool have_pixmaps;
  if (!XShmQueryVersion(display_, &major, &minor, &have_pixmaps)) {
    // Shared memory not supported. CaptureRect will use the XImage API instead.
    return;
  }

  bool using_shm = false;
  shm_segment_info_ = new XShmSegmentInfo;
  shm_segment_info_->shmid = -1;
  shm_segment_info_->shmaddr = nullptr;
  shm_segment_info_->readOnly = False;
  x_shm_image_ = XShmCreateImage(display_, default_visual, default_depth,
                                 ZPixmap, 0, shm_segment_info_,
                                 window_rect_.width(), window_rect_.height());
  if (x_shm_image_) {
    shm_segment_info_->shmid =
        shmget(IPC_PRIVATE, x_shm_image_->bytes_per_line * x_shm_image_->height,
               IPC_CREAT | 0600);
    if (shm_segment_info_->shmid != -1) {
      void* shmat_result = shmat(shm_segment_info_->shmid, 0, 0);
      if (shmat_result != reinterpret_cast<void*>(-1)) {
        shm_segment_info_->shmaddr = reinterpret_cast<char*>(shmat_result);
        x_shm_image_->data = shm_segment_info_->shmaddr;

        XErrorTrap error_trap(display_);
        using_shm = XShmAttach(display_, shm_segment_info_);
        XSync(display_, False);
        if (error_trap.GetLastErrorAndDisable() != 0)
          using_shm = false;
        if (using_shm) {
          RTC_LOG(LS_VERBOSE)
              << "Using X shared memory segment " << shm_segment_info_->shmid;
        }
      }
    } else {
      RTC_LOG(LS_WARNING) << "Failed to get shared memory segment. "
                             "Performance may be degraded.";
    }
  }

  if (!using_shm) {
    RTC_LOG(LS_WARNING)
        << "Not using shared memory. Performance may be degraded.";
    ReleaseSharedMemorySegment();
    return;
  }

  if (have_pixmaps)
    have_pixmaps = InitPixmaps(default_depth);

  shmctl(shm_segment_info_->shmid, IPC_RMID, 0);
  shm_segment_info_->shmid = -1;

  RTC_LOG(LS_VERBOSE) << "Using X shared memory extension v" << major << "."
                      << minor << " with" << (have_pixmaps ? "" : "out")
                      << " pixmaps.";
}

bool XServerPixelBuffer::InitPixmaps(int depth) {
  if (XShmPixmapFormat(display_) != ZPixmap)
    return false;

  {
    XErrorTrap error_trap(display_);
    shm_pixmap_ = XShmCreatePixmap(
        display_, window_, shm_segment_info_->shmaddr, shm_segment_info_,
        window_rect_.width(), window_rect_.height(), depth);
    XSync(display_, False);
    if (error_trap.GetLastErrorAndDisable() != 0) {
      // |shm_pixmap_| is not not valid because the request was not processed
      // by the X Server, so zero it.
      shm_pixmap_ = 0;
      return false;
    }
  }

  {
    XErrorTrap error_trap(display_);
    XGCValues shm_gc_values;
    shm_gc_values.subwindow_mode = IncludeInferiors;
    shm_gc_values.graphics_exposures = False;
    shm_gc_ = XCreateGC(display_, window_,
                        GCSubwindowMode | GCGraphicsExposures, &shm_gc_values);
    XSync(display_, False);
    if (error_trap.GetLastErrorAndDisable() != 0) {
      XFreePixmap(display_, shm_pixmap_);
      shm_pixmap_ = 0;
      shm_gc_ = 0;  // See shm_pixmap_ comment above.
      return false;
    }
  }

  return true;
}

bool XServerPixelBuffer::IsWindowValid() const {
  XWindowAttributes attributes;
  {
    XErrorTrap error_trap(display_);
    if (!XGetWindowAttributes(display_, window_, &attributes) ||
        error_trap.GetLastErrorAndDisable() != 0) {
      return false;
    }
  }
  return true;
}

void XServerPixelBuffer::Synchronize() {
  if (shm_segment_info_ && !shm_pixmap_) {
    // XShmGetImage can fail if the display is being reconfigured.
    XErrorTrap error_trap(display_);
    // XShmGetImage fails if the window is partially out of screen.
    xshm_get_image_succeeded_ =
        XShmGetImage(display_, window_, x_shm_image_, 0, 0, AllPlanes);
  }
}

bool XServerPixelBuffer::CaptureRect(const DesktopRect& rect,
                                     DesktopFrame* frame) {
  RTC_DCHECK_LE(rect.right(), window_rect_.width());
  RTC_DCHECK_LE(rect.bottom(), window_rect_.height());

  XImage* image;
  uint8_t* data;

  if (shm_segment_info_ && (shm_pixmap_ || xshm_get_image_succeeded_)) {
    if (shm_pixmap_) {
      XCopyArea(display_, window_, shm_pixmap_, shm_gc_, rect.left(),
                rect.top(), rect.width(), rect.height(), rect.left(),
                rect.top());
      XSync(display_, False);
    }

    image = x_shm_image_;
    data = reinterpret_cast<uint8_t*>(image->data) +
           rect.top() * image->bytes_per_line +
           rect.left() * image->bits_per_pixel / 8;

  } else {
    if (x_image_)
      XDestroyImage(x_image_);
    x_image_ = XGetImage(display_, window_, rect.left(), rect.top(),
                         rect.width(), rect.height(), AllPlanes, ZPixmap);
    if (!x_image_)
      return false;

    image = x_image_;
    data = reinterpret_cast<uint8_t*>(image->data);
  }

  if (IsXImageRGBFormat(image)) {
    FastBlit(image, data, rect, frame);
  } else {
    SlowBlit(image, data, rect, frame);
  }

  return true;
}

}  // namespace webrtc
