widget/windows/RemoteBackbuffer.h
author Chris Martin <cmartin@mozilla.com>
Thu, 13 Feb 2020 03:59:13 +0000
changeset 513675 71e63781b38cbde024a9057553cae96c98e5ecb2
child 514676 d69f53c5968cf816bf07c5664b274863c155d19f
permissions -rw-r--r--
Bug 1604412 - Enable remote backbuffer GDI compositing r=jmathies,jld This change adds new "remote backbuffer" logic when compositing without HW acceleration on Windows (IE compositing through Cairo using the Win32 GDI) A new piece of shared memory is created between the GPU process and the UI process, and the GPU process sends requests to the UI process to first "borrow" a properly-sized buffer to draw into, and then sends a "present" request to tell the UI process to actually blit the buffer to the Win32 window. This is needed for the GPU sandbox to work, since Windows rightly doesn't allow the untrusted GPU process to directly draw the contents of a window owned by the trusted UI process. Differential Revision: https://phabricator.services.mozilla.com/D61370

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef widget_windows_RemoteBackbuffer_h
#define widget_windows_RemoteBackbuffer_h

#include <thread>
#include <windows.h>
#include "mozilla/Maybe.h"

namespace mozilla {
namespace widget {
namespace remote_backbuffer {

struct SharedData;
struct BorrowResponseData;
struct PresentResponseData;
class SharedImage;
class PresentableSharedImage;

class Provider {
 public:
  Provider();
  ~Provider();

  bool Initialize(HWND aWindowHandle, DWORD aTargetProcessId);

  Maybe<RemoteBackbufferHandles> CreateRemoteHandles();

  Provider(const Provider&) = delete;
  Provider(Provider&&) = delete;
  Provider& operator=(const Provider&) = delete;
  Provider& operator=(Provider&&) = delete;

 private:
  void ThreadMain();

  void HandleBorrowRequest(BorrowResponseData* aResponseData);
  void HandlePresentRequest(PresentResponseData* aResponseData);

  HWND mWindowHandle;
  DWORD mTargetProcessId;
  HANDLE mFileMapping;
  HANDLE mRequestReadyEvent;
  HANDLE mResponseReadyEvent;
  SharedData* mSharedDataPtr;
  bool mStopServiceThread;
  std::thread mServiceThread;
  std::unique_ptr<PresentableSharedImage> mBackbuffer;
};

class Client {
 public:
  Client();
  ~Client();

  bool Initialize(const RemoteBackbufferHandles& aRemoteHandles);

  already_AddRefed<gfx::DrawTarget> BorrowDrawTarget();
  bool PresentDrawTarget();

  Client(const Client&) = delete;
  Client(Client&&) = delete;
  Client& operator=(const Client&) = delete;
  Client& operator=(Client&&) = delete;

 private:
  HANDLE mFileMapping;
  HANDLE mRequestReadyEvent;
  HANDLE mResponseReadyEvent;
  SharedData* mSharedDataPtr;
  std::unique_ptr<SharedImage> mBackbuffer;
};

}  // namespace remote_backbuffer
}  // namespace widget
}  // namespace mozilla

#endif  // widget_windows_RemoteBackbuffer_h