FireBreath  1.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Pages
NpapiAsyncDrawService.cpp
1 /**********************************************************\
2 Original Author: Gil Gonen
3 
4 Created: Jan 28, 2013
5 License: Dual license model; choose one of two:
6  New BSD License
7  http://www.opensource.org/licenses/bsd-license.php
8  - or -
9  GNU Lesser General Public License, version 2.1
10  http://www.gnu.org/licenses/lgpl-2.1.html
11 
12 Copyright 2013 Gil Gonen and the Firebreath development team
13 \**********************************************************/
14 
15 #include "NpapiAsyncDrawService.h"
16 
17 using namespace FB::Npapi;
18 
19 
20 NpapiAsyncDrawService::NpapiAsyncDrawService(NpapiBrowserHostPtr host)
21  : D3d10AsyncDrawService(host)
22  , m_weakHost(host)
23  , m_current(0)
24 {
25 }
26 
27 // static
28 void NpapiAsyncDrawService::finalizeSurfaces(NpapiBrowserHostWeakPtr weakHost, Surface a, Surface b)
29 {
30  NpapiBrowserHostPtr host = weakHost.lock();
31  if (host) {
32  a.finalize(host.get());
33  b.finalize(host.get());
34  }
35 }
36 
37 NpapiAsyncDrawService::~NpapiAsyncDrawService()
38 {
39  NpapiBrowserHostPtr host = m_weakHost.lock();
40  if (host) {
41  if (host->isMainThread()) {
42  m_surface[0].finalize(host.get());
43  m_surface[1].finalize(host.get());
44  } else {
45  boost::shared_ptr<void> dummy;
46  host->ScheduleOnMainThread(dummy, boost::bind(finalizeSurfaces, m_weakHost, m_surface[0], m_surface[1]));
47  }
48  }
49 }
50 
51 
52 void NpapiAsyncDrawService::present(bool initOnly)
53 {
54  if (m_pBufferMutex) {
55  m_pBufferMutex->ReleaseSync(0);
56  m_pBufferMutex = 0;
57  }
58 
59  NpapiBrowserHostPtr hostPtr = m_weakHost.lock();
60  NpapiBrowserHost* host = hostPtr.get();
61  ID3D10Device1* dev = device();
62  if (!dev || !host)
63  return;
64 
65  int next = 1 - m_current;
66  m_surface[next].makeCurrent(host);
67  int prev = m_current;
68  m_current = next;
69 
70  // create or (if the size has changed) recreate the back buffer
71  if (m_surface[prev].sizeIsDifferent(m_width, m_height)) {
72  if (m_width && m_height) {
73  NPSize dims = { m_width, m_height };
74  m_surface[prev].init(host, &dims);
75  }
76  }
77 
78  // send the back buffer to the render thread
79  {
80  boost::lock_guard<boost::mutex> lock(m_mut);
81  REFIID riid = __uuidof(ID3D10Texture2D);
82  if (m_surface[prev].valid) {
83  HRESULT hr = dev->OpenSharedResource(m_surface[prev].sharedHandle, __uuidof(ID3D10Texture2D), (void**) &m_pBackBuffer.p);
84  if (SUCCEEDED(hr)) {
85  m_pBackBuffer->QueryInterface(&m_pBufferMutex);
86  if (m_pBufferMutex) {
87  hr = m_pBufferMutex->AcquireSync(0, 50);
88  if (FAILED(hr)) {
89  m_pBufferMutex = 0;
90  }
91  }
92 
93  m_cond.notify_one();
94  }
95  }
96  }
97 }
98 
99 NpapiAsyncDrawService::Surface::Surface()
100  : valid(false)
101 {
102  version = 0;
103 }
104 
105 NPError NpapiAsyncDrawService::Surface::init(NpapiBrowserHost* host, NPSize* size)
106 {
107  if (valid) {
108  finalize(host);
109  }
110  NPError result = host->InitAsyncSurface(size, NPImageFormatBGRA32, NULL /*initData*/, this);
111  valid = (0 == result);
112  return result;
113 }
114 
115 void NpapiAsyncDrawService::Surface::finalize(NpapiBrowserHost* host)
116 {
117  if (valid) {
118  host->FinalizeAsyncSurface(this);
119  valid = false;
120  }
121 }
122 
123 void NpapiAsyncDrawService::Surface::makeCurrent(NpapiBrowserHost* host)
124 {
125  host->SetCurrentAsyncSurface(valid ? this : 0, NULL);
126 }
127 
128 bool NpapiAsyncDrawService::Surface::sizeIsDifferent(unsigned width, unsigned height) const
129 {
130  return !valid || height != size.height || width != size.width;
131 }
Provides a FB::BrowserHost implementation for Npapi.