// Copyright (c) 2012 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.

#ifndef UI_SURFACE_ACCELERATED_SURFACE_WIN_H_
#define UI_SURFACE_ACCELERATED_SURFACE_WIN_H_

#include <d3d9.h>

#include "base/callback_forward.h"
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "base/time/time.h"
#include "base/win/scoped_comptr.h"
#include "ui/events/latency_info.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/size.h"
#include "ui/surface/surface_export.h"

class PresentThread;

namespace gfx {
class Rect;
}

namespace media {
class VideoFrame;
}

class SURFACE_EXPORT AcceleratedPresenter
    : public base::RefCountedThreadSafe<AcceleratedPresenter> {
 public:
  typedef base::Callback<void(bool,
                              base::TimeTicks,
                              base::TimeDelta,
                              const ui::LatencyInfo&)> CompletionTask;

  explicit AcceleratedPresenter(gfx::PluginWindowHandle window);

  static void SetAdapterLUID(uint64 adapter_luid);

  // Returns a thread safe reference to the presenter for the given window or
  // null is no such presenter exists. The thread safe refptr ensures the
  // presenter will not be destroyed. This can be called on any thread.
  static scoped_refptr<AcceleratedPresenter> GetForWindow(
      gfx::PluginWindowHandle window);

  // Schedule a frame to be presented. The completion callback will be invoked
  // when it is safe to write to the surface on another thread. The lock for
  // this surface will be held while the completion callback runs. This can be
  // called on any thread.
  void AsyncPresentAndAcknowledge(
      const gfx::Size& size,
      int64 surface_handle,
      const ui::LatencyInfo& latency_info,
      const CompletionTask& completion_task);

  // Returns true if the swap chain has been created and initialized.  This can
  // be called on any thread.
  bool IsSwapChainInitialized() const;

  // Schedule the presenter to free all its resources. This can be called on any
  // thread.
  void Suspend();

  // Indicates that the presenter has become invisible.
  void WasHidden();

  // Called when the Windows session is locked or unlocked.
  void SetIsSessionLocked(bool locked);

  // Schedule the presenter to release its reference to the shared surface.
  void ReleaseSurface();

  // The public member functions are called on the main thread.
  void Present(HDC dc);
  void AsyncCopyTo(const gfx::Rect& src_subrect,
                   const gfx::Size& dst_size,
                   const base::Callback<void(bool, const SkBitmap&)>& callback);
  void AsyncCopyToVideoFrame(
      const gfx::Rect& src_subrect,
      const scoped_refptr<media::VideoFrame>& target,
      const base::Callback<void(bool)>& callback);
  void Invalidate();

  // Destroy any D3D resources owned by the given present thread. Called on
  // the given present thread.
  void ResetPresentThread(PresentThread* present_thread);

 private:
  friend class base::RefCountedThreadSafe<AcceleratedPresenter>;

  ~AcceleratedPresenter();

  // These member functions are called on the PresentThread with which the
  // presenter has affinity.
  void DoPresentAndAcknowledge(
      const gfx::Size& size,
      int64 surface_handle,
      const ui::LatencyInfo& latency_info,
      const CompletionTask& completion_task);
  void DoSuspend();
  void DoPresent(const base::Closure& composite_task);
  void DoReleaseSurface();
  void DoCopyToAndAcknowledge(
      const gfx::Rect& src_subrect,
      const gfx::Size& dst_size,
      scoped_refptr<base::SingleThreadTaskRunner> callback_runner,
      const base::Callback<void(bool, const SkBitmap&)>& callback);
  void DoCopyToVideoFrameAndAcknowledge(
      const gfx::Rect& src_subrect,
      const scoped_refptr<media::VideoFrame>& target,
      const scoped_refptr<base::SingleThreadTaskRunner>& callback_runner,
      const base::Callback<void(bool)>& callback);
  bool DoCopyToYUV(const gfx::Rect& src_subrect,
                   const scoped_refptr<media::VideoFrame>& frame);
  bool DoCopyToARGB(const gfx::Rect& src_subrect,
                    const gfx::Size& dst_size,
                    SkBitmap* bitmap);

  void PresentWithGDI(HDC dc);
  gfx::Size GetWindowSize();

  // This function tries to guess whether Direct3D will be able to reliably
  // present to the window. When the window is resizing, presenting with
  // Direct3D causes other regions of the window rendered with GDI to
  // flicker transparent / non-transparent.
  bool CheckDirect3DWillWork();

  // The thread with which this presenter has affinity.
  PresentThread* const present_thread_;

  // The window that is presented to.
  gfx::PluginWindowHandle window_;

  // UI thread can wait on this event to ensure a present is finished.
  base::WaitableEvent event_;

  // The current size of the swap chain. This is only accessed on the thread
  // with which the surface has affinity. The swap chain size is rounded up and
  // is not necessarily the same as the window size.
  gfx::Size quantized_size_;

  // The size of the window on the last present. This is used to trigger the
  // compositor instead of presenting the last frame in the case where the
  // window has been resized.
  gfx::Size present_size_;

  // This is a shared texture that is being presented from.
  base::win::ScopedComPtr<IDirect3DTexture9> source_texture_;

  // The swap chain is presented to the child window. Copy semantics
  // are used so it is possible to represent it to quickly validate the window.
  base::win::ScopedComPtr<IDirect3DSwapChain9> swap_chain_;

  // Whether the window is hidden or has not been presented to since it was
  // last hidden.
  bool hidden_;

  // Set to true if the first present after the tab is unhidden needs to be done
  // with GDI.
  bool do_present_with_GDI_;

  // Set to true when the Windows session is locked.
  bool is_session_locked_;

  // These are used to detect when the window is resizing. For some reason,
  // presenting with D3D while the window resizes causes those parts not
  // drawn with D3D (e.g. with GDI) to flicker visible / invisible.
  // http://crbug.com/120904
  gfx::Size last_window_size_;
  base::Time last_window_resize_time_;

  ui::LatencyInfo latency_info_;

  DISALLOW_COPY_AND_ASSIGN(AcceleratedPresenter);
};

class SURFACE_EXPORT AcceleratedSurface {
 public:
  AcceleratedSurface(gfx::PluginWindowHandle window);
  ~AcceleratedSurface();

  // Synchronously present a frame with no acknowledgement.
  void Present(HDC dc);

  // Returns true if the surface is fully initialized and has been presented to
  // at least once.
  bool IsReadyForCopy() const;

  // Transfer the contents of the surface to an SkBitmap, and invoke a callback
  // with the result.
  void AsyncCopyTo(const gfx::Rect& src_subrect,
                   const gfx::Size& dst_size,
                   const base::Callback<void(bool, const SkBitmap&)>& callback);

  // Transfer the contents of the surface to an already-allocated YV12
  // VideoFrame, and invoke a callback to indicate success or failure.
  void AsyncCopyToVideoFrame(
      const gfx::Rect& src_subrect,
      const scoped_refptr<media::VideoFrame>& target,
      const base::Callback<void(bool)>& callback);

  // Temporarily release resources until a new surface is asynchronously
  // presented. Present will not be able to represent the last surface after
  // calling this and will return false.
  void Suspend();

  // Indicates that the surface has become invisible.
  void WasHidden();

  // Called when the Windows session in locked or unlocked.
  void SetIsSessionLocked(bool locked);

 private:
  const scoped_refptr<AcceleratedPresenter> presenter_;
  DISALLOW_COPY_AND_ASSIGN(AcceleratedSurface);
};

#endif  // UI_SURFACE_ACCELERATED_SURFACE_WIN_H_
