OLD | NEW |
1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/demos/app_framework/application.h" | 5 #include "gpu/demos/framework/window.h" |
6 | 6 |
7 #include "gpu/command_buffer/client/gles2_implementation.h" | 7 #include "gpu/command_buffer/client/gles2_implementation.h" |
8 #include "gpu/command_buffer/client/gles2_lib.h" | 8 #include "gpu/command_buffer/client/gles2_lib.h" |
9 #include "gpu/command_buffer/service/command_buffer_service.h" | 9 #include "gpu/command_buffer/service/command_buffer_service.h" |
10 #include "gpu/command_buffer/service/gpu_processor.h" | 10 #include "gpu/command_buffer/service/gpu_processor.h" |
| 11 #include "gpu/demos/framework/demo_factory.h" |
11 | 12 |
12 using gpu::Buffer; | 13 using gpu::Buffer; |
13 using gpu::CommandBufferService; | 14 using gpu::CommandBufferService; |
14 using gpu::GPUProcessor; | 15 using gpu::GPUProcessor; |
15 using gpu::gles2::GLES2CmdHelper; | 16 using gpu::gles2::GLES2CmdHelper; |
16 using gpu::gles2::GLES2Implementation; | 17 using gpu::gles2::GLES2Implementation; |
17 | 18 |
18 // TODO(alokp): Implement it on mac and linux when gpu process is functional | 19 // TODO(alokp): Make this class cross-platform. Investigate using SDL. |
19 // on these OS'. | |
20 #if defined(OS_WIN) | |
21 namespace { | 20 namespace { |
22 static const int32 kCommandBufferSize = 1024 * 1024; | 21 const int32 kCommandBufferSize = 1024 * 1024; |
23 static const int32 kTransferBufferSize = 512 * 1024; | 22 const int32 kTransferBufferSize = 512 * 1024; |
24 | 23 |
25 static LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, | 24 LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, |
26 WPARAM w_param, LPARAM l_param) { | 25 WPARAM w_param, LPARAM l_param) { |
27 LRESULT result = 0; | 26 LRESULT result = 0; |
28 switch (msg) { | 27 switch (msg) { |
29 case WM_CLOSE: | 28 case WM_CLOSE: |
30 ::DestroyWindow(hwnd); | 29 ::DestroyWindow(hwnd); |
31 break; | 30 break; |
32 case WM_DESTROY: | 31 case WM_DESTROY: |
33 ::PostQuitMessage(0); | 32 ::PostQuitMessage(0); |
34 break; | 33 break; |
| 34 case WM_ERASEBKGND: |
| 35 break; |
35 case WM_PAINT: { | 36 case WM_PAINT: { |
36 using gpu_demos::Application; | 37 gpu::demos::Window* window = reinterpret_cast<gpu::demos::Window*>( |
37 Application* app = reinterpret_cast<Application*>( | |
38 GetWindowLongPtr(hwnd, GWL_USERDATA)); | 38 GetWindowLongPtr(hwnd, GWL_USERDATA)); |
39 if (app != NULL) app->OnPaint(); | 39 if (window != NULL) window->OnPaint(); |
40 ::ValidateRect(hwnd, NULL); | 40 ::ValidateRect(hwnd, NULL); |
41 break; | 41 break; |
42 } | 42 } |
43 default: | 43 default: |
44 result = ::DefWindowProc(hwnd, msg, w_param, l_param); | 44 result = ::DefWindowProc(hwnd, msg, w_param, l_param); |
45 break; | 45 break; |
46 } | 46 } |
47 return result; | 47 return result; |
48 } | 48 } |
49 } // namespace. | |
50 | 49 |
51 namespace gpu_demos { | 50 HWND CreateNativeWindow(const wchar_t* title, int width, int height, |
| 51 LONG_PTR user_data) { |
| 52 WNDCLASS wnd_class = {0}; |
| 53 HINSTANCE instance = GetModuleHandle(NULL); |
| 54 wnd_class.style = CS_OWNDC; |
| 55 wnd_class.lpfnWndProc = WindowProc; |
| 56 wnd_class.hInstance = instance; |
| 57 wnd_class.hbrBackground = |
| 58 reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)); |
| 59 wnd_class.lpszClassName = L"gpu_demo"; |
| 60 if (!RegisterClass(&wnd_class)) return NULL; |
52 | 61 |
53 Application::Application() | 62 DWORD wnd_style = WS_VISIBLE | WS_POPUP | WS_BORDER | WS_SYSMENU | WS_CAPTION; |
54 : width_(512), | 63 RECT wnd_rect; |
55 height_(512), | 64 wnd_rect.left = 0; |
56 window_handle_(NULL) { | 65 wnd_rect.top = 0; |
| 66 wnd_rect.right = width; |
| 67 wnd_rect.bottom = height; |
| 68 AdjustWindowRect(&wnd_rect, wnd_style, FALSE); |
| 69 |
| 70 HWND hwnd = CreateWindow( |
| 71 wnd_class.lpszClassName, |
| 72 title, |
| 73 wnd_style, |
| 74 0, |
| 75 0, |
| 76 wnd_rect.right - wnd_rect.left, |
| 77 wnd_rect.bottom - wnd_rect.top, |
| 78 NULL, |
| 79 NULL, |
| 80 instance, |
| 81 NULL); |
| 82 if (hwnd == NULL) return NULL; |
| 83 |
| 84 ShowWindow(hwnd, SW_SHOWNORMAL); |
| 85 // Set this to the GWL_USERDATA so that it is available to WindowProc. |
| 86 SetWindowLongPtr(hwnd, GWL_USERDATA, user_data); |
| 87 |
| 88 return hwnd; |
57 } | 89 } |
58 | 90 |
59 Application::~Application() { | 91 bool InitRenderContext(HWND hwnd) { |
60 } | 92 CHECK(hwnd); |
61 | |
62 void Application::MainLoop() { | |
63 MSG msg; | |
64 bool done = false; | |
65 while (!done) { | |
66 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { | |
67 if (msg.message == WM_QUIT) done = true; | |
68 TranslateMessage(&msg); | |
69 DispatchMessage(&msg); | |
70 } | |
71 // Message queue is empty and application has not quit yet - keep painting. | |
72 if (!done) SendMessage(window_handle_, WM_PAINT, 0, 0); | |
73 } | |
74 } | |
75 | |
76 void Application::OnPaint() { | |
77 float elapsed_sec = 0.0f; | |
78 const base::Time current_time = base::Time::Now(); | |
79 if (!last_draw_time_.is_null()) { | |
80 base::TimeDelta time_delta = current_time - last_draw_time_; | |
81 elapsed_sec = static_cast<float>(time_delta.InSecondsF()); | |
82 } | |
83 last_draw_time_ = current_time; | |
84 | |
85 Draw(elapsed_sec); | |
86 gles2::GetGLContext()->SwapBuffers(); | |
87 } | |
88 | |
89 bool Application::InitRenderContext() { | |
90 window_handle_ = CreateNativeWindow(); | |
91 if (window_handle_ == NULL) { | |
92 return false; | |
93 } | |
94 | 93 |
95 scoped_ptr<CommandBufferService> command_buffer(new CommandBufferService); | 94 scoped_ptr<CommandBufferService> command_buffer(new CommandBufferService); |
96 if (!command_buffer->Initialize(kCommandBufferSize)) { | 95 if (!command_buffer->Initialize(kCommandBufferSize)) { |
97 return false; | 96 return false; |
98 } | 97 } |
99 | 98 |
100 scoped_refptr<GPUProcessor> gpu_processor( | 99 scoped_refptr<GPUProcessor> gpu_processor( |
101 new GPUProcessor(command_buffer.get())); | 100 new GPUProcessor(command_buffer.get())); |
102 if (!gpu_processor->Initialize(window_handle_)) { | 101 if (!gpu_processor->Initialize(hwnd)) { |
103 return false; | 102 return false; |
104 } | 103 } |
105 | 104 |
106 command_buffer->SetPutOffsetChangeCallback( | 105 command_buffer->SetPutOffsetChangeCallback( |
107 NewCallback(gpu_processor.get(), &GPUProcessor::ProcessCommands)); | 106 NewCallback(gpu_processor.get(), &GPUProcessor::ProcessCommands)); |
108 | 107 |
109 GLES2CmdHelper* helper = new GLES2CmdHelper(command_buffer.get()); | 108 GLES2CmdHelper* helper = new GLES2CmdHelper(command_buffer.get()); |
110 if (!helper->Initialize()) { | 109 if (!helper->Initialize()) { |
111 // TODO(alokp): cleanup. | 110 // TODO(alokp): cleanup. |
112 return false; | 111 return false; |
113 } | 112 } |
114 | 113 |
115 int32 transfer_buffer_id = | 114 int32 transfer_buffer_id = |
116 command_buffer->CreateTransferBuffer(kTransferBufferSize); | 115 command_buffer->CreateTransferBuffer(kTransferBufferSize); |
117 Buffer transfer_buffer = | 116 Buffer transfer_buffer = |
118 command_buffer->GetTransferBuffer(transfer_buffer_id); | 117 command_buffer->GetTransferBuffer(transfer_buffer_id); |
119 if (transfer_buffer.ptr == NULL) return false; | 118 if (transfer_buffer.ptr == NULL) return false; |
120 | 119 |
121 gles2::g_gl_impl = new GLES2Implementation(helper, | 120 gles2::SetGLContext(new GLES2Implementation(helper, |
122 transfer_buffer.size, | 121 transfer_buffer.size, |
123 transfer_buffer.ptr, | 122 transfer_buffer.ptr, |
124 transfer_buffer_id); | 123 transfer_buffer_id)); |
125 | |
126 return command_buffer.release() != NULL; | 124 return command_buffer.release() != NULL; |
127 } | 125 } |
| 126 } // namespace. |
128 | 127 |
129 NativeWindowHandle Application::CreateNativeWindow() { | 128 namespace gpu { |
130 WNDCLASS wnd_class = {0}; | 129 namespace demos { |
131 HINSTANCE instance = GetModuleHandle(NULL); | |
132 wnd_class.style = CS_OWNDC; | |
133 wnd_class.lpfnWndProc = (WNDPROC)WindowProc; | |
134 wnd_class.hInstance = instance; | |
135 wnd_class.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); | |
136 wnd_class.lpszClassName = L"opengles2.0"; | |
137 if (!RegisterClass(&wnd_class)) return NULL; | |
138 | 130 |
139 DWORD wnd_style = WS_VISIBLE | WS_POPUP | WS_BORDER | WS_SYSMENU | WS_CAPTION; | 131 Window::Window() |
140 RECT wnd_rect; | 132 : window_handle_(NULL), |
141 wnd_rect.left = 0; | 133 demo_(CreateDemo()) { |
142 wnd_rect.top = 0; | |
143 wnd_rect.right = width_; | |
144 wnd_rect.bottom = height_; | |
145 AdjustWindowRect(&wnd_rect, wnd_style, FALSE); | |
146 | |
147 HWND hwnd = CreateWindow( | |
148 wnd_class.lpszClassName, | |
149 wnd_class.lpszClassName, | |
150 wnd_style, | |
151 0, | |
152 0, | |
153 wnd_rect.right - wnd_rect.left, | |
154 wnd_rect.bottom - wnd_rect.top, | |
155 NULL, | |
156 NULL, | |
157 instance, | |
158 NULL); | |
159 if (hwnd == NULL) return NULL; | |
160 | |
161 ShowWindow(hwnd, SW_SHOWNORMAL); | |
162 // Set this to the GWL_USERDATA so that it is available to WindowProc. | |
163 SetWindowLongPtr(hwnd, GWL_USERDATA, (LONG_PTR)this); | |
164 | |
165 return hwnd; | |
166 } | 134 } |
167 | 135 |
168 } // namespace gpu_demos | 136 Window::~Window() { |
169 #endif // defined(OS_WIN) | 137 } |
| 138 |
| 139 bool Window::Init(int width, int height) { |
| 140 window_handle_ = CreateNativeWindow(demo_->Title(), width, height, |
| 141 reinterpret_cast<LONG_PTR>(this)); |
| 142 if (window_handle_ == NULL) return false; |
| 143 if (!InitRenderContext(window_handle_)) return false; |
| 144 |
| 145 demo_->InitWindowSize(width, height); |
| 146 return demo_->InitGL(); |
| 147 } |
| 148 |
| 149 void Window::MainLoop() { |
| 150 MSG msg; |
| 151 bool done = false; |
| 152 while (!done) { |
| 153 while (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { |
| 154 if (msg.message == WM_QUIT) done = true; |
| 155 ::TranslateMessage(&msg); |
| 156 ::DispatchMessage(&msg); |
| 157 } |
| 158 // Message queue is empty and application has not quit yet - keep painting. |
| 159 if (!done) ::UpdateWindow(window_handle_); |
| 160 } |
| 161 } |
| 162 |
| 163 void Window::OnPaint() { |
| 164 demo_->Draw(); |
| 165 ::gles2::GetGLContext()->SwapBuffers(); |
| 166 } |
| 167 |
| 168 } // namespace demos |
| 169 } // namespace gpu |
OLD | NEW |