summaryrefslogtreecommitdiffstats
path: root/ui/surface
diff options
context:
space:
mode:
Diffstat (limited to 'ui/surface')
-rw-r--r--ui/surface/accelerated_surface_win.cc181
-rw-r--r--ui/surface/accelerated_surface_win.h6
2 files changed, 21 insertions, 166 deletions
diff --git a/ui/surface/accelerated_surface_win.cc b/ui/surface/accelerated_surface_win.cc
index ceec12e..2fadfc0 100644
--- a/ui/surface/accelerated_surface_win.cc
+++ b/ui/surface/accelerated_surface_win.cc
@@ -232,7 +232,6 @@ class AcceleratedPresenterMap {
scoped_refptr<AcceleratedPresenter> CreatePresenter(gfx::NativeWindow window);
void RemovePresenter(const scoped_refptr<AcceleratedPresenter>& presenter);
scoped_refptr<AcceleratedPresenter> GetPresenter(gfx::NativeWindow window);
-
private:
base::Lock lock_;
typedef std::map<gfx::NativeWindow, AcceleratedPresenter*> PresenterMap;
@@ -240,42 +239,6 @@ class AcceleratedPresenterMap {
DISALLOW_COPY_AND_ASSIGN(AcceleratedPresenterMap);
};
-// Presents a swap chain on the main thread without blocking.
-class PresentOnMainThread :
- public base::RefCountedThreadSafe<PresentOnMainThread> {
- public:
- enum Result {
- INCOMPLETE,
- COMPLETE,
- FAILED
- };
-
- PresentOnMainThread(
- const base::win::ScopedComPtr<IDirect3DSwapChain9Ex>& swap_chain,
- HWND window,
- const gfx::Size& size);
-
- // This is called by a present thread. It returns when either the present
- // has completed or the timeout has elapsed. It returns whether the
- // present completed and atomically cancels it if it times out. That is,
- // if it returns INCOMPLETE, the present definitely will not happen.
- Result WaitForCompletion(base::TimeDelta timeout);
-
- // This is posted on the main thread. It either presents or reschedules
- // itself if the present would block.
- void DoPresent();
-
- private:
- base::win::ScopedComPtr<IDirect3DSwapChain9Ex> swap_chain_;
- HWND window_;
- gfx::Size size_;
- base::WaitableEvent completion_event_;
- bool canceled_;
- Result result_;
- base::Lock lock_;
- DISALLOW_COPY_AND_ASSIGN(PresentOnMainThread);
-};
-
base::LazyInstance<PresentThreadPool>
g_present_thread_pool = LAZY_INSTANCE_INITIALIZER;
@@ -454,72 +417,11 @@ scoped_refptr<AcceleratedPresenter> AcceleratedPresenterMap::GetPresenter(
return it->second;
}
-PresentOnMainThread::PresentOnMainThread(
- const base::win::ScopedComPtr<IDirect3DSwapChain9Ex>& swap_chain,
- HWND window,
- const gfx::Size& size)
- : swap_chain_(swap_chain),
- window_(window),
- size_(size),
- completion_event_(false, false),
- canceled_(false),
- result_(INCOMPLETE) {
-}
-
-PresentOnMainThread::Result PresentOnMainThread::WaitForCompletion(
- base::TimeDelta timeout) {
- completion_event_.TimedWait(timeout);
-
- base::AutoLock locked(lock_);
- canceled_ = true;
- return result_;
-}
-
-void PresentOnMainThread::DoPresent() {
- TRACE_EVENT0("gpu", "PresentOnMainThread");
-
- base::AutoLock locked(lock_);
-
- if (canceled_)
- return;
-
- DWM_TIMING_INFO info = {
- sizeof(DWM_TIMING_INFO)
- };
- HRESULT hr = DwmGetCompositionTimingInfo(window_, &info);
- if (SUCCEEDED(hr) && info.cRefreshNextPresented > 0) {
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- base::Bind(&PresentOnMainThread::DoPresent,
- this),
- base::TimeDelta::FromMilliseconds(1));
- return;
- }
-
- RECT rect = {
- 0, 0,
- size_.width(), size_.height()
- };
-
- hr = swap_chain_->Present(&rect, &rect, window_, NULL, 0);
-
- // For latency_tests.cc:
- UNSHIPPED_TRACE_EVENT_INSTANT0("test_gpu", "CompositorSwapBuffersComplete");
-
- if (SUCCEEDED(hr))
- result_ = COMPLETE;
- else
- result_ = FAILED;
-
- completion_event_.Signal();
-}
-
AcceleratedPresenter::AcceleratedPresenter(gfx::NativeWindow window)
: present_thread_(g_present_thread_pool.Pointer()->NextThread()),
window_(window),
event_(false, false),
hidden_(true) {
- main_message_loop_ = base::MessageLoopProxy::current();
}
scoped_refptr<AcceleratedPresenter> AcceleratedPresenter::GetForWindow(
@@ -581,6 +483,7 @@ bool AcceleratedPresenter::DoRealPresent(HDC dc)
if (!window_)
return true;
+
RECT window_rect;
GetClientRect(window_, &window_rect);
if (window_rect.right != present_size_.width() ||
@@ -612,13 +515,12 @@ bool AcceleratedPresenter::DoRealPresent(HDC dc)
};
{
- TRACE_EVENT0("gpu", "Present");
+ TRACE_EVENT0("gpu", "PresentEx");
hr = swap_chain_->Present(&present_rect,
&present_rect,
window_,
NULL,
- 0);
-
+ D3DPRESENT_INTERVAL_IMMEDIATE);
// For latency_tests.cc:
UNSHIPPED_TRACE_EVENT_INSTANT0("test_gpu", "CompositorSwapBuffersComplete");
if (FAILED(hr))
@@ -825,22 +727,16 @@ void AcceleratedPresenter::DoPresentAndAcknowledge(
parameters.BackBufferHeight = quantized_size.height();
parameters.BackBufferCount = 1;
parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
- parameters.hDeviceWindow = window_;
+ parameters.hDeviceWindow = GetShellWindow();
parameters.Windowed = TRUE;
parameters.Flags = 0;
parameters.PresentationInterval = GetPresentationInterval();
parameters.SwapEffect = D3DSWAPEFFECT_COPY;
swap_chain_ = NULL;
-
- base::win::ScopedComPtr<IDirect3DSwapChain9> swap_chain;
HRESULT hr = present_thread_->device()->CreateAdditionalSwapChain(
&parameters,
- swap_chain.Receive());
- if (FAILED(hr))
- return;
-
- hr = swap_chain_.QueryFrom(swap_chain);
+ swap_chain_.Receive());
if (FAILED(hr))
return;
}
@@ -920,69 +816,19 @@ void AcceleratedPresenter::DoPresentAndAcknowledge(
default_render_target->Release();
}
- // Issue a query that indicate when the texture has been
- // copied to the swap chain on the GPU. Do it before presenting so it
- // doesn't wait for the present as well.
hr = present_thread_->query()->Issue(D3DISSUE_END);
if (FAILED(hr))
return;
- hr = present_thread_->query()->GetData(NULL, 0, D3DGETDATA_FLUSH);
- if (FAILED(hr))
- return;
- hidden_ = false;
present_size_ = size;
- // If Aero is enabled, the present must take place on the main thread because
- // if the the main thread uses GDI while the present is taking place, things
- // flicker.
- DWM_TIMING_INFO timing_info = {
- sizeof(DWM_TIMING_INFO)
- };
- hr = DwmGetCompositionTimingInfo(window_, &timing_info);
- if (SUCCEEDED(hr)) {
- scoped_refptr<PresentOnMainThread> present_on_main_thread(
- new PresentOnMainThread(swap_chain_,
- window_,
- present_size_));
- main_message_loop_->PostTask(
- FROM_HERE,
- base::Bind(
- &PresentOnMainThread::DoPresent,
- present_on_main_thread));
-
- // The timeout is to avoid a deadlock if the main thread is synchronously
- // presenting.
- TRACE_EVENT0("gpu", "waitevent");
- PresentOnMainThread::Result result =
- present_on_main_thread->WaitForCompletion(
- 4 * base::TimeDelta::FromQPCValue(timing_info.qpcRefreshPeriod));
-
- // If the present did not complete on time then schedule the window for
- // repainting later.
- if (result != PresentOnMainThread::COMPLETE) {
- // Reset the device if it failed.
- if (result == PresentOnMainThread::FAILED)
- present_thread_->ResetDevice();
-
- InvalidateRect(window_, NULL, FALSE);
- }
- } else {
- hr = swap_chain_->Present(&rect, &rect, window_, NULL, 0);
-
- // For latency_tests.cc:
- UNSHIPPED_TRACE_EVENT_INSTANT0("test_gpu", "CompositorSwapBuffersComplete");
-
- if (hr == D3DERR_DEVICELOST)
- present_thread_->ResetDevice();
- }
-
- // Wait for the blit to complete before notifying the GPU process
+ // Wait for the StretchRect to complete before notifying the GPU process
// that it is safe to write to its backing store again.
{
TRACE_EVENT0("gpu", "spin");
do {
hr = present_thread_->query()->GetData(NULL, 0, D3DGETDATA_FLUSH);
+
if (hr == S_FALSE)
Sleep(1);
} while (hr == S_FALSE);
@@ -993,6 +839,17 @@ void AcceleratedPresenter::DoPresentAndAcknowledge(
base::PlatformThread::Sleep(swap_delay);
{
+ TRACE_EVENT0("gpu", "Present");
+ hr = swap_chain_->Present(&rect, &rect, window_, NULL, 0);
+ // For latency_tests.cc:
+ UNSHIPPED_TRACE_EVENT_INSTANT0("test_gpu", "CompositorSwapBuffersComplete");
+ if (FAILED(hr) &&
+ FAILED(present_thread_->device()->CheckDeviceState(window_))) {
+ present_thread_->ResetDevice();
+ }
+ }
+
+ {
TRACE_EVENT0("gpu", "GetPresentationStats");
base::TimeTicks timebase;
base::TimeDelta interval;
@@ -1009,6 +866,8 @@ void AcceleratedPresenter::DoPresentAndAcknowledge(
"timebase", timebase.ToInternalValue(),
"interval", interval.ToInternalValue());
}
+
+ hidden_ = false;
}
void AcceleratedPresenter::DoSuspend() {
diff --git a/ui/surface/accelerated_surface_win.h b/ui/surface/accelerated_surface_win.h
index 68f0c87..6a19e81 100644
--- a/ui/surface/accelerated_surface_win.h
+++ b/ui/surface/accelerated_surface_win.h
@@ -9,7 +9,6 @@
#include "base/callback_forward.h"
#include "base/memory/ref_counted.h"
-#include "base/message_loop_proxy.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "base/win/scoped_comptr.h"
@@ -122,13 +121,10 @@ class SURFACE_EXPORT AcceleratedPresenter
// 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<IDirect3DSwapChain9Ex> swap_chain_;
+ base::win::ScopedComPtr<IDirect3DSwapChain9> swap_chain_;
bool hidden_;
- // Message loop for the main thread.
- scoped_refptr<base::MessageLoopProxy> main_message_loop_;
-
DISALLOW_COPY_AND_ASSIGN(AcceleratedPresenter);
};