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

#include "remoting/host/capturer.h"

#include <windows.h>

#include "base/memory/scoped_ptr.h"
#include "remoting/host/capturer_helper.h"
#include "remoting/host/differ.h"
#include "ui/gfx/rect.h"

namespace remoting {

namespace {

// CapturerGdi captures 32bit RGB using GDI.
//
// CapturerGdi is double-buffered as required by Capturer. See
// remoting/host/capturer.h.
class CapturerGdi : public Capturer {
 public:
  CapturerGdi();
  virtual ~CapturerGdi();

  // Capturer interface.
  virtual void ScreenConfigurationChanged() OVERRIDE;
  virtual media::VideoFrame::Format pixel_format() const OVERRIDE;
  virtual void ClearInvalidRects() OVERRIDE;
  virtual void InvalidateRects(const InvalidRects& inval_rects) OVERRIDE;
  virtual void InvalidateScreen(const gfx::Size& size) OVERRIDE;
  virtual void InvalidateFullScreen() OVERRIDE;
  virtual void CaptureInvalidRects(CaptureCompletedCallback* callback) OVERRIDE;
  virtual const gfx::Size& size_most_recent() const OVERRIDE;

 private:
  struct VideoFrameBuffer {
    VideoFrameBuffer(void* data, const gfx::Size& size, int bytes_per_pixel,
                     int bytes_per_row)
      : data(data), size(size), bytes_per_pixel(bytes_per_pixel),
        bytes_per_row(bytes_per_row) {
    }
    VideoFrameBuffer() {
      data = 0;
      size = gfx::Size(0, 0);
      bytes_per_pixel = 0;
      bytes_per_row = 0;
    }
    void* data;
    gfx::Size size;
    int bytes_per_pixel;
    int bytes_per_row;
  };

  // Make sure that the current buffer has the same size as the screen.
  void UpdateBufferCapture(const gfx::Size& size);

  // Allocate memory for a buffer of a given size, freeing any memory previously
  // allocated for that buffer.
  void ReallocateBuffer(int buffer_index, const gfx::Size& size);

  void CalculateInvalidRects();
  void CaptureRects(const InvalidRects& rects,
                    CaptureCompletedCallback* callback);

  void ReleaseBuffers();
  // Generates an image in the current buffer.
  void CaptureImage();

  // Gets the current screen size and calls ScreenConfigurationChanged
  // if the screen size has changed.
  void MaybeChangeScreenConfiguration();

  // Gets the screen size.
  gfx::Size GetScreenSize();

  // A thread-safe list of invalid rectangles, and the size of the most
  // recently captured screen.
  CapturerHelper helper;

  // There are two buffers for the screen images, as required by Capturer.
  static const int kNumBuffers = 2;
  VideoFrameBuffer buffers_[kNumBuffers];

  // Gdi specific information about screen.
  HDC desktop_dc_;
  HDC memory_dc_;
  HBITMAP target_bitmap_[kNumBuffers];

  // The screen size attached to the device contexts through which the screen
  // is captured.
  gfx::Size dc_size_;

  // The current buffer with valid data for reading.
  int current_buffer_;

  // Format of pixels returned in buffer.
  media::VideoFrame::Format pixel_format_;

  // Class to calculate the difference between two screen bitmaps.
  scoped_ptr<Differ> differ_;

  // True if we should force a fullscreen capture.
  bool capture_fullscreen_;

  DISALLOW_COPY_AND_ASSIGN(CapturerGdi);
};

// 3780 pixels per meter is equivalent to 96 DPI, typical on desktop monitors.
static const int kPixelsPerMeter = 3780;
// 32 bit RGBA is 4 bytes per pixel.
static const int kBytesPerPixel = 4;

CapturerGdi::CapturerGdi()
    : desktop_dc_(NULL),
      memory_dc_(NULL),
      dc_size_(0, 0),
      current_buffer_(0),
      pixel_format_(media::VideoFrame::RGB32),
      capture_fullscreen_(true) {
  memset(target_bitmap_, 0, sizeof(target_bitmap_));
  memset(buffers_, 0, sizeof(buffers_));
  ScreenConfigurationChanged();
}

CapturerGdi::~CapturerGdi() {
  ReleaseBuffers();
}

media::VideoFrame::Format CapturerGdi::pixel_format() const {
  return pixel_format_;
}

void CapturerGdi::ClearInvalidRects() {
  helper.ClearInvalidRects();
}

void CapturerGdi::InvalidateRects(const InvalidRects& inval_rects) {
  helper.InvalidateRects(inval_rects);
}

void CapturerGdi::InvalidateScreen(const gfx::Size& size) {
  helper.InvalidateScreen(size);
}

void CapturerGdi::InvalidateFullScreen() {
  helper.InvalidateFullScreen();
}

void CapturerGdi::CaptureInvalidRects(CaptureCompletedCallback* callback) {
  CalculateInvalidRects();
  InvalidRects inval_rects;
  helper.SwapInvalidRects(inval_rects);
  CaptureRects(inval_rects, callback);
}

const gfx::Size& CapturerGdi::size_most_recent() const {
  return helper.size_most_recent();
}

void CapturerGdi::ReleaseBuffers() {
  for (int i = kNumBuffers - 1; i >= 0; i--) {
    if (target_bitmap_[i]) {
      DeleteObject(target_bitmap_[i]);
      target_bitmap_[i] = NULL;
    }
    if (buffers_[i].data) {
      DeleteObject(buffers_[i].data);
      buffers_[i].data = NULL;
    }
  }

  desktop_dc_ = NULL;
  if (memory_dc_) {
    DeleteDC(memory_dc_);
    memory_dc_ = NULL;
  }
}

void CapturerGdi::ScreenConfigurationChanged() {
  // We poll for screen configuration changes, so ignore notifications.
}

void CapturerGdi::UpdateBufferCapture(const gfx::Size& size) {
  // Make sure the DCs have the correct dimensions.
  if (size != dc_size_) {
    // TODO(simonmorris): screen dimensions changing isn't equivalent to needing
    // a new DC, but it's good enough for now.
    desktop_dc_ = GetDC(GetDesktopWindow());
    if (memory_dc_)
      DeleteDC(memory_dc_);
    memory_dc_ = CreateCompatibleDC(desktop_dc_);
    dc_size_ = size;
  }

  // Make sure the current bitmap has the correct dimensions.
  if (size != buffers_[current_buffer_].size) {
    ReallocateBuffer(current_buffer_, size);
    capture_fullscreen_ = true;
  }
}

void CapturerGdi::ReallocateBuffer(int buffer_index, const gfx::Size& size) {
  // Delete any previously constructed bitmap.
  if (target_bitmap_[buffer_index]) {
    DeleteObject(target_bitmap_[buffer_index]);
    target_bitmap_[buffer_index] = NULL;
  }
  if (buffers_[buffer_index].data) {
    DeleteObject(buffers_[buffer_index].data);
    buffers_[buffer_index].data = NULL;
  }

  // Create a bitmap to keep the desktop image.
  int rounded_width = (size.width() + 3) & (~3);

  // Dimensions of screen.
  pixel_format_ = media::VideoFrame::RGB32;
  int bytes_per_row = rounded_width * kBytesPerPixel;

  // Create a device independent bitmap (DIB) that is the same size.
  BITMAPINFO bmi;
  memset(&bmi, 0, sizeof(bmi));
  bmi.bmiHeader.biHeight = -size.height();
  bmi.bmiHeader.biWidth = size.width();
  bmi.bmiHeader.biPlanes = 1;
  bmi.bmiHeader.biBitCount = kBytesPerPixel * 8;
  bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
  bmi.bmiHeader.biSizeImage = bytes_per_row * size.height();
  bmi.bmiHeader.biXPelsPerMeter = kPixelsPerMeter;
  bmi.bmiHeader.biYPelsPerMeter = kPixelsPerMeter;

  // Create memory for the buffers.
  target_bitmap_[buffer_index] =
      CreateDIBSection(desktop_dc_, &bmi, DIB_RGB_COLORS,
                       static_cast<void**>(&buffers_[buffer_index].data),
                       NULL, 0);
  buffers_[buffer_index].size = gfx::Size(bmi.bmiHeader.biWidth,
                                          std::abs(bmi.bmiHeader.biHeight));
  buffers_[buffer_index].bytes_per_pixel = bmi.bmiHeader.biBitCount / 8;
  buffers_[buffer_index].bytes_per_row =
      bmi.bmiHeader.biSizeImage / std::abs(bmi.bmiHeader.biHeight);
}

void CapturerGdi::CalculateInvalidRects() {
  CaptureImage();

  const VideoFrameBuffer& current = buffers_[current_buffer_];
  if (helper.IsCaptureFullScreen(current.size))
    capture_fullscreen_ = true;

  if (capture_fullscreen_) {
    InvalidateScreen(current.size);
    capture_fullscreen_ = false;
    return;
  }

  // Find the previous and current screens.
  int prev_buffer_id = current_buffer_ - 1;
  if (prev_buffer_id < 0) {
    prev_buffer_id = kNumBuffers - 1;
  }
  const VideoFrameBuffer& prev = buffers_[prev_buffer_id];

  // Maybe the previous and current screens can't be differenced.
  if ((current.size != prev.size) ||
      (current.bytes_per_pixel != prev.bytes_per_pixel) ||
      (current.bytes_per_row != prev.bytes_per_row)) {
    InvalidateScreen(current.size);
    return;
  }

  // Make sure the differencer is set up correctly for these previous and
  // current screens.
  if (!differ_.get() ||
      (differ_->width() != current.size.width()) ||
      (differ_->height() != current.size.height()) ||
      (differ_->bytes_per_pixel() != current.bytes_per_pixel) ||
      (differ_->bytes_per_row() != current.bytes_per_row)) {
    differ_.reset(new Differ(current.size.width(), current.size.height(),
      current.bytes_per_pixel, current.bytes_per_row));
  }

  InvalidRects rects;
  differ_->CalcDirtyRects(prev.data, current.data, &rects);

  InvalidateRects(rects);
}

void CapturerGdi::CaptureRects(const InvalidRects& rects,
                               CaptureCompletedCallback* callback) {
  scoped_ptr<CaptureCompletedCallback> callback_deleter(callback);

  const VideoFrameBuffer& buffer = buffers_[current_buffer_];
  current_buffer_ = (current_buffer_ + 1) % kNumBuffers;

  DataPlanes planes;
  planes.data[0] = static_cast<uint8*>(buffer.data);
  planes.strides[0] = buffer.bytes_per_row;

  scoped_refptr<CaptureData> data(new CaptureData(planes,
                                                  buffer.size,
                                                  pixel_format_));
  data->mutable_dirty_rects() = rects;

  helper.set_size_most_recent(data->size());

  callback->Run(data);
}

void CapturerGdi::CaptureImage() {
  // Make sure the structures we use to capture the image have the correct size.
  UpdateBufferCapture(GetScreenSize());

  // Select the target bitmap into the memory dc.
  SelectObject(memory_dc_, target_bitmap_[current_buffer_]);

  // And then copy the rect from desktop to memory.
  BitBlt(memory_dc_, 0, 0, buffers_[current_buffer_].size.width(),
      buffers_[current_buffer_].size.height(), desktop_dc_, 0, 0,
      SRCCOPY | CAPTUREBLT);
}

gfx::Size CapturerGdi::GetScreenSize() {
  return gfx::Size(GetSystemMetrics(SM_CXSCREEN),
                   GetSystemMetrics(SM_CYSCREEN));
}

}  // namespace

// static
Capturer* Capturer::Create() {
  return new CapturerGdi();
}

}  // namespace remoting
