From 85c5b0230b1a9a9d8e02ad6049c31bf55eb5c076 Mon Sep 17 00:00:00 2001 From: "apatrick@google.com" Date: Wed, 11 Nov 2009 18:48:49 +0000 Subject: Reverting 31676. git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31682 0039d316-1c4b-4281-b951-d872f2087c98 --- o3d/build/o3d_all.gyp | 3 +- o3d/command_buffer/client/cmd_buffer_helper.cc | 197 ++ o3d/command_buffer/client/cmd_buffer_helper.h | 212 ++ .../client/cmd_buffer_helper_test.cc | 298 ++ o3d/command_buffer/client/effect_helper.cc | 250 ++ o3d/command_buffer/client/effect_helper.h | 156 + o3d/command_buffer/client/fenced_allocator.cc | 214 ++ o3d/command_buffer/client/fenced_allocator.h | 266 ++ o3d/command_buffer/client/fenced_allocator_test.cc | 496 +++ o3d/command_buffer/client/id_allocator.cc | 85 + o3d/command_buffer/client/id_allocator.h | 78 + o3d/command_buffer/client/id_allocator_test.cc | 112 + o3d/command_buffer/client/o3d_cmd_helper.cc | 42 + o3d/command_buffer/client/o3d_cmd_helper.h | 636 ++++ o3d/command_buffer/command_buffer.gyp | 243 ++ o3d/command_buffer/common/GLES2/gl2.h | 621 ++++ o3d/command_buffer/common/GLES2/gl2platform.h | 29 + o3d/command_buffer/common/KHR/khrplatform.h | 269 ++ o3d/command_buffer/common/bitfield_helpers.h | 68 + o3d/command_buffer/common/bitfield_helpers_test.cc | 66 + o3d/command_buffer/common/cmd_buffer_common.cc | 57 + o3d/command_buffer/common/cmd_buffer_common.h | 247 ++ o3d/command_buffer/common/constants.h | 71 + o3d/command_buffer/common/gapi_interface.h | 833 ++++++ o3d/command_buffer/common/logging.h | 67 + o3d/command_buffer/common/o3d_cmd_format.cc | 57 + o3d/command_buffer/common/o3d_cmd_format.h | 3155 ++++++++++++++++++++ o3d/command_buffer/common/resource.cc | 120 + o3d/command_buffer/common/resource.h | 229 ++ o3d/command_buffer/common/types.h | 60 + o3d/command_buffer/service/big_test_main.cc | 123 + o3d/command_buffer/service/cmd_buffer_engine.h | 70 + o3d/command_buffer/service/cmd_parser.cc | 111 + o3d/command_buffer/service/cmd_parser.h | 115 + o3d/command_buffer/service/cmd_parser_test.cc | 314 ++ o3d/command_buffer/service/common_decoder.cc | 121 + o3d/command_buffer/service/common_decoder.h | 107 + o3d/command_buffer/service/d3d9_utils.h | 145 + o3d/command_buffer/service/effect_d3d9.cc | 677 +++++ o3d/command_buffer/service/effect_d3d9.h | 139 + o3d/command_buffer/service/effect_gl.cc | 850 ++++++ o3d/command_buffer/service/effect_gl.h | 162 + o3d/command_buffer/service/effect_utils.cc | 68 + o3d/command_buffer/service/effect_utils.h | 54 + o3d/command_buffer/service/effect_utils_test.cc | 86 + o3d/command_buffer/service/gapi_d3d9.cc | 392 +++ o3d/command_buffer/service/gapi_d3d9.h | 508 ++++ o3d/command_buffer/service/gapi_decoder.cc | 938 ++++++ o3d/command_buffer/service/gapi_decoder.h | 81 + o3d/command_buffer/service/gapi_gl.cc | 417 +++ o3d/command_buffer/service/gapi_gl.h | 465 +++ o3d/command_buffer/service/geometry_d3d9.cc | 436 +++ o3d/command_buffer/service/geometry_d3d9.h | 126 + o3d/command_buffer/service/geometry_gl.cc | 553 ++++ o3d/command_buffer/service/geometry_gl.h | 144 + o3d/command_buffer/service/gl_utils.h | 60 + o3d/command_buffer/service/mocks.h | 108 + o3d/command_buffer/service/precompile.cc | 33 + o3d/command_buffer/service/precompile.h | 50 + o3d/command_buffer/service/render_surface_d3d9.cc | 229 ++ o3d/command_buffer/service/render_surface_d3d9.h | 161 + o3d/command_buffer/service/render_surface_gl.cc | 261 ++ o3d/command_buffer/service/render_surface_gl.h | 117 + o3d/command_buffer/service/resource.cc | 100 + o3d/command_buffer/service/resource.h | 268 ++ o3d/command_buffer/service/resource_test.cc | 126 + o3d/command_buffer/service/sampler_d3d9.cc | 198 ++ o3d/command_buffer/service/sampler_d3d9.h | 85 + o3d/command_buffer/service/sampler_gl.cc | 237 ++ o3d/command_buffer/service/sampler_gl.h | 87 + o3d/command_buffer/service/states_d3d9.cc | 352 +++ o3d/command_buffer/service/states_gl.cc | 345 +++ o3d/command_buffer/service/texture_d3d9.cc | 730 +++++ o3d/command_buffer/service/texture_d3d9.h | 282 ++ o3d/command_buffer/service/texture_gl.cc | 766 +++++ o3d/command_buffer/service/texture_gl.h | 284 ++ o3d/command_buffer/service/texture_utils.cc | 102 + o3d/command_buffer/service/texture_utils.h | 156 + o3d/command_buffer/service/x_utils.cc | 91 + o3d/command_buffer/service/x_utils.h | 76 + o3d/core/core.gyp | 8 +- o3d/core/cross/command_buffer/buffer_cb.cc | 4 +- o3d/core/cross/command_buffer/display_window_cb.h | 4 +- o3d/core/cross/command_buffer/effect_cb.cc | 8 +- o3d/core/cross/command_buffer/effect_cb.h | 2 +- o3d/core/cross/command_buffer/param_cache_cb.cc | 4 +- o3d/core/cross/command_buffer/primitive_cb.cc | 4 +- o3d/core/cross/command_buffer/primitive_cb.h | 2 +- o3d/core/cross/command_buffer/render_surface_cb.cc | 2 +- o3d/core/cross/command_buffer/render_surface_cb.h | 2 +- o3d/core/cross/command_buffer/renderer_cb.cc | 16 +- o3d/core/cross/command_buffer/renderer_cb.h | 12 +- o3d/core/cross/command_buffer/sampler_cb.cc | 4 +- o3d/core/cross/command_buffer/sampler_cb.h | 2 +- o3d/core/cross/command_buffer/states_cb.cc | 2 +- o3d/core/cross/command_buffer/states_cb.h | 4 +- o3d/core/cross/command_buffer/stream_bank_cb.cc | 4 +- o3d/core/cross/command_buffer/stream_bank_cb.h | 2 +- o3d/core/cross/command_buffer/texture_cb.cc | 8 +- o3d/core/cross/command_buffer/texture_cb.h | 2 +- o3d/gpu/command_buffer/client/cmd_buffer_helper.cc | 197 -- o3d/gpu/command_buffer/client/cmd_buffer_helper.h | 212 -- .../client/cmd_buffer_helper_test.cc | 298 -- o3d/gpu/command_buffer/client/effect_helper.cc | 250 -- o3d/gpu/command_buffer/client/effect_helper.h | 156 - o3d/gpu/command_buffer/client/fenced_allocator.cc | 214 -- o3d/gpu/command_buffer/client/fenced_allocator.h | 266 -- .../command_buffer/client/fenced_allocator_test.cc | 496 --- o3d/gpu/command_buffer/client/id_allocator.cc | 85 - o3d/gpu/command_buffer/client/id_allocator.h | 78 - o3d/gpu/command_buffer/client/id_allocator_test.cc | 112 - o3d/gpu/command_buffer/client/o3d_cmd_helper.cc | 42 - o3d/gpu/command_buffer/client/o3d_cmd_helper.h | 636 ---- o3d/gpu/command_buffer/common/GLES2/gl2.h | 621 ---- o3d/gpu/command_buffer/common/GLES2/gl2platform.h | 29 - o3d/gpu/command_buffer/common/KHR/khrplatform.h | 269 -- o3d/gpu/command_buffer/common/bitfield_helpers.h | 68 - .../command_buffer/common/bitfield_helpers_test.cc | 66 - o3d/gpu/command_buffer/common/cmd_buffer_common.cc | 57 - o3d/gpu/command_buffer/common/cmd_buffer_common.h | 247 -- o3d/gpu/command_buffer/common/constants.h | 71 - o3d/gpu/command_buffer/common/gapi_interface.h | 833 ------ o3d/gpu/command_buffer/common/logging.h | 67 - o3d/gpu/command_buffer/common/o3d_cmd_format.cc | 57 - o3d/gpu/command_buffer/common/o3d_cmd_format.h | 3155 -------------------- o3d/gpu/command_buffer/common/resource.cc | 120 - o3d/gpu/command_buffer/common/resource.h | 229 -- o3d/gpu/command_buffer/common/types.h | 60 - o3d/gpu/command_buffer/service/big_test_main.cc | 124 - o3d/gpu/command_buffer/service/cmd_buffer_engine.h | 70 - o3d/gpu/command_buffer/service/cmd_parser.cc | 112 - o3d/gpu/command_buffer/service/cmd_parser.h | 115 - o3d/gpu/command_buffer/service/cmd_parser_test.cc | 316 -- o3d/gpu/command_buffer/service/common_decoder.cc | 122 - o3d/gpu/command_buffer/service/common_decoder.h | 107 - o3d/gpu/command_buffer/service/d3d9_utils.h | 145 - o3d/gpu/command_buffer/service/effect_d3d9.cc | 679 ----- o3d/gpu/command_buffer/service/effect_d3d9.h | 139 - o3d/gpu/command_buffer/service/effect_gl.cc | 852 ------ o3d/gpu/command_buffer/service/effect_gl.h | 162 - o3d/gpu/command_buffer/service/effect_utils.cc | 69 - o3d/gpu/command_buffer/service/effect_utils.h | 54 - .../command_buffer/service/effect_utils_test.cc | 87 - o3d/gpu/command_buffer/service/gapi_d3d9.cc | 393 --- o3d/gpu/command_buffer/service/gapi_d3d9.h | 508 ---- o3d/gpu/command_buffer/service/gapi_decoder.cc | 940 ------ o3d/gpu/command_buffer/service/gapi_decoder.h | 81 - o3d/gpu/command_buffer/service/gapi_gl.cc | 420 --- o3d/gpu/command_buffer/service/gapi_gl.h | 465 --- o3d/gpu/command_buffer/service/geometry_d3d9.cc | 439 --- o3d/gpu/command_buffer/service/geometry_d3d9.h | 126 - o3d/gpu/command_buffer/service/geometry_gl.cc | 554 ---- o3d/gpu/command_buffer/service/geometry_gl.h | 144 - o3d/gpu/command_buffer/service/gl_utils.h | 60 - o3d/gpu/command_buffer/service/mocks.h | 108 - o3d/gpu/command_buffer/service/precompile.cc | 33 - o3d/gpu/command_buffer/service/precompile.h | 50 - .../command_buffer/service/render_surface_d3d9.cc | 230 -- .../command_buffer/service/render_surface_d3d9.h | 161 - .../command_buffer/service/render_surface_gl.cc | 262 -- o3d/gpu/command_buffer/service/render_surface_gl.h | 117 - o3d/gpu/command_buffer/service/resource.cc | 101 - o3d/gpu/command_buffer/service/resource.h | 268 -- o3d/gpu/command_buffer/service/resource_test.cc | 127 - o3d/gpu/command_buffer/service/sampler_d3d9.cc | 199 -- o3d/gpu/command_buffer/service/sampler_d3d9.h | 85 - o3d/gpu/command_buffer/service/sampler_gl.cc | 238 -- o3d/gpu/command_buffer/service/sampler_gl.h | 87 - o3d/gpu/command_buffer/service/states_d3d9.cc | 355 --- o3d/gpu/command_buffer/service/states_gl.cc | 346 --- o3d/gpu/command_buffer/service/texture_d3d9.cc | 731 ----- o3d/gpu/command_buffer/service/texture_d3d9.h | 282 -- o3d/gpu/command_buffer/service/texture_gl.cc | 767 ----- o3d/gpu/command_buffer/service/texture_gl.h | 284 -- o3d/gpu/command_buffer/service/texture_utils.cc | 105 - o3d/gpu/command_buffer/service/texture_utils.h | 156 - o3d/gpu/command_buffer/service/x_utils.cc | 92 - o3d/gpu/command_buffer/service/x_utils.h | 76 - o3d/gpu/gpu.gyp | 351 --- o3d/gpu/gpu_plugin/command_buffer.cc | 143 - o3d/gpu/gpu_plugin/command_buffer.h | 130 - o3d/gpu/gpu_plugin/command_buffer_mock.h | 42 - o3d/gpu/gpu_plugin/command_buffer_unittest.cc | 182 -- o3d/gpu/gpu_plugin/gpu_plugin.cc | 136 - o3d/gpu/gpu_plugin/gpu_plugin.h | 30 - o3d/gpu/gpu_plugin/gpu_plugin_object.cc | 117 - o3d/gpu/gpu_plugin/gpu_plugin_object.h | 132 - o3d/gpu/gpu_plugin/gpu_plugin_object_factory.cc | 27 - o3d/gpu/gpu_plugin/gpu_plugin_object_factory.h | 26 - .../gpu_plugin_object_factory_unittest.cc | 39 - o3d/gpu/gpu_plugin/gpu_plugin_object_unittest.cc | 346 --- o3d/gpu/gpu_plugin/gpu_plugin_object_win.cc | 62 - o3d/gpu/gpu_plugin/gpu_plugin_unittest.cc | 305 -- o3d/gpu/gpu_plugin/gpu_processor.cc | 80 - o3d/gpu/gpu_plugin/gpu_processor.h | 119 - o3d/gpu/gpu_plugin/gpu_processor_mock.h | 41 - o3d/gpu/gpu_plugin/gpu_processor_unittest.cc | 309 -- o3d/gpu/gpu_plugin/gpu_processor_win.cc | 85 - o3d/gpu/np_utils/default_np_object.h | 84 - o3d/gpu/np_utils/dispatched_np_object_unittest.cc | 403 --- o3d/gpu/np_utils/dynamic_np_object.cc | 59 - o3d/gpu/np_utils/dynamic_np_object.h | 35 - o3d/gpu/np_utils/dynamic_np_object_unittest.cc | 83 - o3d/gpu/np_utils/np_browser.cc | 128 - o3d/gpu/np_utils/np_browser.h | 95 - o3d/gpu/np_utils/np_browser_mock.h | 50 - o3d/gpu/np_utils/np_browser_stub.cc | 125 - o3d/gpu/np_utils/np_browser_stub.h | 84 - o3d/gpu/np_utils/np_class.h | 125 - o3d/gpu/np_utils/np_class_unittest.cc | 143 - o3d/gpu/np_utils/np_dispatcher.cc | 85 - o3d/gpu/np_utils/np_dispatcher.h | 222 -- o3d/gpu/np_utils/np_dispatcher_specializations.h | 85 - o3d/gpu/np_utils/np_headers.h | 16 - o3d/gpu/np_utils/np_object_mock.h | 36 - o3d/gpu/np_utils/np_object_pointer.h | 119 - o3d/gpu/np_utils/np_object_pointer_unittest.cc | 220 -- o3d/gpu/np_utils/np_plugin_object.h | 50 - o3d/gpu/np_utils/np_plugin_object_factory.cc | 30 - o3d/gpu/np_utils/np_plugin_object_factory.h | 37 - o3d/gpu/np_utils/np_plugin_object_factory_mock.h | 23 - o3d/gpu/np_utils/np_plugin_object_mock.h | 26 - o3d/gpu/np_utils/np_utils.cc | 170 -- o3d/gpu/np_utils/np_utils.h | 271 -- o3d/gpu/np_utils/np_utils_unittest.cc | 424 --- o3d/gpu/np_utils/webkit_browser.h | 117 - o3d/gpu_plugin/command_buffer.cc | 143 + o3d/gpu_plugin/command_buffer.h | 130 + o3d/gpu_plugin/command_buffer_mock.h | 42 + o3d/gpu_plugin/command_buffer_unittest.cc | 182 ++ o3d/gpu_plugin/gpu_plugin.cc | 136 + o3d/gpu_plugin/gpu_plugin.gyp | 162 + o3d/gpu_plugin/gpu_plugin.h | 30 + o3d/gpu_plugin/gpu_plugin_object.cc | 117 + o3d/gpu_plugin/gpu_plugin_object.h | 132 + o3d/gpu_plugin/gpu_plugin_object_factory.cc | 27 + o3d/gpu_plugin/gpu_plugin_object_factory.h | 26 + .../gpu_plugin_object_factory_unittest.cc | 39 + o3d/gpu_plugin/gpu_plugin_object_unittest.cc | 346 +++ o3d/gpu_plugin/gpu_plugin_object_win.cc | 62 + o3d/gpu_plugin/gpu_plugin_unittest.cc | 305 ++ o3d/gpu_plugin/gpu_processor.cc | 80 + o3d/gpu_plugin/gpu_processor.h | 119 + o3d/gpu_plugin/gpu_processor_mock.h | 41 + o3d/gpu_plugin/gpu_processor_unittest.cc | 309 ++ o3d/gpu_plugin/gpu_processor_win.cc | 85 + o3d/gpu_plugin/np_utils/default_np_object.h | 84 + .../np_utils/dispatched_np_object_unittest.cc | 403 +++ o3d/gpu_plugin/np_utils/dynamic_np_object.cc | 59 + o3d/gpu_plugin/np_utils/dynamic_np_object.h | 35 + .../np_utils/dynamic_np_object_unittest.cc | 83 + o3d/gpu_plugin/np_utils/np_browser.cc | 128 + o3d/gpu_plugin/np_utils/np_browser.h | 95 + o3d/gpu_plugin/np_utils/np_browser_mock.h | 50 + o3d/gpu_plugin/np_utils/np_browser_stub.cc | 125 + o3d/gpu_plugin/np_utils/np_browser_stub.h | 84 + o3d/gpu_plugin/np_utils/np_class.h | 125 + o3d/gpu_plugin/np_utils/np_class_unittest.cc | 143 + o3d/gpu_plugin/np_utils/np_dispatcher.cc | 85 + o3d/gpu_plugin/np_utils/np_dispatcher.h | 222 ++ .../np_utils/np_dispatcher_specializations.h | 85 + o3d/gpu_plugin/np_utils/np_headers.h | 16 + o3d/gpu_plugin/np_utils/np_object_mock.h | 36 + o3d/gpu_plugin/np_utils/np_object_pointer.h | 119 + .../np_utils/np_object_pointer_unittest.cc | 220 ++ o3d/gpu_plugin/np_utils/np_plugin_object.h | 50 + .../np_utils/np_plugin_object_factory.cc | 30 + o3d/gpu_plugin/np_utils/np_plugin_object_factory.h | 37 + .../np_utils/np_plugin_object_factory_mock.h | 23 + o3d/gpu_plugin/np_utils/np_plugin_object_mock.h | 26 + o3d/gpu_plugin/np_utils/np_utils.cc | 170 ++ o3d/gpu_plugin/np_utils/np_utils.h | 271 ++ o3d/gpu_plugin/np_utils/np_utils_unittest.cc | 424 +++ o3d/gpu_plugin/np_utils/webkit_browser.h | 117 + o3d/plugin/cross/o3d_glue.cc | 6 +- o3d/plugin/plugin.gyp | 2 +- o3d/plugin/win/main_win.cc | 2 +- o3d/tests/common/win/testing_common.cc | 4 +- o3d/tests/tests.gyp | 8 +- 279 files changed, 27658 insertions(+), 27642 deletions(-) create mode 100644 o3d/command_buffer/client/cmd_buffer_helper.cc create mode 100644 o3d/command_buffer/client/cmd_buffer_helper.h create mode 100644 o3d/command_buffer/client/cmd_buffer_helper_test.cc create mode 100644 o3d/command_buffer/client/effect_helper.cc create mode 100644 o3d/command_buffer/client/effect_helper.h create mode 100644 o3d/command_buffer/client/fenced_allocator.cc create mode 100644 o3d/command_buffer/client/fenced_allocator.h create mode 100644 o3d/command_buffer/client/fenced_allocator_test.cc create mode 100644 o3d/command_buffer/client/id_allocator.cc create mode 100644 o3d/command_buffer/client/id_allocator.h create mode 100644 o3d/command_buffer/client/id_allocator_test.cc create mode 100644 o3d/command_buffer/client/o3d_cmd_helper.cc create mode 100644 o3d/command_buffer/client/o3d_cmd_helper.h create mode 100644 o3d/command_buffer/command_buffer.gyp create mode 100644 o3d/command_buffer/common/GLES2/gl2.h create mode 100644 o3d/command_buffer/common/GLES2/gl2platform.h create mode 100644 o3d/command_buffer/common/KHR/khrplatform.h create mode 100644 o3d/command_buffer/common/bitfield_helpers.h create mode 100644 o3d/command_buffer/common/bitfield_helpers_test.cc create mode 100644 o3d/command_buffer/common/cmd_buffer_common.cc create mode 100644 o3d/command_buffer/common/cmd_buffer_common.h create mode 100644 o3d/command_buffer/common/constants.h create mode 100644 o3d/command_buffer/common/gapi_interface.h create mode 100644 o3d/command_buffer/common/logging.h create mode 100644 o3d/command_buffer/common/o3d_cmd_format.cc create mode 100644 o3d/command_buffer/common/o3d_cmd_format.h create mode 100644 o3d/command_buffer/common/resource.cc create mode 100644 o3d/command_buffer/common/resource.h create mode 100644 o3d/command_buffer/common/types.h create mode 100644 o3d/command_buffer/service/big_test_main.cc create mode 100644 o3d/command_buffer/service/cmd_buffer_engine.h create mode 100644 o3d/command_buffer/service/cmd_parser.cc create mode 100644 o3d/command_buffer/service/cmd_parser.h create mode 100644 o3d/command_buffer/service/cmd_parser_test.cc create mode 100644 o3d/command_buffer/service/common_decoder.cc create mode 100644 o3d/command_buffer/service/common_decoder.h create mode 100644 o3d/command_buffer/service/d3d9_utils.h create mode 100644 o3d/command_buffer/service/effect_d3d9.cc create mode 100644 o3d/command_buffer/service/effect_d3d9.h create mode 100644 o3d/command_buffer/service/effect_gl.cc create mode 100644 o3d/command_buffer/service/effect_gl.h create mode 100644 o3d/command_buffer/service/effect_utils.cc create mode 100644 o3d/command_buffer/service/effect_utils.h create mode 100644 o3d/command_buffer/service/effect_utils_test.cc create mode 100644 o3d/command_buffer/service/gapi_d3d9.cc create mode 100644 o3d/command_buffer/service/gapi_d3d9.h create mode 100644 o3d/command_buffer/service/gapi_decoder.cc create mode 100644 o3d/command_buffer/service/gapi_decoder.h create mode 100644 o3d/command_buffer/service/gapi_gl.cc create mode 100644 o3d/command_buffer/service/gapi_gl.h create mode 100644 o3d/command_buffer/service/geometry_d3d9.cc create mode 100644 o3d/command_buffer/service/geometry_d3d9.h create mode 100644 o3d/command_buffer/service/geometry_gl.cc create mode 100644 o3d/command_buffer/service/geometry_gl.h create mode 100644 o3d/command_buffer/service/gl_utils.h create mode 100644 o3d/command_buffer/service/mocks.h create mode 100644 o3d/command_buffer/service/precompile.cc create mode 100644 o3d/command_buffer/service/precompile.h create mode 100644 o3d/command_buffer/service/render_surface_d3d9.cc create mode 100644 o3d/command_buffer/service/render_surface_d3d9.h create mode 100644 o3d/command_buffer/service/render_surface_gl.cc create mode 100644 o3d/command_buffer/service/render_surface_gl.h create mode 100644 o3d/command_buffer/service/resource.cc create mode 100644 o3d/command_buffer/service/resource.h create mode 100644 o3d/command_buffer/service/resource_test.cc create mode 100644 o3d/command_buffer/service/sampler_d3d9.cc create mode 100644 o3d/command_buffer/service/sampler_d3d9.h create mode 100644 o3d/command_buffer/service/sampler_gl.cc create mode 100644 o3d/command_buffer/service/sampler_gl.h create mode 100644 o3d/command_buffer/service/states_d3d9.cc create mode 100644 o3d/command_buffer/service/states_gl.cc create mode 100644 o3d/command_buffer/service/texture_d3d9.cc create mode 100644 o3d/command_buffer/service/texture_d3d9.h create mode 100644 o3d/command_buffer/service/texture_gl.cc create mode 100644 o3d/command_buffer/service/texture_gl.h create mode 100644 o3d/command_buffer/service/texture_utils.cc create mode 100644 o3d/command_buffer/service/texture_utils.h create mode 100644 o3d/command_buffer/service/x_utils.cc create mode 100644 o3d/command_buffer/service/x_utils.h delete mode 100644 o3d/gpu/command_buffer/client/cmd_buffer_helper.cc delete mode 100644 o3d/gpu/command_buffer/client/cmd_buffer_helper.h delete mode 100644 o3d/gpu/command_buffer/client/cmd_buffer_helper_test.cc delete mode 100644 o3d/gpu/command_buffer/client/effect_helper.cc delete mode 100644 o3d/gpu/command_buffer/client/effect_helper.h delete mode 100644 o3d/gpu/command_buffer/client/fenced_allocator.cc delete mode 100644 o3d/gpu/command_buffer/client/fenced_allocator.h delete mode 100644 o3d/gpu/command_buffer/client/fenced_allocator_test.cc delete mode 100644 o3d/gpu/command_buffer/client/id_allocator.cc delete mode 100644 o3d/gpu/command_buffer/client/id_allocator.h delete mode 100644 o3d/gpu/command_buffer/client/id_allocator_test.cc delete mode 100644 o3d/gpu/command_buffer/client/o3d_cmd_helper.cc delete mode 100644 o3d/gpu/command_buffer/client/o3d_cmd_helper.h delete mode 100644 o3d/gpu/command_buffer/common/GLES2/gl2.h delete mode 100644 o3d/gpu/command_buffer/common/GLES2/gl2platform.h delete mode 100644 o3d/gpu/command_buffer/common/KHR/khrplatform.h delete mode 100644 o3d/gpu/command_buffer/common/bitfield_helpers.h delete mode 100644 o3d/gpu/command_buffer/common/bitfield_helpers_test.cc delete mode 100644 o3d/gpu/command_buffer/common/cmd_buffer_common.cc delete mode 100644 o3d/gpu/command_buffer/common/cmd_buffer_common.h delete mode 100644 o3d/gpu/command_buffer/common/constants.h delete mode 100644 o3d/gpu/command_buffer/common/gapi_interface.h delete mode 100644 o3d/gpu/command_buffer/common/logging.h delete mode 100644 o3d/gpu/command_buffer/common/o3d_cmd_format.cc delete mode 100644 o3d/gpu/command_buffer/common/o3d_cmd_format.h delete mode 100644 o3d/gpu/command_buffer/common/resource.cc delete mode 100644 o3d/gpu/command_buffer/common/resource.h delete mode 100644 o3d/gpu/command_buffer/common/types.h delete mode 100644 o3d/gpu/command_buffer/service/big_test_main.cc delete mode 100644 o3d/gpu/command_buffer/service/cmd_buffer_engine.h delete mode 100644 o3d/gpu/command_buffer/service/cmd_parser.cc delete mode 100644 o3d/gpu/command_buffer/service/cmd_parser.h delete mode 100644 o3d/gpu/command_buffer/service/cmd_parser_test.cc delete mode 100644 o3d/gpu/command_buffer/service/common_decoder.cc delete mode 100644 o3d/gpu/command_buffer/service/common_decoder.h delete mode 100644 o3d/gpu/command_buffer/service/d3d9_utils.h delete mode 100644 o3d/gpu/command_buffer/service/effect_d3d9.cc delete mode 100644 o3d/gpu/command_buffer/service/effect_d3d9.h delete mode 100644 o3d/gpu/command_buffer/service/effect_gl.cc delete mode 100644 o3d/gpu/command_buffer/service/effect_gl.h delete mode 100644 o3d/gpu/command_buffer/service/effect_utils.cc delete mode 100644 o3d/gpu/command_buffer/service/effect_utils.h delete mode 100644 o3d/gpu/command_buffer/service/effect_utils_test.cc delete mode 100644 o3d/gpu/command_buffer/service/gapi_d3d9.cc delete mode 100644 o3d/gpu/command_buffer/service/gapi_d3d9.h delete mode 100644 o3d/gpu/command_buffer/service/gapi_decoder.cc delete mode 100644 o3d/gpu/command_buffer/service/gapi_decoder.h delete mode 100644 o3d/gpu/command_buffer/service/gapi_gl.cc delete mode 100644 o3d/gpu/command_buffer/service/gapi_gl.h delete mode 100644 o3d/gpu/command_buffer/service/geometry_d3d9.cc delete mode 100644 o3d/gpu/command_buffer/service/geometry_d3d9.h delete mode 100644 o3d/gpu/command_buffer/service/geometry_gl.cc delete mode 100644 o3d/gpu/command_buffer/service/geometry_gl.h delete mode 100644 o3d/gpu/command_buffer/service/gl_utils.h delete mode 100644 o3d/gpu/command_buffer/service/mocks.h delete mode 100644 o3d/gpu/command_buffer/service/precompile.cc delete mode 100644 o3d/gpu/command_buffer/service/precompile.h delete mode 100644 o3d/gpu/command_buffer/service/render_surface_d3d9.cc delete mode 100644 o3d/gpu/command_buffer/service/render_surface_d3d9.h delete mode 100644 o3d/gpu/command_buffer/service/render_surface_gl.cc delete mode 100644 o3d/gpu/command_buffer/service/render_surface_gl.h delete mode 100644 o3d/gpu/command_buffer/service/resource.cc delete mode 100644 o3d/gpu/command_buffer/service/resource.h delete mode 100644 o3d/gpu/command_buffer/service/resource_test.cc delete mode 100644 o3d/gpu/command_buffer/service/sampler_d3d9.cc delete mode 100644 o3d/gpu/command_buffer/service/sampler_d3d9.h delete mode 100644 o3d/gpu/command_buffer/service/sampler_gl.cc delete mode 100644 o3d/gpu/command_buffer/service/sampler_gl.h delete mode 100644 o3d/gpu/command_buffer/service/states_d3d9.cc delete mode 100644 o3d/gpu/command_buffer/service/states_gl.cc delete mode 100644 o3d/gpu/command_buffer/service/texture_d3d9.cc delete mode 100644 o3d/gpu/command_buffer/service/texture_d3d9.h delete mode 100644 o3d/gpu/command_buffer/service/texture_gl.cc delete mode 100644 o3d/gpu/command_buffer/service/texture_gl.h delete mode 100644 o3d/gpu/command_buffer/service/texture_utils.cc delete mode 100644 o3d/gpu/command_buffer/service/texture_utils.h delete mode 100644 o3d/gpu/command_buffer/service/x_utils.cc delete mode 100644 o3d/gpu/command_buffer/service/x_utils.h delete mode 100644 o3d/gpu/gpu.gyp delete mode 100644 o3d/gpu/gpu_plugin/command_buffer.cc delete mode 100644 o3d/gpu/gpu_plugin/command_buffer.h delete mode 100644 o3d/gpu/gpu_plugin/command_buffer_mock.h delete mode 100644 o3d/gpu/gpu_plugin/command_buffer_unittest.cc delete mode 100644 o3d/gpu/gpu_plugin/gpu_plugin.cc delete mode 100644 o3d/gpu/gpu_plugin/gpu_plugin.h delete mode 100644 o3d/gpu/gpu_plugin/gpu_plugin_object.cc delete mode 100644 o3d/gpu/gpu_plugin/gpu_plugin_object.h delete mode 100644 o3d/gpu/gpu_plugin/gpu_plugin_object_factory.cc delete mode 100644 o3d/gpu/gpu_plugin/gpu_plugin_object_factory.h delete mode 100644 o3d/gpu/gpu_plugin/gpu_plugin_object_factory_unittest.cc delete mode 100644 o3d/gpu/gpu_plugin/gpu_plugin_object_unittest.cc delete mode 100644 o3d/gpu/gpu_plugin/gpu_plugin_object_win.cc delete mode 100644 o3d/gpu/gpu_plugin/gpu_plugin_unittest.cc delete mode 100644 o3d/gpu/gpu_plugin/gpu_processor.cc delete mode 100644 o3d/gpu/gpu_plugin/gpu_processor.h delete mode 100644 o3d/gpu/gpu_plugin/gpu_processor_mock.h delete mode 100644 o3d/gpu/gpu_plugin/gpu_processor_unittest.cc delete mode 100644 o3d/gpu/gpu_plugin/gpu_processor_win.cc delete mode 100644 o3d/gpu/np_utils/default_np_object.h delete mode 100644 o3d/gpu/np_utils/dispatched_np_object_unittest.cc delete mode 100644 o3d/gpu/np_utils/dynamic_np_object.cc delete mode 100644 o3d/gpu/np_utils/dynamic_np_object.h delete mode 100644 o3d/gpu/np_utils/dynamic_np_object_unittest.cc delete mode 100644 o3d/gpu/np_utils/np_browser.cc delete mode 100644 o3d/gpu/np_utils/np_browser.h delete mode 100644 o3d/gpu/np_utils/np_browser_mock.h delete mode 100644 o3d/gpu/np_utils/np_browser_stub.cc delete mode 100644 o3d/gpu/np_utils/np_browser_stub.h delete mode 100644 o3d/gpu/np_utils/np_class.h delete mode 100644 o3d/gpu/np_utils/np_class_unittest.cc delete mode 100644 o3d/gpu/np_utils/np_dispatcher.cc delete mode 100644 o3d/gpu/np_utils/np_dispatcher.h delete mode 100644 o3d/gpu/np_utils/np_dispatcher_specializations.h delete mode 100644 o3d/gpu/np_utils/np_headers.h delete mode 100644 o3d/gpu/np_utils/np_object_mock.h delete mode 100644 o3d/gpu/np_utils/np_object_pointer.h delete mode 100644 o3d/gpu/np_utils/np_object_pointer_unittest.cc delete mode 100644 o3d/gpu/np_utils/np_plugin_object.h delete mode 100644 o3d/gpu/np_utils/np_plugin_object_factory.cc delete mode 100644 o3d/gpu/np_utils/np_plugin_object_factory.h delete mode 100644 o3d/gpu/np_utils/np_plugin_object_factory_mock.h delete mode 100644 o3d/gpu/np_utils/np_plugin_object_mock.h delete mode 100644 o3d/gpu/np_utils/np_utils.cc delete mode 100644 o3d/gpu/np_utils/np_utils.h delete mode 100644 o3d/gpu/np_utils/np_utils_unittest.cc delete mode 100644 o3d/gpu/np_utils/webkit_browser.h create mode 100644 o3d/gpu_plugin/command_buffer.cc create mode 100644 o3d/gpu_plugin/command_buffer.h create mode 100644 o3d/gpu_plugin/command_buffer_mock.h create mode 100644 o3d/gpu_plugin/command_buffer_unittest.cc create mode 100644 o3d/gpu_plugin/gpu_plugin.cc create mode 100644 o3d/gpu_plugin/gpu_plugin.gyp create mode 100644 o3d/gpu_plugin/gpu_plugin.h create mode 100644 o3d/gpu_plugin/gpu_plugin_object.cc create mode 100644 o3d/gpu_plugin/gpu_plugin_object.h create mode 100644 o3d/gpu_plugin/gpu_plugin_object_factory.cc create mode 100644 o3d/gpu_plugin/gpu_plugin_object_factory.h create mode 100644 o3d/gpu_plugin/gpu_plugin_object_factory_unittest.cc create mode 100644 o3d/gpu_plugin/gpu_plugin_object_unittest.cc create mode 100644 o3d/gpu_plugin/gpu_plugin_object_win.cc create mode 100644 o3d/gpu_plugin/gpu_plugin_unittest.cc create mode 100644 o3d/gpu_plugin/gpu_processor.cc create mode 100644 o3d/gpu_plugin/gpu_processor.h create mode 100644 o3d/gpu_plugin/gpu_processor_mock.h create mode 100644 o3d/gpu_plugin/gpu_processor_unittest.cc create mode 100644 o3d/gpu_plugin/gpu_processor_win.cc create mode 100644 o3d/gpu_plugin/np_utils/default_np_object.h create mode 100644 o3d/gpu_plugin/np_utils/dispatched_np_object_unittest.cc create mode 100644 o3d/gpu_plugin/np_utils/dynamic_np_object.cc create mode 100644 o3d/gpu_plugin/np_utils/dynamic_np_object.h create mode 100644 o3d/gpu_plugin/np_utils/dynamic_np_object_unittest.cc create mode 100644 o3d/gpu_plugin/np_utils/np_browser.cc create mode 100644 o3d/gpu_plugin/np_utils/np_browser.h create mode 100644 o3d/gpu_plugin/np_utils/np_browser_mock.h create mode 100644 o3d/gpu_plugin/np_utils/np_browser_stub.cc create mode 100644 o3d/gpu_plugin/np_utils/np_browser_stub.h create mode 100644 o3d/gpu_plugin/np_utils/np_class.h create mode 100644 o3d/gpu_plugin/np_utils/np_class_unittest.cc create mode 100644 o3d/gpu_plugin/np_utils/np_dispatcher.cc create mode 100644 o3d/gpu_plugin/np_utils/np_dispatcher.h create mode 100644 o3d/gpu_plugin/np_utils/np_dispatcher_specializations.h create mode 100644 o3d/gpu_plugin/np_utils/np_headers.h create mode 100644 o3d/gpu_plugin/np_utils/np_object_mock.h create mode 100644 o3d/gpu_plugin/np_utils/np_object_pointer.h create mode 100644 o3d/gpu_plugin/np_utils/np_object_pointer_unittest.cc create mode 100644 o3d/gpu_plugin/np_utils/np_plugin_object.h create mode 100644 o3d/gpu_plugin/np_utils/np_plugin_object_factory.cc create mode 100644 o3d/gpu_plugin/np_utils/np_plugin_object_factory.h create mode 100644 o3d/gpu_plugin/np_utils/np_plugin_object_factory_mock.h create mode 100644 o3d/gpu_plugin/np_utils/np_plugin_object_mock.h create mode 100644 o3d/gpu_plugin/np_utils/np_utils.cc create mode 100644 o3d/gpu_plugin/np_utils/np_utils.h create mode 100644 o3d/gpu_plugin/np_utils/np_utils_unittest.cc create mode 100644 o3d/gpu_plugin/np_utils/webkit_browser.h (limited to 'o3d') diff --git a/o3d/build/o3d_all.gyp b/o3d/build/o3d_all.gyp index f30de4c..80447b7 100644 --- a/o3d/build/o3d_all.gyp +++ b/o3d/build/o3d_all.gyp @@ -50,8 +50,7 @@ ['renderer=="cb"', { 'dependencies': [ - '../gpu/gpu.gyp:gpu_plugin_unittests', - '../gpu/gpu.gyp:np_utils_unittests', + '../gpu_plugin/gpu_plugin.gyp:*', ], }, ], diff --git a/o3d/command_buffer/client/cmd_buffer_helper.cc b/o3d/command_buffer/client/cmd_buffer_helper.cc new file mode 100644 index 0000000..4dd2ece --- /dev/null +++ b/o3d/command_buffer/client/cmd_buffer_helper.cc @@ -0,0 +1,197 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the implementation of the command buffer helper class. + +#include "command_buffer/client/cmd_buffer_helper.h" +#include "o3d/gpu_plugin/np_utils/np_utils.h" + +namespace command_buffer { + +using gpu_plugin::CommandBuffer; +using gpu_plugin::NPBrowser; +using gpu_plugin::NPInvoke; +using gpu_plugin::NPObjectPointer; + +CommandBufferHelper::CommandBufferHelper( + NPP npp, + const NPObjectPointer& command_buffer) + : npp_(npp), + command_buffer_(command_buffer), + entries_(NULL), + entry_count_(0), + token_(0), + last_token_read_(-1), + get_(0), + put_(0) { +} + +bool CommandBufferHelper::Initialize() { + ring_buffer_ = command_buffer_->GetRingBuffer(); + if (!ring_buffer_) + return false; + + // Map the ring buffer into this process. + if (!ring_buffer_->Map(ring_buffer_->max_size())) + return false; + + entries_ = static_cast(ring_buffer_->memory()); + entry_count_ = command_buffer_->GetSize(); + get_ = command_buffer_->GetGetOffset(); + put_ = command_buffer_->GetPutOffset(); + last_token_read_ = command_buffer_->GetToken(); + + return true; +} + +CommandBufferHelper::~CommandBufferHelper() { +} + +bool CommandBufferHelper::Flush() { + get_ = command_buffer_->SyncOffsets(put_); + return !command_buffer_->GetErrorStatus(); +} + +// Calls Flush() and then waits until the buffer is empty. Break early if the +// error is set. +bool CommandBufferHelper::Finish() { + do { + // Do not loop forever if the flush fails, meaning the command buffer reader + // has shutdown). + if (!Flush()) + return false; + } while (put_ != get_); + + return true; +} + +// Inserts a new token into the command stream. It uses an increasing value +// scheme so that we don't lose tokens (a token has passed if the current token +// value is higher than that token). Calls Finish() if the token value wraps, +// which will be rare. +int32 CommandBufferHelper::InsertToken() { + // Increment token as 31-bit integer. Negative values are used to signal an + // error. + token_ = (token_ + 1) & 0x7FFFFFFF; + CommandBufferEntry args; + args.value_uint32 = token_; + const uint32 kSetToken = 1; // TODO(gman): add a common set of commands. + AddCommand(kSetToken, 1, &args); + if (token_ == 0) { + // we wrapped + Finish(); + last_token_read_ = command_buffer_->GetToken(); + DCHECK_EQ(token_, last_token_read_); + } + return token_; +} + +// Waits until the current token value is greater or equal to the value passed +// in argument. +void CommandBufferHelper::WaitForToken(int32 token) { + // Return immediately if corresponding InsertToken failed. + if (token < 0) + return; + if (last_token_read_ >= token) return; // fast path. + if (token > token_) return; // we wrapped + Flush(); + last_token_read_ = command_buffer_->GetToken(); + while (last_token_read_ < token) { + if (get_ == put_) { + LOG(FATAL) << "Empty command buffer while waiting on a token."; + return; + } + // Do not loop forever if the flush fails, meaning the command buffer reader + // has shutdown. + if (!Flush()) + return; + last_token_read_ = command_buffer_->GetToken(); + } +} + +// Waits for available entries, basically waiting until get >= put + count + 1. +// It actually waits for contiguous entries, so it may need to wrap the buffer +// around, adding noops. Thus this function may change the value of put_. +// The function will return early if an error occurs, in which case the +// available space may not be available. +void CommandBufferHelper::WaitForAvailableEntries(int32 count) { + CHECK(count < entry_count_); + if (put_ + count > entry_count_) { + // There's not enough room between the current put and the end of the + // buffer, so we need to wrap. We will add noops all the way to the end, + // but we need to make sure get wraps first, actually that get is 1 or + // more (since put will wrap to 0 after we add the noops). + DCHECK_LE(1, put_); + Flush(); + while (get_ > put_ || get_ == 0) { + // Do not loop forever if the flush fails, meaning the command buffer + // reader has shutdown. + if (!Flush()) + return; + } + // Add the noops. By convention, a noop is a command 0 with no args. + // TODO(apatrick): A noop can have a size. It would be better to add a + // single noop with a variable size. Watch out for size limit on + // individual commands. + CommandHeader header; + header.size = 1; + header.command = 0; + while (put_ < entry_count_) { + entries_[put_++].value_header = header; + } + put_ = 0; + } + // If we have enough room, return immediatly. + if (count <= AvailableEntries()) return; + // Otherwise flush, and wait until we do have enough room. + Flush(); + while (AvailableEntries() < count) { + // Do not loop forever if the flush fails, meaning the command buffer reader + // has shutdown. + if (!Flush()) + return; + } +} + +CommandBufferEntry* CommandBufferHelper::GetSpace(uint32 entries) { + WaitForAvailableEntries(entries); + CommandBufferEntry* space = &entries_[put_]; + put_ += entries; + return space; +} + +parse_error::ParseError CommandBufferHelper::GetParseError() { + int32 parse_error = command_buffer_->ResetParseError(); + return static_cast(parse_error); +} + +} // namespace command_buffer diff --git a/o3d/command_buffer/client/cmd_buffer_helper.h b/o3d/command_buffer/client/cmd_buffer_helper.h new file mode 100644 index 0000000..e17e234 --- /dev/null +++ b/o3d/command_buffer/client/cmd_buffer_helper.h @@ -0,0 +1,212 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the command buffer helper class. + +#ifndef GPU_COMMAND_BUFFER_CLIENT_CROSS_CMD_BUFFER_HELPER_H_ +#define GPU_COMMAND_BUFFER_CLIENT_CROSS_CMD_BUFFER_HELPER_H_ + +#include "command_buffer/common/logging.h" +#include "command_buffer/common/constants.h" +#include "command_buffer/common/cmd_buffer_common.h" +#include "o3d/gpu_plugin/command_buffer.h" +#include "o3d/gpu_plugin/np_utils/np_object_pointer.h" + +namespace command_buffer { + +// Command buffer helper class. This class simplifies ring buffer management: +// it will allocate the buffer, give it to the buffer interface, and let the +// user add commands to it, while taking care of the synchronization (put and +// get). It also provides a way to ensure commands have been executed, through +// the token mechanism: +// +// helper.AddCommand(...); +// helper.AddCommand(...); +// int32 token = helper.InsertToken(); +// helper.AddCommand(...); +// helper.AddCommand(...); +// [...] +// +// helper.WaitForToken(token); // this doesn't return until the first two +// // commands have been executed. +class CommandBufferHelper { + public: + CommandBufferHelper( + NPP npp, + const gpu_plugin::NPObjectPointer& + command_buffer); + virtual ~CommandBufferHelper(); + + bool Initialize(); + + // Flushes the commands, setting the put pointer to let the buffer interface + // know that new commands have been added. After a flush returns, the command + // buffer service is aware of all pending commands and it is guaranteed to + // have made some progress in processing them. Returns whether the flush was + // successful. The flush will fail if the command buffer service has + // disconnected. + bool Flush(); + + // Waits until all the commands have been executed. Returns whether it + // was successful. The function will fail if the command buffer service has + // disconnected. + bool Finish(); + + // Waits until a given number of available entries are available. + // Parameters: + // count: number of entries needed. This value must be at most + // the size of the buffer minus one. + void WaitForAvailableEntries(int32 count); + + // Adds a command data to the command buffer. This may wait until sufficient + // space is available. + // Parameters: + // entries: The command entries to add. + // count: The number of entries. + void AddCommandData(const CommandBufferEntry* entries, int32 count) { + WaitForAvailableEntries(count); + for (; count > 0; --count) { + entries_[put_++] = *entries++; + } + DCHECK_LE(put_, entry_count_); + if (put_ == entry_count_) put_ = 0; + } + + // A typed version of AddCommandData. + template + void AddTypedCmdData(const T& cmd) { + AddCommandData(reinterpret_cast(&cmd), + ComputeNumEntries(sizeof(cmd))); + } + + // Adds a command to the command buffer. This may wait until sufficient space + // is available. + // Parameters: + // command: the command index. + // arg_count: the number of arguments for the command. + // args: the arguments for the command (these are copied before the + // function returns). + void AddCommand(int32 command, + int32 arg_count, + const CommandBufferEntry *args) { + CommandHeader header; + header.size = arg_count + 1; + header.command = command; + WaitForAvailableEntries(header.size); + entries_[put_++].value_header = header; + for (int i = 0; i < arg_count; ++i) { + entries_[put_++] = args[i]; + } + DCHECK_LE(put_, entry_count_); + if (put_ == entry_count_) put_ = 0; + } + + // Inserts a new token into the command buffer. This token either has a value + // different from previously inserted tokens, or ensures that previously + // inserted tokens with that value have already passed through the command + // stream. + // Returns: + // the value of the new token or -1 if the command buffer reader has + // shutdown. + int32 InsertToken(); + + // Waits until the token of a particular value has passed through the command + // stream (i.e. commands inserted before that token have been executed). + // NOTE: This will call Flush if it needs to block. + // Parameters: + // the value of the token to wait for. + void WaitForToken(int32 token); + + // Waits for a certain amount of space to be available. Returns address + // of space. + CommandBufferEntry* GetSpace(uint32 entries); + + // Typed version of GetSpace. Gets enough room for the given type and returns + // a reference to it. + template + T& GetCmdSpace() { + COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed); + uint32 space_needed = ComputeNumEntries(sizeof(T)); + void* data = GetSpace(space_needed); + return *reinterpret_cast(data); + } + + // Typed version of GetSpace for immediate commands. + template + T& GetImmediateCmdSpace(size_t space) { + COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); + uint32 space_needed = ComputeNumEntries(sizeof(T) + space); + void* data = GetSpace(space_needed); + return *reinterpret_cast(data); + } + + parse_error::ParseError GetParseError(); + + // Common Commands + void Noop(uint32 skip_count) { + cmd::Noop& cmd = GetImmediateCmdSpace( + skip_count * sizeof(CommandBufferEntry)); + cmd.Init(skip_count); + } + + void SetToken(uint32 token) { + cmd::SetToken& cmd = GetCmdSpace(); + cmd.Init(token); + } + + + private: + // Waits until get changes, updating the value of get_. + void WaitForGetChange(); + + // Returns the number of available entries (they may not be contiguous). + int32 AvailableEntries() { + return (get_ - put_ - 1 + entry_count_) % entry_count_; + } + + NPP npp_; + gpu_plugin::NPObjectPointer command_buffer_; + ::base::SharedMemory* ring_buffer_; + CommandBufferEntry *entries_; + int32 entry_count_; + int32 token_; + int32 last_token_read_; + int32 get_; + int32 put_; + + friend class CommandBufferHelperTest; + DISALLOW_COPY_AND_ASSIGN(CommandBufferHelper); +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_CLIENT_CROSS_CMD_BUFFER_HELPER_H_ diff --git a/o3d/command_buffer/client/cmd_buffer_helper_test.cc b/o3d/command_buffer/client/cmd_buffer_helper_test.cc new file mode 100644 index 0000000..b7a4f85 --- /dev/null +++ b/o3d/command_buffer/client/cmd_buffer_helper_test.cc @@ -0,0 +1,298 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// Tests for the Command Buffer Helper. + +#include "tests/common/win/testing_common.h" +#include "base/message_loop.h" +#include "command_buffer/client/cmd_buffer_helper.h" +#include "command_buffer/service/mocks.h" +#include "gpu_plugin/command_buffer.h" +#include "gpu_plugin/gpu_processor.h" +#include "gpu_plugin/np_utils/np_object_pointer.h" + +namespace command_buffer { + +using gpu_plugin::CommandBuffer; +using gpu_plugin::GPUProcessor; +using gpu_plugin::NPCreateObject; +using gpu_plugin::NPObjectPointer; +using testing::Return; +using testing::Mock; +using testing::Truly; +using testing::Sequence; +using testing::DoAll; +using testing::Invoke; +using testing::_; + +const int32 kNumCommandEntries = 10; +const int32 kCommandBufferSizeBytes = kNumCommandEntries * sizeof(int32); + +// Test fixture for CommandBufferHelper test - Creates a CommandBufferHelper, +// using a CommandBufferEngine with a mock AsyncAPIInterface for its interface +// (calling it directly, not through the RPC mechanism). +class CommandBufferHelperTest : public testing::Test { + protected: + virtual void SetUp() { + api_mock_.reset(new AsyncAPIMock); + // ignore noops in the mock - we don't want to inspect the internals of the + // helper. + EXPECT_CALL(*api_mock_, DoCommand(0, 0, _)) + .WillRepeatedly(Return(parse_error::kParseNoError)); + + ::base::SharedMemory* ring_buffer = new ::base::SharedMemory; + ring_buffer->Create(std::wstring(), false, false, kCommandBufferSizeBytes); + ring_buffer->Map(1024); + + command_buffer_ = NPCreateObject(NULL); + command_buffer_->Initialize(ring_buffer); + + parser_ = new command_buffer::CommandParser(ring_buffer->memory(), + kCommandBufferSizeBytes, + 0, + kCommandBufferSizeBytes, + 0, + api_mock_.get()); + + scoped_refptr gpu_processor(new GPUProcessor( + NULL, command_buffer_.Get(), NULL, NULL, parser_, 1)); + command_buffer_->SetPutOffsetChangeCallback(NewCallback( + gpu_processor.get(), &GPUProcessor::ProcessCommands)); + + api_mock_->set_engine(gpu_processor.get()); + + helper_.reset(new CommandBufferHelper(NULL, command_buffer_)); + helper_->Initialize(); + } + + virtual void TearDown() { + // If the GPUProcessor posts any tasks, this forces them to run. + MessageLoop::current()->RunAllPending(); + helper_.release(); + } + + // Adds a command to the buffer through the helper, while adding it as an + // expected call on the API mock. + void AddCommandWithExpect(parse_error::ParseError _return, + unsigned int command, + unsigned int arg_count, + CommandBufferEntry *args) { + helper_->AddCommand(command, arg_count, args); + EXPECT_CALL(*api_mock_, DoCommand(command, arg_count, + Truly(AsyncAPIMock::IsArgs(arg_count, args)))) + .InSequence(sequence_) + .WillOnce(Return(_return)); + } + + // Checks that the buffer from put to put+size is free in the parser. + void CheckFreeSpace(CommandBufferOffset put, unsigned int size) { + CommandBufferOffset parser_put = parser_->put(); + CommandBufferOffset parser_get = parser_->get(); + CommandBufferOffset limit = put + size; + if (parser_get > parser_put) { + // "busy" buffer wraps, so "free" buffer is between put (inclusive) and + // get (exclusive). + EXPECT_LE(parser_put, put); + EXPECT_GT(parser_get, limit); + } else { + // "busy" buffer does not wrap, so the "free" buffer is the top side (from + // put to the limit) and the bottom side (from 0 to get). + if (put >= parser_put) { + // we're on the top side, check we are below the limit. + EXPECT_GE(kNumCommandEntries, limit); + } else { + // we're on the bottom side, check we are below get. + EXPECT_GT(parser_get, limit); + } + } + } + + CommandBufferOffset get_helper_put() { return helper_->put_; } + + scoped_ptr api_mock_; + NPObjectPointer command_buffer_; + command_buffer::CommandParser* parser_; + scoped_ptr helper_; + Sequence sequence_; +}; + +// Checks that commands in the buffer are properly executed, and that the +// status/error stay valid. +TEST_F(CommandBufferHelperTest, TestCommandProcessing) { + // Check initial state of the engine - it should have been configured by the + // helper. + EXPECT_TRUE(parser_ != NULL); + EXPECT_FALSE(command_buffer_->GetErrorStatus()); + EXPECT_EQ(parse_error::kParseNoError, command_buffer_->ResetParseError()); + EXPECT_EQ(0u, command_buffer_->GetGetOffset()); + + // Add 3 commands through the helper + AddCommandWithExpect(parse_error::kParseNoError, 1, 0, NULL); + + CommandBufferEntry args1[2]; + args1[0].value_uint32 = 3; + args1[1].value_float = 4.f; + AddCommandWithExpect(parse_error::kParseNoError, 2, 2, args1); + + CommandBufferEntry args2[2]; + args2[0].value_uint32 = 5; + args2[1].value_float = 6.f; + AddCommandWithExpect(parse_error::kParseNoError, 3, 2, args2); + + helper_->Flush(); + // Check that the engine has work to do now. + EXPECT_FALSE(parser_->IsEmpty()); + + // Wait until it's done. + helper_->Finish(); + // Check that the engine has no more work to do. + EXPECT_TRUE(parser_->IsEmpty()); + + // Check that the commands did happen. + Mock::VerifyAndClearExpectations(api_mock_.get()); + + // Check the error status. + EXPECT_FALSE(command_buffer_->GetErrorStatus()); + EXPECT_EQ(parse_error::kParseNoError, command_buffer_->ResetParseError()); +} + +// Checks that commands in the buffer are properly executed when wrapping the +// buffer, and that the status/error stay valid. +TEST_F(CommandBufferHelperTest, TestCommandWrapping) { + // Add 5 commands of size 3 through the helper to make sure we do wrap. + CommandBufferEntry args1[2]; + args1[0].value_uint32 = 3; + args1[1].value_float = 4.f; + + for (unsigned int i = 0; i < 5; ++i) { + AddCommandWithExpect(parse_error::kParseNoError, i + 1, 2, args1); + } + + helper_->Finish(); + // Check that the commands did happen. + Mock::VerifyAndClearExpectations(api_mock_.get()); + + // Check the error status. + EXPECT_FALSE(command_buffer_->GetErrorStatus()); + EXPECT_EQ(parse_error::kParseNoError, command_buffer_->ResetParseError()); +} + + +// Checks that commands in the buffer are properly executed, even if they +// generate a recoverable error. Check that the error status is properly set, +// and reset when queried. +TEST_F(CommandBufferHelperTest, TestRecoverableError) { + CommandBufferEntry args[2]; + args[0].value_uint32 = 3; + args[1].value_float = 4.f; + + // Create a command buffer with 3 commands, 2 of them generating errors + AddCommandWithExpect(parse_error::kParseNoError, 1, 2, args); + AddCommandWithExpect(parse_error::kParseUnknownCommand, 2, 2, args); + AddCommandWithExpect(parse_error::kParseInvalidArguments, 3, 2, + args); + + helper_->Finish(); + // Check that the commands did happen. + Mock::VerifyAndClearExpectations(api_mock_.get()); + + // Check that the error status was set to the first error. + EXPECT_EQ(parse_error::kParseUnknownCommand, + command_buffer_->ResetParseError()); + // Check that the error status was reset after the query. + EXPECT_EQ(parse_error::kParseNoError, command_buffer_->ResetParseError()); +} + +// Checks that asking for available entries work, and that the parser +// effectively won't use that space. +TEST_F(CommandBufferHelperTest, TestAvailableEntries) { + CommandBufferEntry args[2]; + args[0].value_uint32 = 3; + args[1].value_float = 4.f; + + // Add 2 commands through the helper - 8 entries + AddCommandWithExpect(parse_error::kParseNoError, 1, 0, NULL); + AddCommandWithExpect(parse_error::kParseNoError, 2, 0, NULL); + AddCommandWithExpect(parse_error::kParseNoError, 3, 2, args); + AddCommandWithExpect(parse_error::kParseNoError, 4, 2, args); + + // Ask for 5 entries. + helper_->WaitForAvailableEntries(5); + + CommandBufferOffset put = get_helper_put(); + CheckFreeSpace(put, 5); + + // Add more commands. + AddCommandWithExpect(parse_error::kParseNoError, 5, 2, args); + + // Wait until everything is done done. + helper_->Finish(); + + // Check that the commands did happen. + Mock::VerifyAndClearExpectations(api_mock_.get()); + + // Check the error status. + EXPECT_FALSE(command_buffer_->GetErrorStatus()); + EXPECT_EQ(parse_error::kParseNoError, command_buffer_->ResetParseError()); +} + +// Checks that the InsertToken/WaitForToken work. +TEST_F(CommandBufferHelperTest, TestToken) { + CommandBufferEntry args[2]; + args[0].value_uint32 = 3; + args[1].value_float = 4.f; + + // Add a first command. + AddCommandWithExpect(parse_error::kParseNoError, 3, 2, args); + // keep track of the buffer position. + CommandBufferOffset command1_put = get_helper_put(); + int32 token = helper_->InsertToken(); + + EXPECT_CALL(*api_mock_.get(), DoCommand(cmd::kSetToken, 1, _)) + .WillOnce(DoAll(Invoke(api_mock_.get(), &AsyncAPIMock::SetToken), + Return(parse_error::kParseNoError))); + // Add another command. + AddCommandWithExpect(parse_error::kParseNoError, 4, 2, args); + helper_->WaitForToken(token); + // check that the get pointer is beyond the first command. + EXPECT_LE(command1_put, command_buffer_->GetGetOffset()); + helper_->Finish(); + + // Check that the commands did happen. + Mock::VerifyAndClearExpectations(api_mock_.get()); + + // Check the error status. + EXPECT_FALSE(command_buffer_->GetErrorStatus()); + EXPECT_EQ(parse_error::kParseNoError, command_buffer_->ResetParseError()); +} + +} // namespace command_buffer diff --git a/o3d/command_buffer/client/effect_helper.cc b/o3d/command_buffer/client/effect_helper.cc new file mode 100644 index 0000000..eb7faf9 --- /dev/null +++ b/o3d/command_buffer/client/effect_helper.cc @@ -0,0 +1,250 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file implements the EffectHelper class. + +#include "command_buffer/common/o3d_cmd_format.h" +#include "command_buffer/client/cmd_buffer_helper.h" +#include "command_buffer/client/effect_helper.h" +#include "command_buffer/client/fenced_allocator.h" +#include "command_buffer/client/id_allocator.h" + +// TODO: write a unit test. + +namespace command_buffer { + +bool EffectHelper::CreateEffectParameters(ResourceId effect_id, + std::vector *descs) { + using effect_param::Desc; + DCHECK_NE(effect_id, kInvalidResource); + DCHECK(descs); + descs->clear(); + + // Get the param count. + Uint32 *retval = shm_allocator_->AllocTyped(1); + helper_->GetParamCount(effect_id, sizeof(*retval), + shm_id_, shm_allocator_->GetOffset(retval)); + // Finish has to be called to get the result. + helper_->Finish(); + + // We could have failed if the effect_id is invalid. + if (helper_->GetParseError() != parse_error::kParseNoError) { + shm_allocator_->Free(retval); + return false; + } + unsigned int param_count = *retval; + + shm_allocator_->Free(retval); + unsigned int max_buffer_size = shm_allocator_->GetLargestFreeOrPendingSize(); + if (max_buffer_size < sizeof(Desc)) { // NOLINT + // Not enough memory to get at least 1 param desc. + return false; + } + descs->resize(param_count); + for (unsigned int i = 0; i < param_count; ++i) { + EffectParamDesc *desc = &((*descs)[i]); + desc->id = param_id_allocator_->AllocateID(); + helper_->CreateParam(desc->id, effect_id, i); + } + + // Read param descriptions in batches. We use as much shared memory as + // possible so that we only call Finish as little as possible. + unsigned int max_param_per_batch = + std::min(static_cast(param_count), + static_cast(max_buffer_size / sizeof(Desc))); // NOLINT + Desc *raw_descs = shm_allocator_->AllocTyped(max_param_per_batch); + DCHECK(raw_descs); + for (unsigned int i = 0; i < param_count; i += max_param_per_batch) { + unsigned int count = std::min(param_count - i, max_param_per_batch); + for (unsigned int j = 0 ; j < count; ++j) { + EffectParamDesc *desc = &((*descs)[i + j]); + Desc *raw_desc = raw_descs + j; + helper_->GetParamDesc(desc->id, sizeof(*raw_desc), + shm_id_, + shm_allocator_->GetOffset(raw_desc)); + } + // Finish to get the results. + helper_->Finish(); + DCHECK_EQ(helper_->GetParseError(), parse_error::kParseNoError); + for (unsigned int j = 0 ; j < count; ++j) { + EffectParamDesc *desc = &((*descs)[i + j]); + Desc *raw_desc = raw_descs + j; + desc->data_type = raw_desc->data_type; + desc->data_size = raw_desc->data_size; + desc->num_elements = raw_desc->num_elements; + desc->cmd_desc_size = raw_desc->size; + } + } + shm_allocator_->Free(raw_descs); + return true; +} + +bool EffectHelper::GetParamStrings(EffectParamDesc *desc) { + using effect_param::Desc; + DCHECK(desc); + DCHECK_NE(desc->id, kInvalidResource); + // desc may not have come directly from CreateEffectParameters, so it may be + // less than the minimum required size. + unsigned int size = std::max(static_cast(desc->cmd_desc_size), + static_cast(sizeof(Desc))); // NOLINT + Desc *raw_desc = static_cast(shm_allocator_->Alloc(size)); + if (!raw_desc) { + // Not enough memory to get the param desc. + return false; + } + helper_->GetParamDesc(desc->id, size, + shm_id_, + shm_allocator_->GetOffset(raw_desc)); + + // Finish to get the results. + helper_->Finish(); + + // We could have failed if the param ID is invalid. + if (helper_->GetParseError() != parse_error::kParseNoError) { + shm_allocator_->Free(raw_desc); + return false; + } + + if (raw_desc->size > size) { + // We had not allocated enough memory the first time (e.g. if the + // EffectParamDesc didn't come from CreateEffectParameters, so the user had + // no way of knowing what size was needed for the strings), so re-allocate + // and try again. + size = raw_desc->size; + desc->cmd_desc_size = size; + shm_allocator_->Free(raw_desc); + raw_desc = static_cast(shm_allocator_->Alloc(size)); + if (!raw_desc) { + // Not enough memory to get the param desc. + return false; + } + helper_->GetParamDesc(desc->id, size, + shm_id_, + shm_allocator_->GetOffset(raw_desc)); + // Finish to get the results. + helper_->Finish(); + DCHECK_EQ(helper_->GetParseError(), parse_error::kParseNoError); + DCHECK_EQ(raw_desc->size, size); + } + + const char *raw_desc_string = reinterpret_cast(raw_desc); + if (raw_desc->name_offset) { + DCHECK_LE(raw_desc->name_offset + raw_desc->name_size, raw_desc->size); + DCHECK_GT(raw_desc->name_size, 0U); + DCHECK_EQ(raw_desc_string[raw_desc->name_offset + raw_desc->name_size - 1], + 0); + desc->name = String(raw_desc_string + raw_desc->name_offset, + raw_desc->name_size - 1); + } else { + desc->name.clear(); + } + if (raw_desc->semantic_offset) { + DCHECK_LE(raw_desc->semantic_offset + raw_desc->semantic_size, + raw_desc->size); + DCHECK_GT(raw_desc->semantic_size, 0U); + DCHECK_EQ(raw_desc_string[raw_desc->semantic_offset + + raw_desc->semantic_size - 1], + 0); + desc->semantic = String(raw_desc_string + raw_desc->semantic_offset, + raw_desc->semantic_size - 1); + } else { + desc->semantic.clear(); + } + shm_allocator_->Free(raw_desc); + return true; +} + +void EffectHelper::DestroyEffectParameters( + const std::vector &descs) { + for (unsigned int i = 0; i < descs.size(); ++i) { + const EffectParamDesc &desc = descs[i]; + helper_->DestroyParam(desc.id); + param_id_allocator_->FreeID(desc.id); + } +} + +bool EffectHelper::GetEffectStreams(ResourceId effect_id, + std::vector *descs) { + using effect_stream::Desc; + DCHECK_NE(effect_id, kInvalidResource); + + // Get the param count. + Uint32 *retval = shm_allocator_->AllocTyped(1); + helper_->GetStreamCount(effect_id, sizeof(*retval), + shm_id_, + shm_allocator_->GetOffset(retval)); + // Finish has to be called to get the result. + helper_->Finish(); + + // We could have failed if the effect_id is invalid. + if (helper_->GetParseError() != parse_error::kParseNoError) { + shm_allocator_->Free(retval); + return false; + } + unsigned int stream_count = *retval; + shm_allocator_->Free(retval); + unsigned int max_buffer_size = shm_allocator_->GetLargestFreeOrPendingSize(); + if (max_buffer_size < sizeof(Desc)) { // NOLINT + // Not enough memory to get at least 1 stream desc. + return false; + } + descs->resize(stream_count); + + // Read stream descriptions in batches. We use as much shared memory as + // possible so that we only call Finish as little as possible. + unsigned int max_stream_per_batch = + std::min(static_cast(stream_count), + static_cast(max_buffer_size / sizeof(Desc))); // NOLINT + Desc *raw_descs = shm_allocator_->AllocTyped(max_stream_per_batch); + DCHECK(raw_descs); + for (unsigned int i = 0; i < stream_count; i += max_stream_per_batch) { + unsigned int count = std::min(stream_count - i, max_stream_per_batch); + for (unsigned int j = 0 ; j < count; ++j) { + Desc *raw_desc = raw_descs + j; + helper_->GetStreamDesc(effect_id, i + j, sizeof(*raw_desc), + shm_id_, + shm_allocator_->GetOffset(raw_desc)); + } + // Finish to get the results. + helper_->Finish(); + DCHECK_EQ(helper_->GetParseError(), parse_error::kParseNoError); + for (unsigned int j = 0 ; j < count; ++j) { + EffectStreamDesc *desc = &((*descs)[i + j]); + Desc *raw_desc = raw_descs + j; + desc->semantic = static_cast(raw_desc->semantic); + desc->semantic_index = raw_desc->semantic_index; + } + } + shm_allocator_->Free(raw_descs); + return true; +} +} // namespace command_buffer diff --git a/o3d/command_buffer/client/effect_helper.h b/o3d/command_buffer/client/effect_helper.h new file mode 100644 index 0000000..a20375c --- /dev/null +++ b/o3d/command_buffer/client/effect_helper.h @@ -0,0 +1,156 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file defines the EffectHelper class. + +#ifndef GPU_COMMAND_BUFFER_CLIENT_CROSS_EFFECT_HELPER_H_ +#define GPU_COMMAND_BUFFER_CLIENT_CROSS_EFFECT_HELPER_H_ + +#include +#include "command_buffer/common/resource.h" +#include "command_buffer/client/o3d_cmd_helper.h" + +namespace command_buffer { + +class FencedAllocatorWrapper; +class IdAllocator; +class CommandBufferHelper; + +// A helper class to find parameters in an effect. +class EffectHelper { + public: + // A more usable version of effect_param::Desc + struct EffectParamDesc { + ResourceId id; // The resource ID for the param. + String name; // The name of the param. + String semantic; // The semantic of the param. + effect_param::DataType data_type; // The data type of a param. + unsigned int data_size; // The size of the data for a param. + int num_elements; // The number of array entries if the + // parameter is an array, 0 otherwise. + unsigned int cmd_desc_size; // The size of the effect_param::Desc + // structure (counting strings) for a + // param. + }; + struct EffectStreamDesc { + vertex_struct::Semantic semantic; // The semantic enum type. + unsigned int semantic_index; + }; + + EffectHelper(O3DCmdHelper *helper, + FencedAllocatorWrapper *shm_allocator, + unsigned int shm_id, + IdAllocator *param_id_allocator) + : helper_(helper), + shm_allocator_(shm_allocator), + shm_id_(shm_id), + param_id_allocator_(param_id_allocator) { + DCHECK(helper); + DCHECK(shm_allocator); + DCHECK(param_id_allocator); + } + + // Creates all the parameters in an effect and gets their descriptions. The + // strings will not be retrieved, so name and semantic will be empty. The + // cmd_desc_size field will be set to the proper size to be able to get the + // strings with a single command within GetParamStrings, so it should be left + // alone. + // + // The ResourceIDs will be allocated in the param_id_allocator. + // Temporary buffers will be allocated in the shm_allocator, but they will be + // freed before the function returns (possibly pending a token). At least + // sizeof(effect_param::Desc) must be available for this function to succeed. + // This function will call Finish(), hence will block. + // + // Parameters: + // effect_id: the ResourceId of the effect. + // descs: A pointer to a vector containing the returned descriptions. + // The pointed vector will be cleared. + // Returns: + // true if successful. Reasons for failure are: + // - invalid effect_id, + // - not enough memory in the shm_allocator_. + bool CreateEffectParameters(ResourceId effect_id, + std::vector *descs); + + // Gets the strings for a desc. This will fill in the values for the name and + // semantic fields. + // Temporary buffers will be allocated in the shm_allocator, but they will be + // freed before the function returns (possibly pending a token). At least + // desc.cmd_desc_size (as returned by CreateEffectParameters) must be + // available for this function to succeed. + // This function will call Finish(), hence will block. + // + // Parameters: + // desc: a pointer to the description for a parameter. The id field should + // be set to the ResourceId of the parameter. + // Returns: + // true if successful. Reasons for failure are: + // - invalid parameter ResourceId, + // - not enough memory in the shm_allocator_. + bool GetParamStrings(EffectParamDesc *desc); + + // Destroys all parameter resources referenced by the descriptions. The + // ResourceId will be freed from the param_id_allocator. + // Parameters: + // descs: the vector of descriptions containing the ResourceIDs of the + // parameters to destroy. + void DestroyEffectParameters(const std::vector &descs); + + // Gets all the input stream semantics and semantic indices in an + // array. These will be retrieved as many as possible at a time. At least + // sizeof(effect_param::Desc) must be available for this function to succeed. + // This function will call Finish(), hence will block. + // + // Parameters: + // effect_id: the ResourceId of the effect. + // descs: A pointer to a vector containing the returned descriptions. + // The pointed vector will be cleared. + // Returns: + // true if successful. Reasons for failure are: + // - invalid effect_id, + // - not enough memory in the shm_allocator_. + bool GetEffectStreams(ResourceId effect_id, + std::vector *descs); + + private: + O3DCmdHelper *helper_; + FencedAllocatorWrapper *shm_allocator_; + unsigned int shm_id_; + IdAllocator *param_id_allocator_; + + DISALLOW_COPY_AND_ASSIGN(EffectHelper); +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_CLIENT_CROSS_EFFECT_HELPER_H_ diff --git a/o3d/command_buffer/client/fenced_allocator.cc b/o3d/command_buffer/client/fenced_allocator.cc new file mode 100644 index 0000000..990d013 --- /dev/null +++ b/o3d/command_buffer/client/fenced_allocator.cc @@ -0,0 +1,214 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the implementation of the FencedAllocator class. + +#include "command_buffer/client/fenced_allocator.h" +#include +#include "command_buffer/client/cmd_buffer_helper.h" + +namespace command_buffer { + +#ifndef COMPILER_MSVC +const FencedAllocator::Offset FencedAllocator::kInvalidOffset; +#endif + +FencedAllocator::~FencedAllocator() { + // Free blocks pending tokens. + for (unsigned int i = 0; i < blocks_.size(); ++i) { + if (blocks_[i].state == FREE_PENDING_TOKEN) { + i = WaitForTokenAndFreeBlock(i); + } + } + DCHECK_EQ(blocks_.size(), 1u); + DCHECK_EQ(blocks_[0].state, FREE); +} + +// Looks for a non-allocated block that is big enough. Search in the FREE +// blocks first (for direct usage), first-fit, then in the FREE_PENDING_TOKEN +// blocks, waiting for them. The current implementation isn't smart about +// optimizing what to wait for, just looks inside the block in order (first-fit +// as well). +FencedAllocator::Offset FencedAllocator::Alloc(unsigned int size) { + // Similarly to malloc, an allocation of 0 allocates at least 1 byte, to + // return different pointers every time. + if (size == 0) size = 1; + + // Try first to allocate in a free block. + for (unsigned int i = 0; i < blocks_.size(); ++i) { + Block &block = blocks_[i]; + if (block.state == FREE && block.size >= size) { + return AllocInBlock(i, size); + } + } + + // No free block is available. Look for blocks pending tokens, and wait for + // them to be re-usable. + for (unsigned int i = 0; i < blocks_.size(); ++i) { + if (blocks_[i].state != FREE_PENDING_TOKEN) + continue; + i = WaitForTokenAndFreeBlock(i); + if (blocks_[i].size >= size) + return AllocInBlock(i, size); + } + return kInvalidOffset; +} + +// Looks for the corresponding block, mark it FREE, and collapse it if +// necessary. +void FencedAllocator::Free(FencedAllocator::Offset offset) { + BlockIndex index = GetBlockByOffset(offset); + DCHECK_NE(blocks_[index].state, FREE); + blocks_[index].state = FREE; + CollapseFreeBlock(index); +} + +// Looks for the corresponding block, mark it FREE_PENDING_TOKEN. +void FencedAllocator::FreePendingToken(FencedAllocator::Offset offset, + unsigned int token) { + BlockIndex index = GetBlockByOffset(offset); + Block &block = blocks_[index]; + block.state = FREE_PENDING_TOKEN; + block.token = token; +} + +// Gets the max of the size of the blocks marked as free. +unsigned int FencedAllocator::GetLargestFreeSize() { + unsigned int max_size = 0; + for (unsigned int i = 0; i < blocks_.size(); ++i) { + Block &block = blocks_[i]; + if (block.state == FREE) + max_size = std::max(max_size, block.size); + } + return max_size; +} + +// Gets the size of the largest segment of blocks that are either FREE or +// FREE_PENDING_TOKEN. +unsigned int FencedAllocator::GetLargestFreeOrPendingSize() { + unsigned int max_size = 0; + unsigned int current_size = 0; + for (unsigned int i = 0; i < blocks_.size(); ++i) { + Block &block = blocks_[i]; + if (block.state == IN_USE) { + max_size = std::max(max_size, current_size); + current_size = 0; + } else { + DCHECK(block.state == FREE || block.state == FREE_PENDING_TOKEN); + current_size += block.size; + } + } + return std::max(max_size, current_size); +} + +// Makes sure that: +// - there is at least one block. +// - there are no contiguous FREE blocks (they should have been collapsed). +// - the successive offsets match the block sizes, and they are in order. +bool FencedAllocator::CheckConsistency() { + if (blocks_.size() < 1) return false; + for (unsigned int i = 0; i < blocks_.size() - 1; ++i) { + Block ¤t = blocks_[i]; + Block &next = blocks_[i + 1]; + // This test is NOT included in the next one, because offset is unsigned. + if (next.offset <= current.offset) + return false; + if (next.offset != current.offset + current.size) + return false; + if (current.state == FREE && next.state == FREE) + return false; + } + return true; +} + +// Collapse the block to the next one, then to the previous one. Provided the +// structure is consistent, those are the only blocks eligible for collapse. +FencedAllocator::BlockIndex FencedAllocator::CollapseFreeBlock( + BlockIndex index) { + if (index + 1 < blocks_.size()) { + Block &next = blocks_[index + 1]; + if (next.state == FREE) { + blocks_[index].size += next.size; + blocks_.erase(blocks_.begin() + index + 1); + } + } + if (index > 0) { + Block &prev = blocks_[index - 1]; + if (prev.state == FREE) { + prev.size += blocks_[index].size; + blocks_.erase(blocks_.begin() + index); + --index; + } + } + return index; +} + +// Waits for the block's token, then mark the block as free, then collapse it. +FencedAllocator::BlockIndex FencedAllocator::WaitForTokenAndFreeBlock( + BlockIndex index) { + Block &block = blocks_[index]; + DCHECK_EQ(block.state, FREE_PENDING_TOKEN); + helper_->WaitForToken(block.token); + block.state = FREE; + return CollapseFreeBlock(index); +} + +// If the block is exactly the requested size, simply mark it IN_USE, otherwise +// split it and mark the first one (of the requested size) IN_USE. +FencedAllocator::Offset FencedAllocator::AllocInBlock(BlockIndex index, + unsigned int size) { + Block &block = blocks_[index]; + DCHECK_GE(block.size, size); + DCHECK_EQ(block.state, FREE); + Offset offset = block.offset; + if (block.size == size) { + block.state = IN_USE; + return offset; + } + Block newblock = { FREE, offset + size, block.size - size, kUnusedToken}; + block.state = IN_USE; + block.size = size; + // this is the last thing being done because it may invalidate block; + blocks_.insert(blocks_.begin() + index + 1, newblock); + return offset; +} + +// The blocks are in offset order, so we can do a binary search. +FencedAllocator::BlockIndex FencedAllocator::GetBlockByOffset(Offset offset) { + Block templ = { IN_USE, offset, 0, kUnusedToken }; + Container::iterator it = std::lower_bound(blocks_.begin(), blocks_.end(), + templ, OffsetCmp()); + DCHECK(it != blocks_.end() && it->offset == offset); + return it-blocks_.begin(); +} + +} // namespace command_buffer diff --git a/o3d/command_buffer/client/fenced_allocator.h b/o3d/command_buffer/client/fenced_allocator.h new file mode 100644 index 0000000..96c3a8a --- /dev/null +++ b/o3d/command_buffer/client/fenced_allocator.h @@ -0,0 +1,266 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the definition of the FencedAllocator class. + +#ifndef GPU_COMMAND_BUFFER_CLIENT_CROSS_FENCED_ALLOCATOR_H_ +#define GPU_COMMAND_BUFFER_CLIENT_CROSS_FENCED_ALLOCATOR_H_ + +#include +#include "base/basictypes.h" +#include "command_buffer/common/logging.h" + +namespace command_buffer { +class CommandBufferHelper; + +// FencedAllocator provides a mechanism to manage allocations within a fixed +// block of memory (storing the book-keeping externally). Furthermore this +// class allows to free data "pending" the passage of a command buffer token, +// that is, the memory won't be reused until the command buffer has processed +// that token. +// +// NOTE: Although this class is intended to be used in the command buffer +// environment which is multi-process, this class isn't "thread safe", because +// it isn't meant to be shared across modules. It is thread-compatible though +// (see http://www.corp.google.com/eng/doc/cpp_primer.html#thread_safety). +class FencedAllocator { + public: + typedef unsigned int Offset; + // Invalid offset, returned by Alloc in case of failure. + static const Offset kInvalidOffset = 0xffffffffU; + + // Creates a FencedAllocator. Note that the size of the buffer is passed, but + // not its base address: everything is handled as offsets into the buffer. + FencedAllocator(unsigned int size, + CommandBufferHelper *helper) + : helper_(helper) { + Block block = { FREE, 0, size, kUnusedToken }; + blocks_.push_back(block); + } + + ~FencedAllocator(); + + // Allocates a block of memory. If the buffer is out of directly available + // memory, this function may wait until memory that was freed "pending a + // token" can be re-used. + // + // Parameters: + // size: the size of the memory block to allocate. + // + // Returns: + // the offset of the allocated memory block, or kInvalidOffset if out of + // memory. + Offset Alloc(unsigned int size); + + // Frees a block of memory. + // + // Parameters: + // offset: the offset of the memory block to free. + void Free(Offset offset); + + // Frees a block of memory, pending the passage of a token. That memory won't + // be re-allocated until the token has passed through the command stream. + // + // Parameters: + // offset: the offset of the memory block to free. + // token: the token value to wait for before re-using the memory. + void FreePendingToken(Offset offset, unsigned int token); + + // Gets the size of the largest free block that is available without waiting. + unsigned int GetLargestFreeSize(); + + // Gets the size of the largest free block that can be allocated if the + // caller can wait. Allocating a block of this size will succeed, but may + // block. + unsigned int GetLargestFreeOrPendingSize(); + + // Checks for consistency inside the book-keeping structures. Used for + // testing. + bool CheckConsistency(); + + private: + // Status of a block of memory, for book-keeping. + enum State { + IN_USE, + FREE, + FREE_PENDING_TOKEN + }; + + // Book-keeping sturcture that describes a block of memory. + struct Block { + State state; + Offset offset; + unsigned int size; + unsigned int token; // token to wait for in the FREE_PENDING_TOKEN case. + }; + + // Comparison functor for memory block sorting. + class OffsetCmp { + public: + bool operator() (const Block &left, const Block &right) { + return left.offset < right.offset; + } + }; + + typedef std::vector Container; + typedef unsigned int BlockIndex; + + static const unsigned int kUnusedToken = 0; + + // Gets the index of a memory block, given its offset. + BlockIndex GetBlockByOffset(Offset offset); + + // Collapse a free block with its neighbours if they are free. Returns the + // index of the collapsed block. + // NOTE: this will invalidate block indices. + BlockIndex CollapseFreeBlock(BlockIndex index); + + // Waits for a FREE_PENDING_TOKEN block to be usable, and free it. Returns + // the new index of that block (since it may have been collapsed). + // NOTE: this will invalidate block indices. + BlockIndex WaitForTokenAndFreeBlock(BlockIndex index); + + // Allocates a block of memory inside a given block, splitting it in two + // (unless that block is of the exact requested size). + // NOTE: this will invalidate block indices. + // Returns the offset of the allocated block (NOTE: this is different from + // the other functions that return a block index). + Offset AllocInBlock(BlockIndex index, unsigned int size); + + command_buffer::CommandBufferHelper *helper_; + Container blocks_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(FencedAllocator); +}; + +// This class functions just like FencedAllocator, but its API uses pointers +// instead of offsets. +class FencedAllocatorWrapper { + public: + FencedAllocatorWrapper(unsigned int size, + CommandBufferHelper *helper, + void *base) + : allocator_(size, helper), + base_(base) { } + + // Allocates a block of memory. If the buffer is out of directly available + // memory, this function may wait until memory that was freed "pending a + // token" can be re-used. + // + // Parameters: + // size: the size of the memory block to allocate. + // + // Returns: + // the pointer to the allocated memory block, or NULL if out of + // memory. + void *Alloc(unsigned int size) { + FencedAllocator::Offset offset = allocator_.Alloc(size); + return GetPointer(offset); + } + + // Allocates a block of memory. If the buffer is out of directly available + // memory, this function may wait until memory that was freed "pending a + // token" can be re-used. + // This is a type-safe version of Alloc, returning a typed pointer. + // + // Parameters: + // count: the number of elements to allocate. + // + // Returns: + // the pointer to the allocated memory block, or NULL if out of + // memory. + template T *AllocTyped(unsigned int count) { + return static_cast(Alloc(count * sizeof(T))); + } + + // Frees a block of memory. + // + // Parameters: + // pointer: the pointer to the memory block to free. + void Free(void *pointer) { + DCHECK(pointer); + allocator_.Free(GetOffset(pointer)); + } + + // Frees a block of memory, pending the passage of a token. That memory won't + // be re-allocated until the token has passed through the command stream. + // + // Parameters: + // pointer: the pointer to the memory block to free. + // token: the token value to wait for before re-using the memory. + void FreePendingToken(void *pointer, unsigned int token) { + DCHECK(pointer); + allocator_.FreePendingToken(GetOffset(pointer), token); + } + + // Gets a pointer to a memory block given the base memory and the offset. + // It translates FencedAllocator::kInvalidOffset to NULL. + void *GetPointer(FencedAllocator::Offset offset) { + return (offset == FencedAllocator::kInvalidOffset) ? + NULL : static_cast(base_) + offset; + } + + // Gets the offset to a memory block given the base memory and the address. + // It translates NULL to FencedAllocator::kInvalidOffset. + FencedAllocator::Offset GetOffset(void *pointer) { + return pointer ? static_cast(pointer) - static_cast(base_) : + FencedAllocator::kInvalidOffset; + } + + // Gets the size of the largest free block that is available without waiting. + unsigned int GetLargestFreeSize() { + return allocator_.GetLargestFreeSize(); + } + + // Gets the size of the largest free block that can be allocated if the + // caller can wait. + unsigned int GetLargestFreeOrPendingSize() { + return allocator_.GetLargestFreeOrPendingSize(); + } + + // Checks for consistency inside the book-keeping structures. Used for + // testing. + bool CheckConsistency() { + return allocator_.CheckConsistency(); + } + + FencedAllocator &allocator() { return allocator_; } + + private: + FencedAllocator allocator_; + void *base_; + DISALLOW_IMPLICIT_CONSTRUCTORS(FencedAllocatorWrapper); +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_CLIENT_CROSS_FENCED_ALLOCATOR_H_ diff --git a/o3d/command_buffer/client/fenced_allocator_test.cc b/o3d/command_buffer/client/fenced_allocator_test.cc new file mode 100644 index 0000000..aa59be1 --- /dev/null +++ b/o3d/command_buffer/client/fenced_allocator_test.cc @@ -0,0 +1,496 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the tests for the FencedAllocator class. + +#include "tests/common/win/testing_common.h" +#include "base/message_loop.h" +#include "command_buffer/client/cmd_buffer_helper.h" +#include "command_buffer/client/fenced_allocator.h" +#include "command_buffer/service/cmd_buffer_engine.h" +#include "command_buffer/service/mocks.h" +#include "gpu_plugin/command_buffer.h" +#include "gpu_plugin/gpu_processor.h" +#include "gpu_plugin/np_utils/np_object_pointer.h" + +namespace command_buffer { + +using gpu_plugin::CommandBuffer; +using gpu_plugin::GPUProcessor; +using gpu_plugin::NPCreateObject; +using gpu_plugin::NPObjectPointer; +using testing::Return; +using testing::Mock; +using testing::Truly; +using testing::Sequence; +using testing::DoAll; +using testing::Invoke; +using testing::_; + +class BaseFencedAllocatorTest : public testing::Test { + protected: + static const unsigned int kBufferSize = 1024; + + virtual void SetUp() { + api_mock_.reset(new AsyncAPIMock); + // ignore noops in the mock - we don't want to inspect the internals of the + // helper. + EXPECT_CALL(*api_mock_, DoCommand(cmd::kNoop, 0, _)) + .WillRepeatedly(Return(parse_error::kParseNoError)); + // Forward the SetToken calls to the engine + EXPECT_CALL(*api_mock_.get(), DoCommand(cmd::kSetToken, 1, _)) + .WillRepeatedly(DoAll(Invoke(api_mock_.get(), &AsyncAPIMock::SetToken), + Return(parse_error::kParseNoError))); + + ::base::SharedMemory* ring_buffer = new ::base::SharedMemory; + ring_buffer->Create(std::wstring(), false, false, 1024); + ring_buffer->Map(1024); + + command_buffer_ = NPCreateObject(NULL); + command_buffer_->Initialize(ring_buffer); + + parser_ = new command_buffer::CommandParser(ring_buffer->memory(), + kBufferSize, + 0, + kBufferSize, + 0, + api_mock_.get()); + + scoped_refptr gpu_processor(new GPUProcessor( + NULL, command_buffer_.Get(), NULL, NULL, parser_, INT_MAX)); + command_buffer_->SetPutOffsetChangeCallback(NewCallback( + gpu_processor.get(), &GPUProcessor::ProcessCommands)); + + api_mock_->set_engine(gpu_processor.get()); + + helper_.reset(new CommandBufferHelper(NULL, command_buffer_)); + helper_->Initialize(); + } + + virtual void TearDown() { + helper_.release(); + } + + scoped_ptr api_mock_; + NPObjectPointer command_buffer_; + command_buffer::CommandParser* parser_; + scoped_ptr helper_; +}; + +#ifndef COMPILER_MSVC +const unsigned int BaseFencedAllocatorTest::kBufferSize; +#endif + +// Test fixture for FencedAllocator test - Creates a FencedAllocator, using a +// CommandBufferHelper with a mock AsyncAPIInterface for its interface (calling +// it directly, not through the RPC mechanism), making sure Noops are ignored +// and SetToken are properly forwarded to the engine. +class FencedAllocatorTest : public BaseFencedAllocatorTest { + protected: + virtual void SetUp() { + BaseFencedAllocatorTest::SetUp(); + allocator_.reset(new FencedAllocator(kBufferSize, helper_.get())); + } + + virtual void TearDown() { + // If the GPUProcessor posts any tasks, this forces them to run. + MessageLoop::current()->RunAllPending(); + + EXPECT_TRUE(allocator_->CheckConsistency()); + allocator_.release(); + + BaseFencedAllocatorTest::TearDown(); + } + + scoped_ptr allocator_; +}; + +// Checks basic alloc and free. +TEST_F(FencedAllocatorTest, TestBasic) { + allocator_->CheckConsistency(); + + const unsigned int kSize = 16; + FencedAllocator::Offset offset = allocator_->Alloc(kSize); + EXPECT_NE(FencedAllocator::kInvalidOffset, offset); + EXPECT_GE(kBufferSize, offset+kSize); + EXPECT_TRUE(allocator_->CheckConsistency()); + + allocator_->Free(offset); + EXPECT_TRUE(allocator_->CheckConsistency()); +} + +// Checks out-of-memory condition. +TEST_F(FencedAllocatorTest, TestOutOfMemory) { + EXPECT_TRUE(allocator_->CheckConsistency()); + + const unsigned int kSize = 16; + const unsigned int kAllocCount = kBufferSize / kSize; + CHECK(kAllocCount * kSize == kBufferSize); + + // Allocate several buffers to fill in the memory. + FencedAllocator::Offset offsets[kAllocCount]; + for (unsigned int i = 0; i < kAllocCount; ++i) { + offsets[i] = allocator_->Alloc(kSize); + EXPECT_NE(FencedAllocator::kInvalidOffset, offsets[i]); + EXPECT_GE(kBufferSize, offsets[i]+kSize); + EXPECT_TRUE(allocator_->CheckConsistency()); + } + + // This allocation should fail. + FencedAllocator::Offset offset_failed = allocator_->Alloc(kSize); + EXPECT_EQ(FencedAllocator::kInvalidOffset, offset_failed); + EXPECT_TRUE(allocator_->CheckConsistency()); + + // Free one successful allocation, reallocate with half the size + allocator_->Free(offsets[0]); + EXPECT_TRUE(allocator_->CheckConsistency()); + offsets[0] = allocator_->Alloc(kSize/2); + EXPECT_NE(FencedAllocator::kInvalidOffset, offsets[0]); + EXPECT_GE(kBufferSize, offsets[0]+kSize); + EXPECT_TRUE(allocator_->CheckConsistency()); + + // This allocation should fail as well. + offset_failed = allocator_->Alloc(kSize); + EXPECT_EQ(FencedAllocator::kInvalidOffset, offset_failed); + EXPECT_TRUE(allocator_->CheckConsistency()); + + // Free up everything. + for (unsigned int i = 0; i < kAllocCount; ++i) { + allocator_->Free(offsets[i]); + EXPECT_TRUE(allocator_->CheckConsistency()); + } +} + +// Checks the free-pending-token mechanism. +TEST_F(FencedAllocatorTest, TestFreePendingToken) { + EXPECT_TRUE(allocator_->CheckConsistency()); + + const unsigned int kSize = 16; + const unsigned int kAllocCount = kBufferSize / kSize; + CHECK(kAllocCount * kSize == kBufferSize); + + // Allocate several buffers to fill in the memory. + FencedAllocator::Offset offsets[kAllocCount]; + for (unsigned int i = 0; i < kAllocCount; ++i) { + offsets[i] = allocator_->Alloc(kSize); + EXPECT_NE(FencedAllocator::kInvalidOffset, offsets[i]); + EXPECT_GE(kBufferSize, offsets[i]+kSize); + EXPECT_TRUE(allocator_->CheckConsistency()); + } + + // This allocation should fail. + FencedAllocator::Offset offset_failed = allocator_->Alloc(kSize); + EXPECT_EQ(FencedAllocator::kInvalidOffset, offset_failed); + EXPECT_TRUE(allocator_->CheckConsistency()); + + // Free one successful allocation, pending fence. + int32 token = helper_.get()->InsertToken(); + allocator_->FreePendingToken(offsets[0], token); + EXPECT_TRUE(allocator_->CheckConsistency()); + + // The way we hooked up the helper and engine, it won't process commands + // until it has to wait for something. Which means the token shouldn't have + // passed yet at this point. + EXPECT_GT(token, command_buffer_->GetToken()); + + // This allocation will need to reclaim the space freed above, so that should + // process the commands until the token is passed. + offsets[0] = allocator_->Alloc(kSize); + EXPECT_NE(FencedAllocator::kInvalidOffset, offsets[0]); + EXPECT_GE(kBufferSize, offsets[0]+kSize); + EXPECT_TRUE(allocator_->CheckConsistency()); + // Check that the token has indeed passed. + EXPECT_LE(token, command_buffer_->GetToken()); + + // Free up everything. + for (unsigned int i = 0; i < kAllocCount; ++i) { + allocator_->Free(offsets[i]); + EXPECT_TRUE(allocator_->CheckConsistency()); + } +} + +// Tests GetLargestFreeSize +TEST_F(FencedAllocatorTest, TestGetLargestFreeSize) { + EXPECT_TRUE(allocator_->CheckConsistency()); + EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeSize()); + + FencedAllocator::Offset offset = allocator_->Alloc(kBufferSize); + ASSERT_NE(FencedAllocator::kInvalidOffset, offset); + EXPECT_EQ(0u, allocator_->GetLargestFreeSize()); + allocator_->Free(offset); + EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeSize()); + + const unsigned int kSize = 16; + offset = allocator_->Alloc(kSize); + ASSERT_NE(FencedAllocator::kInvalidOffset, offset); + // The following checks that the buffer is allocated "smartly" - which is + // dependent on the implementation. But both first-fit or best-fit would + // ensure that. + EXPECT_EQ(kBufferSize - kSize, allocator_->GetLargestFreeSize()); + + // Allocate 2 more buffers (now 3), and then free the first two. This is to + // ensure a hole. Note that this is dependent on the first-fit current + // implementation. + FencedAllocator::Offset offset1 = allocator_->Alloc(kSize); + ASSERT_NE(FencedAllocator::kInvalidOffset, offset1); + FencedAllocator::Offset offset2 = allocator_->Alloc(kSize); + ASSERT_NE(FencedAllocator::kInvalidOffset, offset2); + allocator_->Free(offset); + allocator_->Free(offset1); + EXPECT_EQ(kBufferSize - 3 * kSize, allocator_->GetLargestFreeSize()); + + offset = allocator_->Alloc(kBufferSize - 3 * kSize); + ASSERT_NE(FencedAllocator::kInvalidOffset, offset); + EXPECT_EQ(2 * kSize, allocator_->GetLargestFreeSize()); + + offset1 = allocator_->Alloc(2 * kSize); + ASSERT_NE(FencedAllocator::kInvalidOffset, offset1); + EXPECT_EQ(0u, allocator_->GetLargestFreeSize()); + + allocator_->Free(offset); + allocator_->Free(offset1); + allocator_->Free(offset2); +} + +// Tests GetLargestFreeOrPendingSize +TEST_F(FencedAllocatorTest, TestGetLargestFreeOrPendingSize) { + EXPECT_TRUE(allocator_->CheckConsistency()); + EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeOrPendingSize()); + + FencedAllocator::Offset offset = allocator_->Alloc(kBufferSize); + ASSERT_NE(FencedAllocator::kInvalidOffset, offset); + EXPECT_EQ(0u, allocator_->GetLargestFreeOrPendingSize()); + allocator_->Free(offset); + EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeOrPendingSize()); + + const unsigned int kSize = 16; + offset = allocator_->Alloc(kSize); + ASSERT_NE(FencedAllocator::kInvalidOffset, offset); + // The following checks that the buffer is allocates "smartly" - which is + // dependent on the implementation. But both first-fit or best-fit would + // ensure that. + EXPECT_EQ(kBufferSize - kSize, allocator_->GetLargestFreeOrPendingSize()); + + // Allocate 2 more buffers (now 3), and then free the first two. This is to + // ensure a hole. Note that this is dependent on the first-fit current + // implementation. + FencedAllocator::Offset offset1 = allocator_->Alloc(kSize); + ASSERT_NE(FencedAllocator::kInvalidOffset, offset1); + FencedAllocator::Offset offset2 = allocator_->Alloc(kSize); + ASSERT_NE(FencedAllocator::kInvalidOffset, offset2); + allocator_->Free(offset); + allocator_->Free(offset1); + EXPECT_EQ(kBufferSize - 3 * kSize, + allocator_->GetLargestFreeOrPendingSize()); + + // Free the last one, pending a token. + int32 token = helper_.get()->InsertToken(); + allocator_->FreePendingToken(offset2, token); + + // Now all the buffers have been freed... + EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeOrPendingSize()); + // .. but one is still waiting for the token. + EXPECT_EQ(kBufferSize - 3 * kSize, + allocator_->GetLargestFreeSize()); + + // The way we hooked up the helper and engine, it won't process commands + // until it has to wait for something. Which means the token shouldn't have + // passed yet at this point. + EXPECT_GT(token, command_buffer_->GetToken()); + // This allocation will need to reclaim the space freed above, so that should + // process the commands until the token is passed, but it will succeed. + offset = allocator_->Alloc(kBufferSize); + ASSERT_NE(FencedAllocator::kInvalidOffset, offset); + // Check that the token has indeed passed. + EXPECT_LE(token, command_buffer_->GetToken()); + allocator_->Free(offset); + + // Everything now has been freed... + EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeOrPendingSize()); + // ... for real. + EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeSize()); +} + +// Test fixture for FencedAllocatorWrapper test - Creates a +// FencedAllocatorWrapper, using a CommandBufferHelper with a mock +// AsyncAPIInterface for its interface (calling it directly, not through the +// RPC mechanism), making sure Noops are ignored and SetToken are properly +// forwarded to the engine. +class FencedAllocatorWrapperTest : public BaseFencedAllocatorTest { + protected: + virtual void SetUp() { + BaseFencedAllocatorTest::SetUp(); + + // Though allocating this buffer isn't strictly necessary, it makes + // allocations point to valid addresses, so they could be used for + // something. + buffer_.reset(new char[kBufferSize]); + allocator_.reset(new FencedAllocatorWrapper(kBufferSize, helper_.get(), + buffer_.get())); + } + + virtual void TearDown() { + // If the GPUProcessor posts any tasks, this forces them to run. + MessageLoop::current()->RunAllPending(); + + EXPECT_TRUE(allocator_->CheckConsistency()); + allocator_.release(); + buffer_.release(); + + BaseFencedAllocatorTest::TearDown(); + } + + scoped_ptr allocator_; + scoped_array buffer_; +}; + +// Checks basic alloc and free. +TEST_F(FencedAllocatorWrapperTest, TestBasic) { + allocator_->CheckConsistency(); + + const unsigned int kSize = 16; + void *pointer = allocator_->Alloc(kSize); + ASSERT_TRUE(pointer); + EXPECT_LE(buffer_.get(), static_cast(pointer)); + EXPECT_GE(kBufferSize, static_cast(pointer) - buffer_.get() + kSize); + EXPECT_TRUE(allocator_->CheckConsistency()); + + allocator_->Free(pointer); + EXPECT_TRUE(allocator_->CheckConsistency()); + + char *pointer_char = allocator_->AllocTyped(kSize); + ASSERT_TRUE(pointer_char); + EXPECT_LE(buffer_.get(), pointer_char); + EXPECT_GE(buffer_.get() + kBufferSize, pointer_char + kSize); + allocator_->Free(pointer_char); + EXPECT_TRUE(allocator_->CheckConsistency()); + + unsigned int *pointer_uint = allocator_->AllocTyped(kSize); + ASSERT_TRUE(pointer_uint); + EXPECT_LE(buffer_.get(), reinterpret_cast(pointer_uint)); + EXPECT_GE(buffer_.get() + kBufferSize, + reinterpret_cast(pointer_uint + kSize)); + + // Check that it did allocate kSize * sizeof(unsigned int). We can't tell + // directly, except from the remaining size. + EXPECT_EQ(kBufferSize - kSize * sizeof(*pointer_uint), + allocator_->GetLargestFreeSize()); + allocator_->Free(pointer_uint); +} + +// Checks out-of-memory condition. +TEST_F(FencedAllocatorWrapperTest, TestOutOfMemory) { + allocator_->CheckConsistency(); + + const unsigned int kSize = 16; + const unsigned int kAllocCount = kBufferSize / kSize; + CHECK(kAllocCount * kSize == kBufferSize); + + // Allocate several buffers to fill in the memory. + void *pointers[kAllocCount]; + for (unsigned int i = 0; i < kAllocCount; ++i) { + pointers[i] = allocator_->Alloc(kSize); + EXPECT_TRUE(pointers[i]); + EXPECT_TRUE(allocator_->CheckConsistency()); + } + + // This allocation should fail. + void *pointer_failed = allocator_->Alloc(kSize); + EXPECT_FALSE(pointer_failed); + EXPECT_TRUE(allocator_->CheckConsistency()); + + // Free one successful allocation, reallocate with half the size + allocator_->Free(pointers[0]); + EXPECT_TRUE(allocator_->CheckConsistency()); + pointers[0] = allocator_->Alloc(kSize/2); + EXPECT_TRUE(pointers[0]); + EXPECT_TRUE(allocator_->CheckConsistency()); + + // This allocation should fail as well. + pointer_failed = allocator_->Alloc(kSize); + EXPECT_FALSE(pointer_failed); + EXPECT_TRUE(allocator_->CheckConsistency()); + + // Free up everything. + for (unsigned int i = 0; i < kAllocCount; ++i) { + allocator_->Free(pointers[i]); + EXPECT_TRUE(allocator_->CheckConsistency()); + } +} + +// Checks the free-pending-token mechanism. +TEST_F(FencedAllocatorWrapperTest, TestFreePendingToken) { + allocator_->CheckConsistency(); + + const unsigned int kSize = 16; + const unsigned int kAllocCount = kBufferSize / kSize; + CHECK(kAllocCount * kSize == kBufferSize); + + // Allocate several buffers to fill in the memory. + void *pointers[kAllocCount]; + for (unsigned int i = 0; i < kAllocCount; ++i) { + pointers[i] = allocator_->Alloc(kSize); + EXPECT_TRUE(pointers[i]); + EXPECT_TRUE(allocator_->CheckConsistency()); + } + + // This allocation should fail. + void *pointer_failed = allocator_->Alloc(kSize); + EXPECT_FALSE(pointer_failed); + EXPECT_TRUE(allocator_->CheckConsistency()); + + // Free one successful allocation, pending fence. + int32 token = helper_.get()->InsertToken(); + allocator_->FreePendingToken(pointers[0], token); + EXPECT_TRUE(allocator_->CheckConsistency()); + + // The way we hooked up the helper and engine, it won't process commands + // until it has to wait for something. Which means the token shouldn't have + // passed yet at this point. + EXPECT_GT(token, command_buffer_->GetToken()); + + // This allocation will need to reclaim the space freed above, so that should + // process the commands until the token is passed. + pointers[0] = allocator_->Alloc(kSize); + EXPECT_TRUE(pointers[0]); + EXPECT_TRUE(allocator_->CheckConsistency()); + // Check that the token has indeed passed. + EXPECT_LE(token, command_buffer_->GetToken()); + + // Free up everything. + for (unsigned int i = 0; i < kAllocCount; ++i) { + allocator_->Free(pointers[i]); + EXPECT_TRUE(allocator_->CheckConsistency()); + } +} + +} // namespace command_buffer diff --git a/o3d/command_buffer/client/id_allocator.cc b/o3d/command_buffer/client/id_allocator.cc new file mode 100644 index 0000000..fc3250d --- /dev/null +++ b/o3d/command_buffer/client/id_allocator.cc @@ -0,0 +1,85 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the implementation of IdAllocator. + +#include "command_buffer/client/id_allocator.h" + +namespace command_buffer { + +IdAllocator::IdAllocator() : bitmap_(1) { bitmap_[0] = 0; } + +static const unsigned int kBitsPerUint32 = sizeof(Uint32) * 8; // NOLINT + +// Looks for the first non-full entry, and return the first free bit in that +// entry. If all the entries are full, it will return the first bit of an entry +// that would be appended, but doesn't actually append that entry to the vector. +unsigned int IdAllocator::FindFirstFree() const { + size_t size = bitmap_.size(); + for (unsigned int i = 0; i < size; ++i) { + Uint32 value = bitmap_[i]; + if (value != 0xffffffffU) { + for (unsigned int j = 0; j < kBitsPerUint32; ++j) { + if (!(value & (1 << j))) return i * kBitsPerUint32 + j; + } + DLOG(FATAL) << "Code should not reach here."; + } + } + return size*kBitsPerUint32; +} + +// Sets the correct bit in the proper entry, resizing the vector if needed. +void IdAllocator::SetBit(unsigned int bit, bool value) { + size_t size = bitmap_.size(); + if (bit >= size * kBitsPerUint32) { + size_t newsize = bit / kBitsPerUint32 + 1; + bitmap_.resize(newsize); + for (size_t i = size; i < newsize; ++i) bitmap_[i] = 0; + } + Uint32 mask = 1U << (bit % kBitsPerUint32); + if (value) { + bitmap_[bit / kBitsPerUint32] |= mask; + } else { + bitmap_[bit / kBitsPerUint32] &= ~mask; + } +} + +// Gets the bit from the proper entry. This doesn't resize the vector, just +// returns false if the bit is beyond the last entry. +bool IdAllocator::GetBit(unsigned int bit) const { + size_t size = bitmap_.size(); + if (bit / kBitsPerUint32 >= size) return false; + Uint32 mask = 1U << (bit % kBitsPerUint32); + return (bitmap_[bit / kBitsPerUint32] & mask) != 0; +} + +} // namespace command_buffer diff --git a/o3d/command_buffer/client/id_allocator.h b/o3d/command_buffer/client/id_allocator.h new file mode 100644 index 0000000..819d13e --- /dev/null +++ b/o3d/command_buffer/client/id_allocator.h @@ -0,0 +1,78 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the definition of the IdAllocator class. + +#ifndef GPU_COMMAND_BUFFER_CLIENT_CROSS_ID_ALLOCATOR_H_ +#define GPU_COMMAND_BUFFER_CLIENT_CROSS_ID_ALLOCATOR_H_ + +#include +#include "base/basictypes.h" +#include "command_buffer/common/types.h" +#include "command_buffer/common/resource.h" + +namespace command_buffer { + +// A class to manage the allocation of resource IDs. It uses a bitfield stored +// into a vector of unsigned ints. +class IdAllocator { + public: + IdAllocator(); + + // Allocates a new resource ID. + command_buffer::ResourceId AllocateID() { + unsigned int bit = FindFirstFree(); + SetBit(bit, true); + return bit; + } + + // Frees a resource ID. + void FreeID(command_buffer::ResourceId id) { + SetBit(id, false); + } + + // Checks whether or not a resource ID is in use. + bool InUse(command_buffer::ResourceId id) { + return GetBit(id); + } + private: + void SetBit(unsigned int bit, bool value); + bool GetBit(unsigned int bit) const; + unsigned int FindFirstFree() const; + + std::vector bitmap_; + DISALLOW_COPY_AND_ASSIGN(IdAllocator); +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_CLIENT_CROSS_ID_ALLOCATOR_H_ diff --git a/o3d/command_buffer/client/id_allocator_test.cc b/o3d/command_buffer/client/id_allocator_test.cc new file mode 100644 index 0000000..b344ab5 --- /dev/null +++ b/o3d/command_buffer/client/id_allocator_test.cc @@ -0,0 +1,112 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file has the unit tests for the IdAllocator class. + +#include "tests/common/win/testing_common.h" +#include "command_buffer/client/id_allocator.h" + +namespace command_buffer { + +using command_buffer::ResourceId; + +class IdAllocatorTest : public testing::Test { + protected: + virtual void SetUp() {} + virtual void TearDown() {} + + IdAllocator* id_allocator() { return &id_allocator_; } + + private: + IdAllocator id_allocator_; +}; + +// Checks basic functionality: AllocateID, FreeID, InUse. +TEST_F(IdAllocatorTest, TestBasic) { + IdAllocator *allocator = id_allocator(); + // Check that resource 0 is not in use + EXPECT_FALSE(allocator->InUse(0)); + + // Allocate an ID, check that it's in use. + ResourceId id1 = allocator->AllocateID(); + EXPECT_TRUE(allocator->InUse(id1)); + + // Allocate another ID, check that it's in use, and different from the first + // one. + ResourceId id2 = allocator->AllocateID(); + EXPECT_TRUE(allocator->InUse(id2)); + EXPECT_NE(id1, id2); + + // Free one of the IDs, check that it's not in use any more. + allocator->FreeID(id1); + EXPECT_FALSE(allocator->InUse(id1)); + + // Frees the other ID, check that it's not in use any more. + allocator->FreeID(id2); + EXPECT_FALSE(allocator->InUse(id2)); +} + +// Checks that the resource IDs are allocated conservatively, and re-used after +// being freed. +TEST_F(IdAllocatorTest, TestAdvanced) { + IdAllocator *allocator = id_allocator(); + + // Allocate a significant number of resources. + const unsigned int kNumResources = 100; + ResourceId ids[kNumResources]; + for (unsigned int i = 0; i < kNumResources; ++i) { + ids[i] = allocator->AllocateID(); + EXPECT_TRUE(allocator->InUse(ids[i])); + } + + // Check that the allocation is conservative with resource IDs, that is that + // the resource IDs don't go over kNumResources - so that the service doesn't + // have to allocate too many internal structures when the resources are used. + for (unsigned int i = 0; i < kNumResources; ++i) { + EXPECT_GT(kNumResources, ids[i]); + } + + // Check that the next resources are still free. + for (unsigned int i = 0; i < kNumResources; ++i) { + EXPECT_FALSE(allocator->InUse(kNumResources + i)); + } + + // Check that a new allocation re-uses the resource we just freed. + ResourceId id1 = ids[kNumResources / 2]; + allocator->FreeID(id1); + EXPECT_FALSE(allocator->InUse(id1)); + ResourceId id2 = allocator->AllocateID(); + EXPECT_TRUE(allocator->InUse(id2)); + EXPECT_EQ(id1, id2); +} + +} // namespace command_buffer diff --git a/o3d/command_buffer/client/o3d_cmd_helper.cc b/o3d/command_buffer/client/o3d_cmd_helper.cc new file mode 100644 index 0000000..cb9ffe1 --- /dev/null +++ b/o3d/command_buffer/client/o3d_cmd_helper.cc @@ -0,0 +1,42 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the implementation of the o3d buffer helper class. + +#include "command_buffer/client/o3d_cmd_helper.h" + +namespace command_buffer { + +// Currently this is a place holder. + +} // namespace command_buffer + diff --git a/o3d/command_buffer/client/o3d_cmd_helper.h b/o3d/command_buffer/client/o3d_cmd_helper.h new file mode 100644 index 0000000..4f4aed2 --- /dev/null +++ b/o3d/command_buffer/client/o3d_cmd_helper.h @@ -0,0 +1,636 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the o3d command buffer helper class. + +#ifndef GPU_COMMAND_BUFFER_CLIENT_CROSS_O3D_CMD_HELPER_H_ +#define GPU_COMMAND_BUFFER_CLIENT_CROSS_O3D_CMD_HELPER_H_ + +#include "command_buffer/common/logging.h" +#include "command_buffer/common/constants.h" +#include "command_buffer/client/cmd_buffer_helper.h" +#include "command_buffer/common/o3d_cmd_format.h" +#include "o3d/gpu_plugin/np_utils/np_object_pointer.h" + +namespace command_buffer { + +// A helper for O3D command buffers. +class O3DCmdHelper : public CommandBufferHelper { + public: + O3DCmdHelper( + NPP npp, + const gpu_plugin::NPObjectPointer& + command_buffer) + : CommandBufferHelper(npp, command_buffer) { + } + virtual ~O3DCmdHelper() { + } + + // ------------------ Individual commands ---------------------- + + void BeginFrame() { + o3d::BeginFrame& cmd = GetCmdSpace(); + cmd.Init(); + } + + + void EndFrame() { + o3d::EndFrame& cmd = GetCmdSpace(); + cmd.Init(); + } + + void Clear( + uint32 buffers, + float red, float green, float blue, float alpha, + float depth, uint32 stencil) { + o3d::Clear& cmd = GetCmdSpace(); + cmd.Init(buffers, red, green, blue, alpha, depth, stencil); + } + + void SetViewport( + uint32 left, + uint32 top, + uint32 width, + uint32 height, + float z_min, + float z_max) { + o3d::SetViewport& cmd = GetCmdSpace(); + cmd.Init(left, top, width, height, z_min, z_max); + } + + void CreateVertexBuffer( + ResourceId vertex_buffer_id, uint32 size, vertex_buffer::Flags flags) { + o3d::CreateVertexBuffer& cmd = GetCmdSpace(); + cmd.Init(vertex_buffer_id, size, flags); + } + + void DestroyVertexBuffer(ResourceId vertex_buffer_id) { + o3d::DestroyVertexBuffer& cmd = GetCmdSpace(); + cmd.Init(vertex_buffer_id); + } + + void SetVertexBufferDataImmediate( + ResourceId vertex_buffer_id, uint32 offset, + const void* data, uint32 size) { + o3d::SetVertexBufferDataImmediate& cmd = + GetImmediateCmdSpace(size); + cmd.Init(vertex_buffer_id, offset, data, size); + } + + void SetVertexBufferData( + ResourceId vertex_buffer_id, uint32 offset, uint32 size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + o3d::SetVertexBufferData& cmd = + GetCmdSpace(); + cmd.Init(vertex_buffer_id, offset, size, + shared_memory_id, shared_memory_offset); + } + + void GetVertexBufferData( + ResourceId vertex_buffer_id, uint32 offset, uint32 size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + o3d::GetVertexBufferData& cmd = + GetCmdSpace(); + cmd.Init(vertex_buffer_id, offset, size, + shared_memory_id, shared_memory_offset); + } + + void CreateIndexBuffer( + ResourceId index_buffer_id, uint32 size, index_buffer::Flags flags) { + o3d::CreateIndexBuffer& cmd = + GetCmdSpace(); + cmd.Init(index_buffer_id, size, flags); + } + + void DestroyIndexBuffer(ResourceId index_buffer_id) { + o3d::DestroyIndexBuffer& cmd = GetCmdSpace(); + cmd.Init(index_buffer_id); + } + + void SetIndexBufferDataImmediate( + ResourceId index_buffer_id, uint32 offset, + const void* data, uint32 size) { + o3d::SetIndexBufferDataImmediate& cmd = + GetImmediateCmdSpace(size); + cmd.Init(index_buffer_id, offset, data, size); + } + + void SetIndexBufferData( + ResourceId index_buffer_id, uint32 offset, uint32 size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + o3d::SetIndexBufferData& cmd = GetCmdSpace(); + cmd.Init(index_buffer_id, offset, size, + shared_memory_id, shared_memory_offset); + } + + void GetIndexBufferData( + ResourceId index_buffer_id, uint32 offset, uint32 size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + o3d::GetIndexBufferData& cmd = GetCmdSpace(); + cmd.Init(index_buffer_id, offset, size, + shared_memory_id, shared_memory_offset); + } + + void CreateVertexStruct(ResourceId vertex_struct_id, uint32 input_count) { + o3d::CreateVertexStruct& cmd = GetCmdSpace(); + cmd.Init(vertex_struct_id, input_count); + } + + void DestroyVertexStruct(ResourceId vertex_struct_id) { + o3d::DestroyVertexStruct& cmd = GetCmdSpace(); + cmd.Init(vertex_struct_id); + } + + void SetVertexInput( + ResourceId vertex_struct_id, + uint32 input_index, + ResourceId vertex_buffer_id, + uint32 offset, + vertex_struct::Semantic semantic, + uint32 semantic_index, + vertex_struct::Type type, + uint32 stride) { + o3d::SetVertexInput& cmd = GetCmdSpace(); + cmd.Init( + vertex_struct_id, + input_index, + vertex_buffer_id, + offset, + semantic, + semantic_index, + type, + stride); + } + + void SetVertexStruct(ResourceId vertex_struct_id) { + o3d::SetVertexStruct& cmd = GetCmdSpace(); + cmd.Init(vertex_struct_id); + } + + void Draw(o3d::PrimitiveType primitive_type, uint32 first, uint32 count) { + o3d::Draw& cmd = GetCmdSpace(); + cmd.Init(primitive_type, first, count); + } + + void DrawIndexed( + o3d::PrimitiveType primitive_type, + ResourceId index_buffer_id, + uint32 first, + uint32 count, + uint32 min_index, + uint32 max_index) { + o3d::DrawIndexed& cmd = GetCmdSpace(); + cmd.Init( + primitive_type, + index_buffer_id, + first, + count, + min_index, + max_index); + } + + void CreateEffect( + ResourceId effect_id, uint32 size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + o3d::CreateEffect& cmd = GetCmdSpace(); + cmd.Init(effect_id, size, shared_memory_id, shared_memory_offset); + } + + void CreateEffectImmediate( + ResourceId effect_id, uint32 size, const void* data) { + o3d::CreateEffectImmediate& cmd = + GetImmediateCmdSpace(size); + cmd.Init(effect_id, size, data); + } + + void DestroyEffect(ResourceId effect_id) { + o3d::DestroyEffect& cmd = GetCmdSpace(); + cmd.Init(effect_id); + } + + void SetEffect(ResourceId effect_id) { + o3d::SetEffect& cmd = GetCmdSpace(); + cmd.Init(effect_id); + } + + void GetParamCount( + ResourceId effect_id, uint32 size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + o3d::GetParamCount& cmd = GetCmdSpace(); + cmd.Init(effect_id, size, shared_memory_id, shared_memory_offset); + } + + void CreateParam(ResourceId param_id, ResourceId effect_id, uint32 index) { + o3d::CreateParam& cmd = GetCmdSpace(); + cmd.Init(param_id, effect_id, index); + } + + void CreateParamByName( + ResourceId param_id, ResourceId effect_id, uint32 size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + o3d::CreateParamByName& cmd = GetCmdSpace(); + cmd.Init(param_id, effect_id, size, shared_memory_id, shared_memory_offset); + } + + void CreateParamByNameImmediate( + ResourceId param_id, ResourceId effect_id, + uint32 size, const void* data) { + o3d::CreateParamByNameImmediate& cmd = + GetImmediateCmdSpace(size); + cmd.Init(param_id, effect_id, size, data); + } + + void DestroyParam(ResourceId param_id) { + o3d::DestroyParam& cmd = GetCmdSpace(); + cmd.Init(param_id); + } + + void SetParamData( + ResourceId param_id, uint32 size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + o3d::SetParamData& cmd = GetCmdSpace(); + cmd.Init(param_id, size, shared_memory_id, shared_memory_offset); + } + + void SetParamDataImmediate( + ResourceId param_id, uint32 size, const void* data) { + o3d::SetParamDataImmediate& cmd = + GetImmediateCmdSpace(size); + cmd.Init(param_id, size, data); + } + + void GetParamDesc( + ResourceId param_id, uint32 size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + o3d::GetParamDesc& cmd = GetCmdSpace(); + cmd.Init(param_id, size, shared_memory_id, shared_memory_offset); + } + + void GetStreamCount( + ResourceId effect_id, uint32 size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + o3d::GetStreamCount& cmd = GetCmdSpace(); + cmd.Init(effect_id, size, shared_memory_id, shared_memory_offset); + } + + void GetStreamDesc( + ResourceId effect_id, uint32 index, uint32 size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + o3d::GetStreamDesc& cmd = GetCmdSpace(); + cmd.Init(effect_id, index, size, shared_memory_id, shared_memory_offset); + } + + void DestroyTexture(ResourceId texture_id) { + o3d::DestroyTexture& cmd = GetCmdSpace(); + cmd.Init(texture_id); + } + + void CreateTexture2d( + ResourceId texture_id, + uint32 width, uint32 height, + uint32 levels, texture::Format format, + bool enable_render_surfaces) { + o3d::CreateTexture2d& cmd = GetCmdSpace(); + cmd.Init(texture_id, + width, height, levels, format, + enable_render_surfaces); + } + + void CreateTexture3d( + ResourceId texture_id, + uint32 width, uint32 height, uint32 depth, + uint32 levels, texture::Format format, + bool enable_render_surfaces) { + o3d::CreateTexture3d& cmd = GetCmdSpace(); + cmd.Init(texture_id, + width, height, depth, + levels, format, + enable_render_surfaces); + } + + void CreateTextureCube( + ResourceId texture_id, + uint32 edge_length, uint32 levels, texture::Format format, + bool enable_render_surfaces) { + o3d::CreateTextureCube& cmd = GetCmdSpace(); + cmd.Init(texture_id, + edge_length, levels, format, + enable_render_surfaces); + } + + void SetTextureData( + ResourceId texture_id, + uint32 x, + uint32 y, + uint32 z, + uint32 width, + uint32 height, + uint32 depth, + uint32 level, + texture::Face face, + uint32 row_pitch, + uint32 slice_pitch, + uint32 size, + uint32 shared_memory_id, + uint32 shared_memory_offset) { + o3d::SetTextureData& cmd = GetCmdSpace(); + cmd.Init( + texture_id, + x, + y, + z, + width, + height, + depth, + level, + face, + row_pitch, + slice_pitch, + size, + shared_memory_id, + shared_memory_offset); + } + + void SetTextureDataImmediate( + ResourceId texture_id, + uint32 x, + uint32 y, + uint32 z, + uint32 width, + uint32 height, + uint32 depth, + uint32 level, + texture::Face face, + uint32 row_pitch, + uint32 slice_pitch, + uint32 size, + const void* data) { + o3d::SetTextureDataImmediate& cmd = + GetImmediateCmdSpace(size); + cmd.Init( + texture_id, + x, + y, + z, + width, + height, + depth, + level, + face, + row_pitch, + slice_pitch, + size, + data); + } + + void GetTextureData( + ResourceId texture_id, + uint32 x, + uint32 y, + uint32 z, + uint32 width, + uint32 height, + uint32 depth, + uint32 level, + texture::Face face, + uint32 row_pitch, + uint32 slice_pitch, + uint32 size, + uint32 shared_memory_id, + uint32 shared_memory_offset) { + o3d::GetTextureData& cmd = GetCmdSpace(); + cmd.Init( + texture_id, + x, + y, + z, + width, + height, + depth, + level, + face, + row_pitch, + slice_pitch, + size, + shared_memory_id, + shared_memory_offset); + } + + void CreateSampler(ResourceId sampler_id) { + o3d::CreateSampler& cmd = GetCmdSpace(); + cmd.Init(sampler_id); + } + + void DestroySampler(ResourceId sampler_id) { + o3d::DestroySampler& cmd = GetCmdSpace(); + cmd.Init(sampler_id); + } + + void SetSamplerStates( + ResourceId sampler_id, + sampler::AddressingMode address_u_value, + sampler::AddressingMode address_v_value, + sampler::AddressingMode address_w_value, + sampler::FilteringMode mag_filter_value, + sampler::FilteringMode min_filter_value, + sampler::FilteringMode mip_filter_value, + uint8 max_anisotropy) { + o3d::SetSamplerStates& cmd = GetCmdSpace(); + cmd.Init( + sampler_id, + address_u_value, + address_v_value, + address_w_value, + mag_filter_value, + min_filter_value, + mip_filter_value, + max_anisotropy); + } + + void SetSamplerBorderColor( + ResourceId sampler_id, + float red, float green, float blue, float alpha) { + o3d::SetSamplerBorderColor& cmd = + GetCmdSpace(); + cmd.Init(sampler_id, red, green, blue, alpha); + } + + void SetSamplerTexture(ResourceId sampler_id, ResourceId texture_id) { + o3d::SetSamplerTexture& cmd = GetCmdSpace(); + cmd.Init(sampler_id, texture_id); + } + + void SetScissor( + uint32 x, + uint32 y, + uint32 width, + uint32 height, + bool enable) { + o3d::SetScissor& cmd = GetCmdSpace(); + cmd.Init( + x, + y, + width, + height, + enable); + } + + void SetPolygonOffset(float slope_factor, float units) { + o3d::SetPolygonOffset& cmd = GetCmdSpace(); + cmd.Init(slope_factor, units); + } + + void SetPointLineRaster( + bool line_smooth_enable, bool point_sprite_enable, float point_size) { + o3d::SetPointLineRaster& cmd = GetCmdSpace(); + cmd.Init(line_smooth_enable, point_sprite_enable, point_size); + } + + void SetPolygonRaster(o3d::PolygonMode fill_mode, + o3d::FaceCullMode cull_mode) { + o3d::SetPolygonRaster& cmd = GetCmdSpace(); + cmd.Init(fill_mode, cull_mode); + } + + void SetAlphaTest(o3d::Comparison func, bool enable, float value) { + o3d::SetAlphaTest& cmd = GetCmdSpace(); + cmd.Init(func, enable, value); + } + + void SetDepthTest(o3d::Comparison func, bool write_enable, bool enable) { + o3d::SetDepthTest& cmd = GetCmdSpace(); + cmd.Init(func, write_enable, enable); + } + + void SetStencilTest( + uint8 write_mask, + uint8 compare_mask, + uint8 reference_value, + bool separate_ccw, + bool enable, + o3d::Comparison cw_func, + o3d::StencilOp cw_pass_op, + o3d::StencilOp cw_fail_op, + o3d::StencilOp cw_z_fail_op, + o3d::Comparison ccw_func, + o3d::StencilOp ccw_pass_op, + o3d::StencilOp ccw_fail_op, + o3d::StencilOp ccw_z_fail_op) { + o3d::SetStencilTest& cmd = GetCmdSpace(); + cmd.Init( + write_mask, + compare_mask, + reference_value, + separate_ccw, + enable, + cw_func, + cw_pass_op, + cw_fail_op, + cw_z_fail_op, + ccw_func, + ccw_pass_op, + ccw_fail_op, + ccw_z_fail_op); + } + + void SetColorWrite(uint8 mask, bool dither_enable) { + o3d::SetColorWrite& cmd = GetCmdSpace(); + cmd.Init(mask, dither_enable); + } + + void SetBlending( + o3d::BlendFunc color_src_func, + o3d::BlendFunc color_dst_func, + o3d::BlendEq color_eq, + o3d::BlendFunc alpha_src_func, + o3d::BlendFunc alpha_dst_func, + o3d::BlendEq alpha_eq, + bool separate_alpha, + bool enable) { + o3d::SetBlending& cmd = GetCmdSpace(); + cmd.Init( + color_src_func, + color_dst_func, + color_eq, + alpha_src_func, + alpha_dst_func, + alpha_eq, + separate_alpha, + enable); + } + + void SetBlendingColor(float red, float green, float blue, float alpha) { + o3d::SetBlendingColor& cmd = GetCmdSpace(); + cmd.Init(red, green, blue, alpha); + } + + void CreateRenderSurface( + ResourceId render_surface_id, ResourceId texture_id, + uint32 width, uint32 height, + uint32 level, uint32 side) { + o3d::CreateRenderSurface& cmd = GetCmdSpace(); + cmd.Init(render_surface_id, texture_id, width, height, level, side); + } + + void DestroyRenderSurface(ResourceId render_surface_id) { + o3d::DestroyRenderSurface& cmd = + GetCmdSpace(); + cmd.Init(render_surface_id); + } + + void CreateDepthSurface( + ResourceId depth_surface_id, uint32 width, uint32 height) { + o3d::CreateDepthSurface& cmd = GetCmdSpace(); + cmd.Init(depth_surface_id, width, height); + } + + void DestroyDepthSurface(ResourceId depth_surface_id) { + o3d::DestroyDepthSurface& cmd = GetCmdSpace(); + cmd.Init(depth_surface_id); + } + + void SetRenderSurface( + ResourceId render_surface_id, ResourceId depth_surface_id) { + o3d::SetRenderSurface& cmd = GetCmdSpace(); + cmd.Init(render_surface_id, depth_surface_id); + } + + void SetBackSurfaces() { + o3d::SetBackSurfaces& cmd = GetCmdSpace(); + cmd.Init(); + } +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_CLIENT_CROSS_O3D_CMD_HELPER_H_ + diff --git a/o3d/command_buffer/command_buffer.gyp b/o3d/command_buffer/command_buffer.gyp new file mode 100644 index 0000000..71865ba --- /dev/null +++ b/o3d/command_buffer/command_buffer.gyp @@ -0,0 +1,243 @@ +# Copyright (c) 2009 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. + +{ + 'variables': { + 'chromium_code': 1, + }, + 'includes': [ + '../build/common.gypi', + ], + 'target_defaults': { + 'include_dirs': [ + '..', + '../..', + '../../<(gtestdir)', + '../../<(nacldir)', + ], + # TODO(rlp): remove this after fixing signed / unsigned issues in + # command buffer code and tests. + 'target_conditions': [ + ['OS == "mac"', + { + 'xcode_settings': { + 'GCC_TREAT_WARNINGS_AS_ERRORS': 'NO' + }, + }, + ], + ], + }, + 'targets': [ + { + 'target_name': 'command_buffer_common', + 'type': 'static_library', + 'all_dependent_settings': { + 'include_dirs': [ + '..', + ], + }, # 'all_dependent_settings' + 'sources': [ + 'common/bitfield_helpers.h', + 'common/cmd_buffer_common.h', + 'common/cmd_buffer_common.cc', + 'common/o3d_cmd_format.h', + 'common/o3d_cmd_format.cc', + 'common/gapi_interface.h', + 'common/logging.h', + 'common/mocks.h', + 'common/resource.cc', + 'common/resource.h', + 'common/types.h', + ], + }, + { + 'target_name': 'command_buffer_common_test', + 'type': 'none', + 'direct_dependent_settings': { + 'sources': [ + 'common/bitfield_helpers_test.cc', + ], + }, + }, + { + 'target_name': 'command_buffer_client', + 'type': 'static_library', + 'dependencies': [ + 'command_buffer_common', + '../gpu_plugin/gpu_plugin.gyp:np_utils', + ], + 'sources': [ + 'client/cmd_buffer_helper.cc', + 'client/cmd_buffer_helper.h', + 'client/effect_helper.cc', + 'client/effect_helper.h', + 'client/fenced_allocator.cc', + 'client/fenced_allocator.h', + 'client/id_allocator.cc', + 'client/id_allocator.h', + 'client/o3d_cmd_helper.cc', + 'client/o3d_cmd_helper.h', + ], + }, + { + 'target_name': 'command_buffer_client_test', + 'type': 'none', + 'direct_dependent_settings': { + 'sources': [ + 'client/cmd_buffer_helper_test.cc', + 'client/fenced_allocator_test.cc', + 'client/id_allocator_test.cc', + ], + }, + }, + { + 'target_name': 'command_buffer_service', + 'type': 'static_library', + 'all_dependent_settings': { + 'include_dirs': [ + '..', + ], + 'conditions': [ + ['OS == "win" and (renderer == "gl" or cb_service == "gl")', + { + 'include_dirs': [ + '../../<(glewdir)/include', + '../../<(cgdir)/include', + ], + }, + ], + ], + }, # 'all_dependent_settings' + 'dependencies': [ + 'command_buffer_common', + ], + 'sources': [ + 'service/common_decoder.cc', + 'service/common_decoder.h', + 'service/cmd_buffer_engine.h', + 'service/cmd_parser.cc', + 'service/cmd_parser.h', + 'service/effect_utils.cc', + 'service/effect_utils.h', + 'service/gapi_decoder.cc', + 'service/gapi_decoder.h', + 'service/mocks.h', + 'service/precompile.cc', + 'service/precompile.h', + 'service/resource.cc', + 'service/resource.h', + 'service/texture_utils.cc', + 'service/texture_utils.h', + ], + 'conditions': [ + ['OS == "win"', + { + 'msvs_settings': { + 'VCCLCompilerTool': { + 'ForcedIncludeFiles': + 'command_buffer/service/precompile.h', + }, + }, + }, + ], + ['OS == "mac"', + { + 'xcode_settings': { + 'GCC_PREFIX_HEADER': 'service/precompile.h', + }, + }, + ], + ['OS == "linux"', + { + 'cflags': [ + '-include', + 'command_buffer/service/precompile.h', + ], + }, + ], + ['cb_service == "d3d9"', + { + 'include_dirs': [ + '$(DXSDK_DIR)/Include', + ], + 'all_dependent_settings': { + 'include_dirs': [ + '$(DXSDK_DIR)/Include', + ], + 'link_settings': { + 'libraries': [ + '"$(DXSDK_DIR)/Lib/x86/DxErr.lib"', + ], + }, + }, # 'all_dependent_settings' + 'sources': [ + 'service/d3d9_utils.h', + 'service/effect_d3d9.cc', + 'service/effect_d3d9.h', + 'service/gapi_d3d9.cc', + 'service/gapi_d3d9.h', + 'service/geometry_d3d9.cc', + 'service/geometry_d3d9.h', + 'service/render_surface_d3d9.cc', + 'service/render_surface_d3d9.h', + 'service/sampler_d3d9.cc', + 'service/sampler_d3d9.h', + 'service/states_d3d9.cc', + 'service/texture_d3d9.cc', + 'service/texture_d3d9.h', + ], # 'sources' + }, + ], + ['cb_service == "gl"', + { + 'dependencies': [ + '../build/libs.gyp:gl_libs', + '../build/libs.gyp:cg_libs', + ], + 'sources': [ + 'service/effect_gl.cc', + 'service/effect_gl.h', + 'service/gapi_gl.cc', + 'service/gapi_gl.h', + 'service/geometry_gl.cc', + 'service/geometry_gl.h', + 'service/gl_utils.h', + 'service/render_surface_gl.cc', + 'service/render_surface_gl.h', + 'service/sampler_gl.cc', + 'service/sampler_gl.h', + 'service/states_gl.cc', + 'service/texture_gl.cc', + 'service/texture_gl.h', + ], # 'sources' + }, + ], + ['OS == "linux"', + { + 'sources': [ + 'service/linux/x_utils.cc', + 'service/linux/x_utils.h', + ], + }, + ], + ], # 'conditions' + }, + { + 'target_name': 'command_buffer_service_test', + 'type': 'none', + 'direct_dependent_settings': { + 'sources': [ + 'service/cmd_parser_test.cc', + 'service/resource_test.cc', + ], + }, + }, + ], # 'targets' +} + +# Local Variables: +# tab-width:2 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=2 shiftwidth=2: diff --git a/o3d/command_buffer/common/GLES2/gl2.h b/o3d/command_buffer/common/GLES2/gl2.h new file mode 100644 index 0000000..94c643b --- /dev/null +++ b/o3d/command_buffer/common/GLES2/gl2.h @@ -0,0 +1,621 @@ +#ifndef __gl2_h_ +#define __gl2_h_ + +/* $Revision: 8784 $ on $Date:: 2009-09-02 09:49:17 -0700 #$ */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This document is licensed under the SGI Free Software B License Version + * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + */ + +/*------------------------------------------------------------------------- + * Data type definitions + *-----------------------------------------------------------------------*/ + +typedef void GLvoid; +typedef unsigned int GLenum; +typedef unsigned char GLboolean; +typedef unsigned int GLbitfield; +typedef khronos_int8_t GLbyte; +typedef short GLshort; +typedef int GLint; +typedef int GLsizei; +typedef khronos_uint8_t GLubyte; +typedef unsigned short GLushort; +typedef unsigned int GLuint; +typedef khronos_float_t GLfloat; +typedef khronos_float_t GLclampf; +typedef khronos_int32_t GLfixed; + +/* GL types for handling large vertex buffer objects */ +typedef khronos_intptr_t GLintptr; +typedef khronos_ssize_t GLsizeiptr; + +/* OpenGL ES core versions */ +#define GL_ES_VERSION_2_0 1 + +/* ClearBufferMask */ +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_COLOR_BUFFER_BIT 0x00004000 + +/* Boolean */ +#define GL_FALSE 0 +#define GL_TRUE 1 + +/* BeginMode */ +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 + +/* AlphaFunction (not supported in ES20) */ +/* GL_NEVER */ +/* GL_LESS */ +/* GL_EQUAL */ +/* GL_LEQUAL */ +/* GL_GREATER */ +/* GL_NOTEQUAL */ +/* GL_GEQUAL */ +/* GL_ALWAYS */ + +/* BlendingFactorDest */ +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 + +/* BlendingFactorSrc */ +/* GL_ZERO */ +/* GL_ONE */ +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +/* GL_SRC_ALPHA */ +/* GL_ONE_MINUS_SRC_ALPHA */ +/* GL_DST_ALPHA */ +/* GL_ONE_MINUS_DST_ALPHA */ + +/* BlendEquationSeparate */ +#define GL_FUNC_ADD 0x8006 +#define GL_BLEND_EQUATION 0x8009 +#define GL_BLEND_EQUATION_RGB 0x8009 /* same as BLEND_EQUATION */ +#define GL_BLEND_EQUATION_ALPHA 0x883D + +/* BlendSubtract */ +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B + +/* Separate Blend Functions */ +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 + +/* Buffer Objects */ +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 + +#define GL_STREAM_DRAW 0x88E0 +#define GL_STATIC_DRAW 0x88E4 +#define GL_DYNAMIC_DRAW 0x88E8 + +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 + +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 + +/* CullFaceMode */ +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_FRONT_AND_BACK 0x0408 + +/* DepthFunction */ +/* GL_NEVER */ +/* GL_LESS */ +/* GL_EQUAL */ +/* GL_LEQUAL */ +/* GL_GREATER */ +/* GL_NOTEQUAL */ +/* GL_GEQUAL */ +/* GL_ALWAYS */ + +/* EnableCap */ +#define GL_TEXTURE_2D 0x0DE1 +#define GL_CULL_FACE 0x0B44 +#define GL_BLEND 0x0BE2 +#define GL_DITHER 0x0BD0 +#define GL_STENCIL_TEST 0x0B90 +#define GL_DEPTH_TEST 0x0B71 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_COVERAGE 0x80A0 + +/* ErrorCode */ +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_OUT_OF_MEMORY 0x0505 + +/* FrontFaceDirection */ +#define GL_CW 0x0900 +#define GL_CCW 0x0901 + +/* GetPName */ +#define GL_LINE_WIDTH 0x0B21 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_VIEWPORT 0x0BA2 +#define GL_SCISSOR_BOX 0x0C10 +/* GL_SCISSOR_TEST */ +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +/* GL_POLYGON_OFFSET_FILL */ +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB + +/* GetTextureParameter */ +/* GL_TEXTURE_MAG_FILTER */ +/* GL_TEXTURE_MIN_FILTER */ +/* GL_TEXTURE_WRAP_S */ +/* GL_TEXTURE_WRAP_T */ + +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 + +/* HintMode */ +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 + +/* HintTarget */ +#define GL_GENERATE_MIPMAP_HINT 0x8192 + +/* DataType */ +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_FIXED 0x140C + +/* PixelFormat */ +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A + +/* PixelType */ +/* GL_UNSIGNED_BYTE */ +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 + +/* Shaders */ +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_SHADER_TYPE 0x8B4F +#define GL_DELETE_STATUS 0x8B80 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D + +/* StencilFunction */ +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 + +/* StencilOp */ +/* GL_ZERO */ +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_INVERT 0x150A +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 + +/* StringName */ +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 + +/* TextureMagFilter */ +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 + +/* TextureMinFilter */ +/* GL_NEAREST */ +/* GL_LINEAR */ +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 + +/* TextureParameterName */ +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 + +/* TextureTarget */ +/* GL_TEXTURE_2D */ +#define GL_TEXTURE 0x1702 + +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C + +/* TextureUnit */ +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 + +/* TextureWrapMode */ +#define GL_REPEAT 0x2901 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_MIRRORED_REPEAT 0x8370 + +/* Uniform Types */ +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_CUBE 0x8B60 + +/* Vertex Arrays */ +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F + +/* Read Format */ +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B + +/* Shader Source */ +#define GL_COMPILE_STATUS 0x8B81 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_COMPILER 0x8DFA + +/* Shader Binary */ +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 + +/* Shader Precision-Specified Types */ +#define GL_LOW_FLOAT 0x8DF0 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_LOW_INT 0x8DF3 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_HIGH_INT 0x8DF5 + +/* Framebuffer Object. */ +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 + +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGB565 0x8D62 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_STENCIL_INDEX 0x1901 +#define GL_STENCIL_INDEX8 0x8D48 + +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 + +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 + +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 + +#define GL_NONE 0 + +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD + +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 + +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 + +/*------------------------------------------------------------------------- + * GL core functions. + *-----------------------------------------------------------------------*/ + +GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture); +GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const char* name); +GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer); +GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); +GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture); +GL_APICALL void GL_APIENTRY glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +GL_APICALL void GL_APIENTRY glBlendEquation ( GLenum mode ); +GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); +GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); +GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void* data, GLenum usage); +GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void* data); +GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target); +GL_APICALL void GL_APIENTRY glClear (GLbitfield mask); +GL_APICALL void GL_APIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +GL_APICALL void GL_APIENTRY glClearDepthf (GLclampf depth); +GL_APICALL void GL_APIENTRY glClearStencil (GLint s); +GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader); +GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data); +GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL GLuint GL_APIENTRY glCreateProgram (void); +GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type); +GL_APICALL void GL_APIENTRY glCullFace (GLenum mode); +GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint* buffers); +GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint* framebuffers); +GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program); +GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint* renderbuffers); +GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader); +GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint* textures); +GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func); +GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag); +GL_APICALL void GL_APIENTRY glDepthRangef (GLclampf zNear, GLclampf zFar); +GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glDisable (GLenum cap); +GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); +GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void* indices); +GL_APICALL void GL_APIENTRY glEnable (GLenum cap); +GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glFinish (void); +GL_APICALL void GL_APIENTRY glFlush (void); +GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode); +GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint* buffers); +GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target); +GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers); +GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers); +GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint* textures); +GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name); +GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name); +GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders); +GL_APICALL int GL_APIENTRY glGetAttribLocation (GLuint program, const char* name); +GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params); +GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL GLenum GL_APIENTRY glGetError (void); +GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufsize, GLsizei* length, char* infolog); +GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog); +GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision); +GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufsize, GLsizei* length, char* source); +GL_APICALL const GLubyte* GL_APIENTRY glGetString (GLenum name); +GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint* params); +GL_APICALL int GL_APIENTRY glGetUniformLocation (GLuint program, const char* name); +GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void** pointer); +GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode); +GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer); +GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap); +GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer); +GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program); +GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer); +GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader); +GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture); +GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width); +GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program); +GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); +GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels); +GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); +GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glSampleCoverage (GLclampf value, GLboolean invert); +GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length); +GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const char** string, const GLint* length); +GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels); +GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat* params); +GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint* params); +GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); +GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat x); +GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint x); +GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint x, GLint y); +GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint x, GLint y, GLint z); +GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint x, GLint y, GLint z, GLint w); +GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUseProgram (GLuint program); +GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program); +GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint indx, GLfloat x); +GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint indx, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint indx, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr); +GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); + +#ifdef __cplusplus +} +#endif + +#endif /* __gl2_h_ */ + diff --git a/o3d/command_buffer/common/GLES2/gl2platform.h b/o3d/command_buffer/common/GLES2/gl2platform.h new file mode 100644 index 0000000..3e9036c --- /dev/null +++ b/o3d/command_buffer/common/GLES2/gl2platform.h @@ -0,0 +1,29 @@ +#ifndef __gl2platform_h_ +#define __gl2platform_h_ + +/* $Revision: 7173 $ on $Date:: 2009-01-09 11:18:21 -0800 #$ */ + +/* + * This document is licensed under the SGI Free Software B License Version + * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + */ + +/* Platform-specific types and definitions for OpenGL ES 2.X gl2.h + * Last modified on 2008/12/19 + * + * Adopters may modify khrplatform.h and this file to suit their platform. + * You are encouraged to submit all modifications to the Khronos group so that + * they can be included in future versions of this file. Please submit changes + * by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla) + * by filing a bug against product "OpenGL-ES" component "Registry". + */ + +#include + +#ifndef GL_APICALL +#define GL_APICALL KHRONOS_APICALL +#endif + +#define GL_APIENTRY KHRONOS_APIENTRY + +#endif /* __gl2platform_h_ */ diff --git a/o3d/command_buffer/common/KHR/khrplatform.h b/o3d/command_buffer/common/KHR/khrplatform.h new file mode 100644 index 0000000..8341f71b --- /dev/null +++ b/o3d/command_buffer/common/KHR/khrplatform.h @@ -0,0 +1,269 @@ +#ifndef __khrplatform_h_ +#define __khrplatform_h_ + +/* +** Copyright (c) 2008-2009 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/* Khronos platform-specific types and definitions. + * + * $Revision: 7820 $ on $Date: 2009-04-03 13:46:26 -0700 (Fri, 03 Apr 2009) $ + * + * Adopters may modify this file to suit their platform. Adopters are + * encouraged to submit platform specific modifications to the Khronos + * group so that they can be included in future versions of this file. + * Please submit changes by sending them to the public Khronos Bugzilla + * (http://khronos.org/bugzilla) by filing a bug against product + * "Khronos (general)" component "Registry". + * + * A predefined template which fills in some of the bug fields can be + * reached using http://tinyurl.com/khrplatform-h-bugreport, but you + * must create a Bugzilla login first. + * + * + * See the Implementer's Guidelines for information about where this file + * should be located on your system and for more details of its use: + * http://www.khronos.org/registry/implementers_guide.pdf + * + * This file should be included as + * #include + * by Khronos client API header files that use its types and defines. + * + * The types in khrplatform.h should only be used to define API-specific types. + * + * Types defined in khrplatform.h: + * khronos_int8_t signed 8 bit + * khronos_uint8_t unsigned 8 bit + * khronos_int16_t signed 16 bit + * khronos_uint16_t unsigned 16 bit + * khronos_int32_t signed 32 bit + * khronos_uint32_t unsigned 32 bit + * khronos_int64_t signed 64 bit + * khronos_uint64_t unsigned 64 bit + * khronos_intptr_t signed same number of bits as a pointer + * khronos_uintptr_t unsigned same number of bits as a pointer + * khronos_ssize_t signed size + * khronos_usize_t unsigned size + * khronos_float_t signed 32 bit floating point + * khronos_time_ns_t unsigned 64 bit time in nanoseconds + * khronos_utime_nanoseconds_t unsigned time interval or absolute time in + * nanoseconds + * khronos_stime_nanoseconds_t signed time interval in nanoseconds + * khronos_boolean_enum_t enumerated boolean type. This should + * only be used as a base type when a client API's boolean type is + * an enum. Client APIs which use an integer or other type for + * booleans cannot use this as the base type for their boolean. + * + * Tokens defined in khrplatform.h: + * + * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. + * + * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. + * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. + * + * Calling convention macros defined in this file: + * KHRONOS_APICALL + * KHRONOS_APIENTRY + * KHRONOS_APIATTRIBUTES + * + * These may be used in function prototypes as: + * + * KHRONOS_APICALL void KHRONOS_APIENTRY funcname( + * int arg1, + * int arg2) KHRONOS_APIATTRIBUTES; + */ + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APICALL + *------------------------------------------------------------------------- + * This precedes the return type of the function in the function prototype. + */ +#if defined(_WIN32) && !defined(__SCITECH_SNAP__) +# define KHRONOS_APICALL __declspec(dllimport) +#elif defined (__SYMBIAN32__) +# define KHRONOS_APICALL IMPORT_C +#else +# define KHRONOS_APICALL +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIENTRY + *------------------------------------------------------------------------- + * This follows the return type of the function and precedes the function + * name in the function prototype. + */ +#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) + /* Win32 but not WinCE */ +# define KHRONOS_APIENTRY __stdcall +#else +# define KHRONOS_APIENTRY +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIATTRIBUTES + *------------------------------------------------------------------------- + * This follows the closing parenthesis of the function prototype arguments. + */ +#if defined (__ARMCC_2__) +#define KHRONOS_APIATTRIBUTES __softfp +#else +#define KHRONOS_APIATTRIBUTES +#endif + +/*------------------------------------------------------------------------- + * basic type definitions + *-----------------------------------------------------------------------*/ +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) + + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__VMS ) || defined(__sgi) + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(_WIN32) && !defined(__SCITECH_SNAP__) + +/* + * Win32 + */ +typedef __int32 khronos_int32_t; +typedef unsigned __int32 khronos_uint32_t; +typedef __int64 khronos_int64_t; +typedef unsigned __int64 khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__sun__) || defined(__digital__) + +/* + * Sun or Digital + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#if defined(__arch64__) || defined(_LP64) +typedef long int khronos_int64_t; +typedef unsigned long int khronos_uint64_t; +#else +typedef long long int khronos_int64_t; +typedef unsigned long long int khronos_uint64_t; +#endif /* __arch64__ */ +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif 0 + +/* + * Hypothetical platform with no float or int64 support + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#define KHRONOS_SUPPORT_INT64 0 +#define KHRONOS_SUPPORT_FLOAT 0 + +#else + +/* + * Generic fallback + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#endif + + +/* + * Types that are (so far) the same on all platforms + */ +typedef signed char khronos_int8_t; +typedef unsigned char khronos_uint8_t; +typedef signed short int khronos_int16_t; +typedef unsigned short int khronos_uint16_t; +typedef signed long int khronos_intptr_t; +typedef unsigned long int khronos_uintptr_t; +typedef signed long int khronos_ssize_t; +typedef unsigned long int khronos_usize_t; + +#if KHRONOS_SUPPORT_FLOAT +/* + * Float type + */ +typedef float khronos_float_t; +#endif + +#if KHRONOS_SUPPORT_INT64 +/* Time types + * + * These types can be used to represent a time interval in nanoseconds or + * an absolute Unadjusted System Time. Unadjusted System Time is the number + * of nanoseconds since some arbitrary system event (e.g. since the last + * time the system booted). The Unadjusted System Time is an unsigned + * 64 bit value that wraps back to 0 every 584 years. Time intervals + * may be either signed or unsigned. + */ +typedef khronos_uint64_t khronos_utime_nanoseconds_t; +typedef khronos_int64_t khronos_stime_nanoseconds_t; +#endif + +/* + * Dummy value used to pad enum types to 32 bits. + */ +#ifndef KHRONOS_MAX_ENUM +#define KHRONOS_MAX_ENUM 0x7FFFFFFF +#endif + +/* + * Enumerated boolean type + * + * Values other than zero should be considered to be true. Therefore + * comparisons should not be made against KHRONOS_TRUE. + */ +typedef enum { + KHRONOS_FALSE = 0, + KHRONOS_TRUE = 1, + KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM +} khronos_boolean_enum_t; + +#endif /* __khrplatform_h_ */ diff --git a/o3d/command_buffer/common/bitfield_helpers.h b/o3d/command_buffer/common/bitfield_helpers.h new file mode 100644 index 0000000..b74374d --- /dev/null +++ b/o3d/command_buffer/common/bitfield_helpers.h @@ -0,0 +1,68 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains a helper template class used to access bit fields in +// unsigned int_ts. + +#ifndef GPU_COMMAND_BUFFER_COMMON_CROSS_BITFIELD_HELPERS_H_ +#define GPU_COMMAND_BUFFER_COMMON_CROSS_BITFIELD_HELPERS_H_ + +namespace command_buffer { + +// Bitfield template class, used to access bit fields in unsigned int_ts. +template class BitField { + public: + static const unsigned int kShift = shift; + static const unsigned int kLength = length; + // the following is really (1<> kShift) & kMask; + } + + // Makes a value that can be or-ed into this field. + static unsigned int MakeValue(unsigned int value) { + return (value & kMask) << kShift; + } + + // Changes the value of this field. + static void Set(unsigned int *container, unsigned int field_value) { + *container = (*container & ~(kMask << kShift)) | MakeValue(field_value); + } +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_COMMON_CROSS_BITFIELD_HELPERS_H_ diff --git a/o3d/command_buffer/common/bitfield_helpers_test.cc b/o3d/command_buffer/common/bitfield_helpers_test.cc new file mode 100644 index 0000000..310ccf0 --- /dev/null +++ b/o3d/command_buffer/common/bitfield_helpers_test.cc @@ -0,0 +1,66 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// Tests for the bitfield helper class. + +#include "gtest/gtest.h" +#include "command_buffer/common/bitfield_helpers.h" + +namespace command_buffer { + +// Tests that BitField<>::Get returns the right bits. +TEST(BitFieldTest, TestGet) { + unsigned int value = 0x12345678u; + EXPECT_EQ(0x8u, (BitField<0, 4>::Get(value))); + EXPECT_EQ(0x45u, (BitField<12, 8>::Get(value))); + EXPECT_EQ(0x12345678u, (BitField<0, 32>::Get(value))); +} + +// Tests that BitField<>::MakeValue generates the right bits. +TEST(BitFieldTest, TestMakeValue) { + EXPECT_EQ(0x00000003u, (BitField<0, 4>::MakeValue(0x3))); + EXPECT_EQ(0x00023000u, (BitField<12, 8>::MakeValue(0x123))); + EXPECT_EQ(0x87654321u, (BitField<0, 32>::MakeValue(0x87654321))); +} + +// Tests that BitField<>::Set modifies the right bits. +TEST(BitFieldTest, TestSet) { + unsigned int value = 0x12345678u; + BitField<0, 4>::Set(&value, 0x9); + EXPECT_EQ(0x12345679u, value); + BitField<12, 8>::Set(&value, 0x123); + EXPECT_EQ(0x12323679u, value); + BitField<0, 32>::Set(&value, 0x87654321); + EXPECT_EQ(0x87654321u, value); +} + +} // namespace command_buffer diff --git a/o3d/command_buffer/common/cmd_buffer_common.cc b/o3d/command_buffer/common/cmd_buffer_common.cc new file mode 100644 index 0000000..b23b0e9 --- /dev/null +++ b/o3d/command_buffer/common/cmd_buffer_common.cc @@ -0,0 +1,57 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the binary format definition of the command buffer and +// command buffer commands. + +#include "command_buffer/common/cmd_buffer_common.h" + +namespace command_buffer { +namespace cmd { + +const char* GetCommandName(CommandId command_id) { + static const char* const names[] = { + #define COMMON_COMMAND_BUFFER_CMD_OP(name) # name, + + COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP) + + #undef COMMON_COMMAND_BUFFER_CMD_OP + }; + + int id = static_cast(command_id); + return (id >= 0 && id < kNumCommands) ? names[id] : "*unknown-command*"; +} + +} // namespace cmd +} // namespace command_buffer + + diff --git a/o3d/command_buffer/common/cmd_buffer_common.h b/o3d/command_buffer/common/cmd_buffer_common.h new file mode 100644 index 0000000..cbafa98 --- /dev/null +++ b/o3d/command_buffer/common/cmd_buffer_common.h @@ -0,0 +1,247 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the common parts of command buffer formats. + +#ifndef GPU_COMMAND_BUFFER_COMMON_CROSS_CMD_BUFFER_COMMON_H_ +#define GPU_COMMAND_BUFFER_COMMON_CROSS_CMD_BUFFER_COMMON_H_ + +#include "base/basictypes.h" +#include "command_buffer/common/types.h" +#include "command_buffer/common/bitfield_helpers.h" +#include "command_buffer/common/logging.h" + +namespace command_buffer { + +namespace cmd { + enum ArgFlags { + kFixed = 0x0, + kAtLeastN = 0x1, + }; +} // namespace cmd + +// Computes the number of command buffer entries needed for a certain size. In +// other words it rounds up to a multiple of entries. +inline uint32 ComputeNumEntries(size_t size_in_bytes) { + return static_cast( + (size_in_bytes + sizeof(uint32) - 1) / sizeof(uint32)); // NOLINT +} + +// Rounds up to a multiple of entries in bytes. +inline size_t RoundSizeToMultipleOfEntries(size_t size_in_bytes) { + return ComputeNumEntries(size_in_bytes) * sizeof(uint32); // NOLINT +} + +// Struct that defines the command header in the command buffer. +struct CommandHeader { + Uint32 size:8; + Uint32 command:24; + + void Init(uint32 _command, uint32 _size) { + DCHECK_LT(_size, 256u); + command = _command; + size = _size; + } + + // Sets the header based on the passed in command. Can not be used for + // variable sized commands like immediate commands or Noop. + template + void SetCmd() { + COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed); + Init(T::kCmdId, ComputeNumEntries(sizeof(T))); // NOLINT + } + + // Sets the header by a size in bytes. + template + void SetCmdBySize(uint32 size_in_bytes) { + COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); + Init(T::kCmdId, ComputeNumEntries(sizeof(T) + size_in_bytes)); // NOLINT + } +}; + +COMPILE_ASSERT(sizeof(CommandHeader) == 4, Sizeof_CommandHeader_is_not_4); + +// Union that defines possible command buffer entries. +union CommandBufferEntry { + CommandHeader value_header; + Uint32 value_uint32; + Int32 value_int32; + float value_float; +}; + +COMPILE_ASSERT(sizeof(CommandBufferEntry) == 4, + Sizeof_CommandBufferEntry_is_not_4); + + +// Make sure the compiler does not add extra padding to any of the command +// structures. +#pragma pack(push, 1) + +// Gets the address of memory just after a structure in a typesafe way. This is +// used for IMMEDIATE commands to get the address of the place to put the data. +// Immediate command put their data direclty in the command buffer. +// Parameters: +// cmd: Address of command. +template +void* ImmediateDataAddress(T* cmd) { + COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); + return reinterpret_cast(cmd) + sizeof(*cmd); +} + +// Gets the address of the place to put the next command in a typesafe way. +// This can only be used for fixed sized commands. +template +// Parameters: +// cmd: Address of command. +void* NextCmdAddress(void* cmd) { + COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed); + return reinterpret_cast(cmd) + sizeof(T); +} + +// Gets the address of the place to put the next command in a typesafe way. +// This can only be used for variable sized command like IMMEDIATE commands. +// Parameters: +// cmd: Address of command. +// size_of_data_in_bytes: Size of the data for the command. +template +void* NextImmediateCmdAddress(void* cmd, uint32 size_of_data_in_bytes) { + COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); + return reinterpret_cast(cmd) + sizeof(T) + // NOLINT + RoundSizeToMultipleOfEntries(size_of_data_in_bytes); +} + +struct SharedMemory { + void Init(uint32 _id, uint32 _offset) { + id = _id; + offset = _offset; + } + + uint32 id; + uint32 offset; +}; + +COMPILE_ASSERT(offsetof(SharedMemory, id) == 0, + Offsetof_SharedMemory_id_not_0); +COMPILE_ASSERT(offsetof(SharedMemory, offset) == 4, + Offsetof_SharedMemory_offset_not_4); + + +namespace cmd { + +// This macro is used to safely and convienently expand the list of commnad +// buffer commands in to various lists and never have them get out of sync. To +// add a new command, add it this list, create the corresponding structure below +// and then add a function in gapi_decoder.cc called Handle_COMMAND_NAME where +// COMMAND_NAME is the name of your command structure. +// +// NOTE: THE ORDER OF THESE MUST NOT CHANGE (their id is derived by order) +#define COMMON_COMMAND_BUFFER_CMDS(OP) \ + OP(Noop) /* 0 */ \ + OP(SetToken) /* 1 */ \ + +// Common commands. +enum CommandId { + #define COMMON_COMMAND_BUFFER_CMD_OP(name) k ## name, + + COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP) + + #undef COMMON_COMMAND_BUFFER_CMD_OP + + kNumCommands, + kLastCommonId = 1023, // reserve 1024 spaces for common commands. +}; + +COMPILE_ASSERT(kNumCommands - 1 <= kLastCommonId, Too_many_common_commands); + +const char* GetCommandName(CommandId id); + +struct Noop { + typedef Noop ValueType; + static const CommandId kCmdId = kNoop; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + void SetHeader(uint32 skip_count) { + header.Init(kCmdId, skip_count + 1); + } + + void Init(uint32 skip_count) { + SetHeader(skip_count); + } + + static void* Set(void* cmd, uint32 skip_count) { + static_cast(cmd)->Init(skip_count); + return NextImmediateCmdAddress( + cmd, skip_count * sizeof(CommandBufferEntry)); // NOLINT + } + + CommandHeader header; +}; + +COMPILE_ASSERT(sizeof(Noop) == 4, Sizeof_Noop_is_not_4); +COMPILE_ASSERT(offsetof(Noop, header) == 0, Offsetof_Noop_header_not_0); + +struct SetToken { + typedef SetToken ValueType; + static const CommandId kCmdId = kSetToken; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(uint32 _token) { + SetHeader(); + token = _token; + } + static void* Set(void* cmd, uint32 token) { + static_cast(cmd)->Init(token); + return NextCmdAddress(cmd); + } + + CommandHeader header; + uint32 token; +}; + +COMPILE_ASSERT(sizeof(SetToken) == 8, Sizeof_SetToken_is_not_8); +COMPILE_ASSERT(offsetof(SetToken, header) == 0, + Offsetof_SetToken_header_not_0); +COMPILE_ASSERT(offsetof(SetToken, token) == 4, + Offsetof_SetToken_token_not_4); + +} // namespace cmd + +#pragma pack(pop) + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_COMMON_CROSS_CMD_BUFFER_COMMON_H_ + diff --git a/o3d/command_buffer/common/constants.h b/o3d/command_buffer/common/constants.h new file mode 100644 index 0000000..ee874cd --- /dev/null +++ b/o3d/command_buffer/common/constants.h @@ -0,0 +1,71 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef O3D_COMMAND_BUFFER_COMMON_CROSS_CONSTANTS_H_ +#define O3D_COMMAND_BUFFER_COMMON_CROSS_CONSTANTS_H_ + +#include "base/basictypes.h" + +namespace command_buffer { + +typedef int32 CommandBufferOffset; +const CommandBufferOffset kInvalidCommandBufferOffset = -1; + +// Status of the command buffer service. It does not process commands +// (meaning: get will not change) unless in kParsing state. +namespace parser_status { + enum ParserStatus { + kNotConnected, // The service is not connected - initial state. + kNoBuffer, // The service is connected but no buffer was set. + kParsing, // The service is connected, and parsing commands from the + // buffer. + kParseError, // Parsing stopped because a parse error was found. + }; +} + +namespace parse_error { + enum ParseError { + kParseNoError, + kParseInvalidSize, + kParseOutOfBounds, + kParseUnknownCommand, + kParseInvalidArguments, + }; +} + +// Invalid shared memory Id, returned by RegisterSharedMemory in case of +// failure. +const int32 kInvalidSharedMemoryId = -1; + +} // namespace command_buffer + +#endif // O3D_COMMAND_BUFFER_COMMON_CROSS_CONSTANTS_H_ diff --git a/o3d/command_buffer/common/gapi_interface.h b/o3d/command_buffer/common/gapi_interface.h new file mode 100644 index 0000000..d946b5d --- /dev/null +++ b/o3d/command_buffer/common/gapi_interface.h @@ -0,0 +1,833 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the interface class for the low-level graphics API +// (GAPI). + +#ifndef GPU_COMMAND_BUFFER_COMMON_CROSS_GAPI_INTERFACE_H_ +#define GPU_COMMAND_BUFFER_COMMON_CROSS_GAPI_INTERFACE_H_ + +#include "command_buffer/common/constants.h" +#include "command_buffer/common/resource.h" +#include "command_buffer/common/o3d_cmd_format.h" + +namespace command_buffer { +namespace o3d { + +// RBGA color definition. +struct RGBA { + float red; + float green; + float blue; + float alpha; +}; + +// This class defines the low-level graphics API, as a pure interface class. +class GAPIInterface { + public: + typedef parse_error::ParseError ParseError; + + GAPIInterface() {} + virtual ~GAPIInterface() {} + + // Initializes the graphics context. + // Returns: + // true if successful. + virtual bool Initialize() = 0; + + // Destroys the graphics context. + virtual void Destroy() = 0; + + // Starts a frame. Rendering should occur between BeginFrame and EndFrame. + virtual void BeginFrame() = 0; + + // Ends the frame, and bring the back buffer to front. Rendering should occur + // between BeginFrame and EndFrame. + virtual void EndFrame() = 0; + + // Clear buffers, filling them with a constant value. + // Parameters: + // buffers: which buffers to clear. Can be a combination (bitwise or) of + // values from ClearBuffer. + // color: the RGBA color to clear the color target with. + // depth: the depth to clear the depth buffer with. + // stencil: the stencil value to clear the stencil buffer with. + virtual void Clear(unsigned int buffers, + const RGBA &color, + float depth, + unsigned int stencil) = 0; + + // Creates a vertex buffer. + // Parameters: + // id: the resource ID for the new vertex buffer. + // size: the size of the vertex buffer, in bytes. + // flags: the vertex buffer flags, as a combination of vertex_buffer::Flags + // Returns: + // parse_error::kParseInvalidArguments if invalid arguments are + // passed, parse_error::kParseNoError otherwise. + virtual ParseError CreateVertexBuffer(ResourceId id, + unsigned int size, + unsigned int flags) = 0; + + // Destroys a vertex buffer. + // Parameters: + // id: the resource ID of the vertex buffer. + // Returns: + // parse_error::kParseInvalidArguments if an invalid vertex buffer + // ID was passed, parse_error::kParseNoError otherwise. + virtual ParseError DestroyVertexBuffer(ResourceId id) = 0; + + // Sets data into a vertex buffer. + // Parameters: + // id: the resource ID of the vertex buffer. + // offset: the offset into the vertex buffer where to place the data. + // size: the size of the data. + // data: the source data. + // Returns: + // parse_error::kParseInvalidArguments if invalid arguments were + // passed: invalid resource ID, or offset or size out of range. + // parse_error::kParseNoError otherwise. + virtual ParseError SetVertexBufferData(ResourceId id, + unsigned int offset, + unsigned int size, + const void *data) = 0; + + // Gets data from a vertex buffer. + // Parameters: + // id: the resource ID of the vertex buffer. + // offset: the offset into the vertex buffer where to get the data. + // size: the size of the data. + // data: the destination buffer. + // Returns: + // parse_error::kParseInvalidArguments if invalid arguments were + // passed: invalid resource ID, or offset or size out of range. + // parse_error::kParseNoError otherwise. + virtual ParseError GetVertexBufferData(ResourceId id, + unsigned int offset, + unsigned int size, + void *data) = 0; + + // Creates an index buffer. + // Parameters: + // id: the resource ID for the new index buffer. + // size: the size of the index buffer, in bytes. + // flags: the index buffer flags, as a combination of index_buffer::Flags. + // Note that indices are 16 bits unless the index_buffer::INDEX_32BIT + // flag is specified. + // Returns: + // parse_error::kParseInvalidArguments if invalid arguments are + // passed, parse_error::kParseNoError otherwise. + virtual ParseError CreateIndexBuffer(ResourceId id, + unsigned int size, + unsigned int flags) = 0; + + // Destroys an index buffer. + // Parameters: + // id: the resource ID of the index buffer. + // Returns: + // parse_error::kParseInvalidArguments if an invalid index buffer + // ID was passed, parse_error::kParseNoError otherwise. + virtual ParseError DestroyIndexBuffer(ResourceId id) = 0; + + // Sets data into an index buffer. + // Parameters: + // id: the resource ID of the index buffer. + // offset: the offset into the index buffer where to place the data. + // size: the size of the data. + // data: the source data. + // Returns: + // parse_error::kParseInvalidArguments if invalid arguments were + // passed: invalid resource ID, or offset or size out of range. + // parse_error::kParseNoError otherwise. + virtual ParseError SetIndexBufferData(ResourceId id, + unsigned int offset, + unsigned int size, + const void *data) = 0; + + // Gets data from an index buffer. + // Parameters: + // id: the resource ID of the index buffer. + // offset: the offset into the index buffer where to get the data. + // size: the size of the data. + // data: the destination buffer. + // Returns: + // parse_error::kParseInvalidArguments if invalid arguments were + // passed: invalid resource ID, or offset or size out of range. + // parse_error::kParseNoError otherwise. + virtual ParseError GetIndexBufferData(ResourceId id, + unsigned int offset, + unsigned int size, + void *data) = 0; + + // Creates a vertex struct. A vertex struct describes the input vertex + // attribute streams. + // Parameters: + // id: the resource ID of the vertex struct. + // input_count: the number of input vertex attributes. + // returns: + // parse_error::kParseInvalidArguments if invalid arguments are + // passed, parse_error::kParseNoError otherwise. + virtual ParseError CreateVertexStruct(ResourceId id, + unsigned int input_count) = 0; + + // Destroys a vertex struct. + // Parameters: + // id: the resource ID of the vertex struct. + // Returns: + // parse_error::kParseInvalidArguments if an invalid vertex struct + // ID was passed, parse_error::kParseNoError otherwise. + virtual ParseError DestroyVertexStruct(ResourceId id) = 0; + + // Sets an input into a vertex struct. + // Parameters: + // vertex_struct_id: the resource ID of the vertex struct. + // input_index: the index of the input being set. + // vertex_buffer_id: the resource ID of the vertex buffer containing the + // data. + // offset: the offset into the vertex buffer of the input data, in bytes. + // stride: the stride of the input data, in bytes. + // type: the type of the input data. + // semantic: the semantic of the input. + // semantic_index: the semantic index of the input. + // Returns: + // parse_error::kParseInvalidArguments if invalid arguments are + // passed, parse_error::kParseNoError otherwise. + virtual ParseError SetVertexInput(ResourceId vertex_struct_id, + unsigned int input_index, + ResourceId vertex_buffer_id, + unsigned int offset, + unsigned int stride, + vertex_struct::Type type, + vertex_struct::Semantic semantic, + unsigned int semantic_index) = 0; + + // Sets the current vertex struct for drawing. + // Parameters: + // id: the resource ID of the vertex struct. + // Returns: + // parse_error::kParseInvalidArguments if invalid arguments are + // passed (invalid vertex struct), parse_error::kParseNoError + // otherwise. + virtual ParseError SetVertexStruct(ResourceId id) = 0; + + // Draws primitives, using the current vertex struct and the current effect. + // Parameters: + // primitive_type: the type of primitive to draw. + // first: the index of the first vertex. + // count: the number of primitives to draw. + // Returns: + // parse_error::kParseInvalidArguments if invalid arguments are + // passed, parse_error::kParseNoError otherwise. + virtual ParseError Draw(PrimitiveType primitive_type, + unsigned int first, + unsigned int count) = 0; + + // Draws primitives, using the current vertex struct and the current effect, + // as well as an index buffer. + // Parameters: + // primitive_type: the type of primitive to draw. + // index_buffer_id: the resource ID of the index buffer. + // first: the index into the index buffer of the first index to draw. + // count: the number of primitives to draw. + // min_index: the lowest index being drawn. + // max_index: the highest index being drawn. + // Returns: + // parse_error::kParseInvalidArguments if invalid arguments are + // passed, parse_error::kParseNoError otherwise. + virtual ParseError DrawIndexed(PrimitiveType primitive_type, + ResourceId index_buffer_id, + unsigned int first, + unsigned int count, + unsigned int min_index, + unsigned int max_index) = 0; + + // Creates an effect, from source code. + // Parameters: + // id: the resource ID of the effect. + // size: the size of data. + // data: the source code for the effect. + // Returns: + // parse_error::kParseInvalidArguments if invalid arguments are + // passed or the effect failed to compile, + // parse_error::kParseNoError otherwise. + virtual ParseError CreateEffect(ResourceId id, + unsigned int size, + const void *data) = 0; + + // Destroys an effect. + // Parameters: + // id: the resource ID of the effect. + // Returns: + // parse_error::kParseInvalidArguments if an invalid effect ID + // was passed, parse_error::kParseNoError otherwise. + virtual ParseError DestroyEffect(ResourceId id) = 0; + + // Sets the active effect for drawing. + // Parameters: + // id: the resource ID of the effect. + // Returns: + // parse_error::kParseInvalidArguments if invalid arguments are + // passed, parse_error::kParseNoError otherwise. + virtual ParseError SetEffect(ResourceId id) = 0; + + // Gets the number of parameters in an effect, returning it in a memory + // buffer as a Uint32. + // Parameters: + // id: the resource ID of the effect. + // size: the size of the data buffer. Must be at least 4 (the size of the + // Uint32). + // data: the buffer receiving the data. + // Returns: + // parse_error::kParseInvalidArguments if invalid arguments are + // passed, parse_error::kParseNoError otherwise. + virtual ParseError GetParamCount(ResourceId id, + unsigned int size, + void *data) = 0; + + // Creates an effect parameter by index. + // Parameters: + // param_id: the resource ID of the parameter being created. + // effect_id: the resource ID of the effect containing the parameter. + // data_type: the data type for the parameter. Must match the data type in + // the effect source. + // index: the index of the parameter. + // Returns: + // parse_error::kParseInvalidArguments if invalid arguments are + // passed, such as invalid effect ID, unmatching data type or invalid + // index, parse_error::kParseNoError otherwise. + virtual ParseError CreateParam(ResourceId param_id, + ResourceId effect_id, + unsigned int index) = 0; + + // Creates an effect parameter by name. + // Parameters: + // param_id: the resource ID of the parameter being created. + // effect_id: the resource ID of the effect containing the parameter. + // data_type: the data type for the parameter. Must match the data type in + // the effect source. + // size: the size of the parameter name. + // name: the parameter name, as an array of char. Doesn't have to be + // nul-terminated (though nul will terminate the string). + // Returns: + // parse_error::kParseInvalidArguments if invalid arguments are + // passed, such as invalid effect ID, unmatching data type or no parameter + // was found with this name, parse_error::kParseNoError otherwise. + virtual ParseError CreateParamByName(ResourceId param_id, + ResourceId effect_id, + unsigned int size, + const void *name) = 0; + + // Destroys an effect parameter. + // Parameters: + // id: the resource ID of the parameter. + // Returns: + // parse_error::kParseInvalidArguments if an invalid parameter ID + // was passed, parse_error::kParseNoError otherwise. + virtual ParseError DestroyParam(ResourceId id) = 0; + + // Sets the effect parameter data. + // Parameters: + // id: the resource ID of the parameter. + // size: the size of the data. Must be at least the size of the parameter + // as described by its type. + // data: the parameter data. + // parse_error::kParseInvalidArguments if invalid arguments are + // passed, such as invalid parameter ID, or unmatching data size, + // parse_error::kParseNoError otherwise. + virtual ParseError SetParamData(ResourceId id, + unsigned int size, + const void *data) = 0; + + // Gets the parameter description, storing it into a memory buffer. The + // parameter is described by a effect_param::Desc structure. The size must be + // at least the size of that structure. The name and semantic fields are only + // filled if the character strings fit into the memory buffer. In any case, + // the size field (in the effect_param::Desc) is filled with the size needed + // to fill in the structure, the name and the semantic (if any). Thus to get + // the complete information, GetParamDesc can be called twice, once to get + // the size, and, after allocating a big enough buffer, again to fill in the + // complete information including the text strings. + // Parameters: + // id: the resource ID of the parameter. + // size: the size of the memory buffer that wil receive the parameter + // description. Must be at least sizeof(effect_param::Desc). + // data: the memory buffer. + // Returns: + // parse_error::kParseInvalidArguments if invalid arguments are + // passed, such as invalid parameter ID, or unsufficient data size, + // parse_error::kParseNoError otherwise. Note that + // parse_error::kParseNoError will be returned if the structure + // itself fits, not necessarily the names. To make sure all the information + // is available, the caller should compare the returned size member of the + // effect_param::Desc structure to the size parameter passed in. + virtual ParseError GetParamDesc(ResourceId id, + unsigned int size, + void *data) = 0; + + // Gets the number of input streams for an effect, returning it in a memory + // buffer as a Uint32. + // Parameters: + // id: the resource ID of the effect. + // size: the size of the data buffer. Must be at least 4 (the size of the + // Uint32). + // data: the buffer receiving the data. + // Returns: + // parse_error::kParseInvalidArguments if invalid arguments are + // passed, parse_error::kParseNoError otherwise. + virtual ParseError GetStreamCount(ResourceId id, + unsigned int size, + void *data) = 0; + + // Gets the stream semantics, storing them in the data buffer. The stream + // is described by an effect_stream::Desc structure which contains a + // semantic type and a semantic index. + // Parameters: + // id: the resource ID of the effect. + // index: which stream semantic to get + // size: the size of the data buffer. Must be at least 8 (the size of two + // Uint32). + // data: the buffer receiving the data. + virtual ParseError GetStreamDesc(ResourceId id, + unsigned int index, + unsigned int size, + void *data) = 0; + + // Creates a 2D texture resource. + // Parameters: + // id: the resource ID of the texture. + // width: the texture width. Must be positive. + // height: the texture height. Must be positive. + // levels: the number of mipmap levels in the texture, or 0 to use the + // maximum. + // format: the format of the texels in the texture. + // flags: the texture flags, as a combination of texture::Flags. + // enable_render_surfaces: bool for whether to enable render surfaces + // Returns: + // parse_error::kParseInvalidArguments if invalid arguments are + // passed, parse_error::kParseNoError otherwise. + virtual ParseError CreateTexture2D(ResourceId id, + unsigned int width, + unsigned int height, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces) = 0; + + // Creates a 3D texture resource. + // Parameters: + // id: the resource ID of the texture. + // width: the texture width. Must be positive. + // height: the texture height. Must be positive. + // depth: the texture depth. Must be positive. + // levels: the number of mipmap levels in the texture, or 0 to use the + // maximum. + // format: the format of the pixels in the texture. + // flags: the texture flags, as a combination of texture::Flags. + // enable_render_surfaces: bool for whether to enable render surfaces + // Returns: + // parse_error::kParseInvalidArguments if invalid arguments are + // passed, parse_error::kParseNoError otherwise. + virtual ParseError CreateTexture3D(ResourceId id, + unsigned int width, + unsigned int height, + unsigned int depth, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces) = 0; + + // Creates a cube map texture resource. + // Parameters: + // id: the resource ID of the texture. + // side: the texture side length. Must be positive. + // levels: the number of mipmap levels in the texture, or 0 to use the + // maximum. + // format: the format of the pixels in the texture. + // flags: the texture flags, as a combination of texture::Flags. + // enable_render_surfaces: bool for whether to enable render surfaces + // Returns: + // parse_error::kParseInvalidArguments if invalid arguments are + // passed, parse_error::kParseNoError otherwise. + virtual ParseError CreateTextureCube(ResourceId id, + unsigned int side, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces) = 0; + + // Sets texel data into a texture resource. This is a common function for + // each of the texture types, but some restrictions exist based on the + // texture type. The specified rectangle or volume of data, defined by x, y, + // width, height and possibly z and depth must fit into the selected mimmap + // level. Data is encoded by rows of 2D blocks, whose size depends on the + // texel format, usually 1x1 texel, but can be 4x4 for DXT* formats. See + // texture::GetBytesPerBlock, texture::GetBlockSizeX and + // texture::GetBlockSizeY. + // Parameters: + // id: the resource ID of the texture. + // x: the x position of the texel corresponding to the first byte of data. + // y: the y position of the texel corresponding to the first byte of data. + // z: the z position of the texel corresponding to the first byte of data. + // Must be 0 for non-3D textures. + // width: the width of the data rectangle/volume. + // height: the height of the data rectangle/volume. + // depth: the depth of the data volume. Must be 1 for non-3D textures. + // level: the mipmap level to put the data into. + // face: which face of the cube to put the data into. Is ignored for + // non-cube map textures. + // row_pitch: the number of bytes between two consecutive rows of blocks, + // in the source data. + // slice_pitch: the number of bytes between two consecutive slices of + // blocks, in the source data. Is ignored for non-3D textures. + // size: the size of the data. + // data: the texel data. + // Returns: + // parse_error::kParseInvalidArguments if invalid arguments are + // passed, for example invalid size, or out-of-bounds rectangle/volume, + // parse_error::kParseNoError otherwise. + virtual ParseError SetTextureData(ResourceId id, + unsigned int x, + unsigned int y, + unsigned int z, + unsigned int width, + unsigned int height, + unsigned int depth, + unsigned int level, + texture::Face face, + unsigned int pitch, + unsigned int slice_pitch, + unsigned int size, + const void *data) = 0; + + // Gets texel data from a texture resource. This is a common function for + // each of the texture types, but some restrictions exist based on the + // texture type. The specified rectangle or volume of data, defined by x, y, + // width, height and possibly z and depth must fit into the selected mimmap + // level. Data is encoded by rows of 2D blocks, whose size depends on the + // texel format, usually 1x1 texel, but can be 4x4 for DXT* formats. See + // texture::GetBytesPerBlock, texture::GetBlockSizeX and + // texture::GetBlockSizeY. + // Parameters: + // id: the resource ID of the texture. + // x: the x position of the texel corresponding to the first byte of data. + // y: the y position of the texel corresponding to the first byte of data. + // z: the z position of the texel corresponding to the first byte of data. + // Must be 0 for non-3D textures. + // width: the width of the data rectangle/volume. + // height: the height of the data rectangle/volume. + // depth: the depth of the data volume. Must be 1 for non-3D textures. + // level: the mipmap level to put the data into. + // face: which face of the cube to put the data into. Is ignored for + // non-cube map textures. + // row_pitch: the number of bytes between two consecutive rows of blocks, + // in the destination buffer. + // slice_pitch: the number of bytes between two consecutive slices of + // blocks, in the destination buffer. Is ignored for non-3D textures. + // size: the size of the data. + // data: the destination buffer. + // Returns: + // parse_error::kParseInvalidArguments if invalid arguments are + // passed, for example invalid size, or out-of-bounds rectangle/volume, + // parse_error::kParseNoError otherwise. + virtual ParseError GetTextureData(ResourceId id, + unsigned int x, + unsigned int y, + unsigned int z, + unsigned int width, + unsigned int height, + unsigned int depth, + unsigned int level, + texture::Face face, + unsigned int pitch, + unsigned int slice_pitch, + unsigned int size, + void *data) = 0; + + // Destroys a texture resource. + // Parameters: + // id: the resource ID of the texture. + // Returns: + // parse_error::kParseInvalidArguments if an invalid texture + // resource ID was passed, parse_error::kParseNoError otherwise. + virtual ParseError DestroyTexture(ResourceId id) = 0; + + // Creates a sampler resource. + // Parameters: + // id: the resource ID of the sampler. + // Returns: + // parse_error::kParseNoError. + virtual ParseError CreateSampler(ResourceId id) = 0; + + // Destroys a sampler resource. + // Parameters: + // id: the resource ID of the sampler. + // Returns: + // parse_error::kParseInvalidArguments if an invalid sampler + // resource ID was passed, parse_error::kParseNoError otherwise. + virtual ParseError DestroySampler(ResourceId id) = 0; + + // Sets the states in a sampler resource. + // Parameters: + // id: the resource ID of the sampler. + // addressing_u: the addressing mode for the U coordinate. + // addressing_v: the addressing mode for the V coordinate. + // addressing_w: the addressing mode for the W coordinate. + // mag_filter: the filtering mode when magnifying textures. + // min_filter: the filtering mode when minifying textures. + // mip_filter: the filtering mode for mip-map interpolation textures. + // max_anisotropy: the maximum anisotropy. + // Returns: + // parse_error::kParseInvalidArguments if an invalid sampler + // resource ID was passed, parse_error::kParseNoError otherwise. + virtual ParseError SetSamplerStates(ResourceId id, + sampler::AddressingMode addressing_u, + sampler::AddressingMode addressing_v, + sampler::AddressingMode addressing_w, + sampler::FilteringMode mag_filter, + sampler::FilteringMode min_filter, + sampler::FilteringMode mip_filter, + unsigned int max_anisotropy) = 0; + + // Sets the color of border pixels. + // Parameters: + // id: the resource ID of the sampler. + // color: the border color. + // Returns: + // parse_error::kParseInvalidArguments if an invalid sampler + // resource ID was passed, parse_error::kParseNoError otherwise. + virtual ParseError SetSamplerBorderColor(ResourceId id, + const RGBA &color) = 0; + + // Sets the texture resource used by a sampler resource. + // Parameters: + // id: the resource ID of the sampler. + // texture_id: the resource id of the texture. + // Returns: + // parse_error::kParseInvalidArguments if an invalid sampler + // resource ID was passed, parse_error::kParseNoError otherwise. + virtual ParseError SetSamplerTexture(ResourceId id, + ResourceId texture_id) = 0; + + // Sets the viewport, and depth range. + // Parameters: + // x, y: upper left corner of the viewport. + // width, height: dimensions of the viewport. + // z_min, z_max: depth range. + virtual void SetViewport(unsigned int x, + unsigned int y, + unsigned int width, + unsigned int height, + float z_min, + float z_max) = 0; + + // Sets the scissor test enable flag and rectangle. + // Parameters: + // enable: whether or not scissor test is enabled. + // x, y: upper left corner of the scissor rectangle. + // width, height: dimensions of the scissor rectangle. + virtual void SetScissor(bool enable, + unsigned int x, + unsigned int y, + unsigned int width, + unsigned int height) = 0; + + // Sets the point and line rasterization state. + // Parameters: + // line_smooth: Whether or not line anti-aliasing is enabled. + // point_sprite: Whether or not point sprites are enabled. + // point_size: The point size. + virtual void SetPointLineRaster(bool line_smooth, + bool point_sprite, + float point_size) = 0; + + // Sets the polygon rasterization state. + // Parameters: + // fill_mode: The polygon filling mode. + // cull_mode: The polygon face culling mode. + virtual void SetPolygonRaster(PolygonMode fill_mode, + FaceCullMode cull_mode) = 0; + + // Sets the polygon offset state. Polygon offset is enabled if slope_factor + // or units is not 0. + // The applied offset (in window coordinates) is: + // o = max_slope * slope_factor + r * units + // Where max_slope is the maximum slope of the polygon (in window + // coordinates again), and r is the minimum resolvable z unit. + // Parameters: + // slope_factor: slope factor for the offset. + // units: constant factor for the offset. + virtual void SetPolygonOffset(float slope_factor, float units) = 0; + + // Sets the alpha test states. + // Parameters: + // enable: alpha test enable state. + // reference: reference value for comparison. + // comp: alpha comparison function. + virtual void SetAlphaTest(bool enable, + float reference, + Comparison comp) = 0; + + // Sets the depth test states. + // Note: if the depth test is disabled, z values are not written to the z + // buffer (i.e enable/kAlways is different from disable/*). + // Parameters: + // enable: depth test enable state. + // write_enable: depth write enable state. + // comp: depth comparison function. + virtual void SetDepthTest(bool enable, + bool write_enable, + Comparison comp) = 0; + + // Sets the stencil test states. + // Parameters: + // enable: stencil test enable state. + // separate_ccw: whether or not counter-clockwise faces use separate + // functions/operations (2-sided stencil). + // write_mask: stencil write mask. + // compare_mask: stencil compare mask. + // ref: stencil reference value. + // func_ops: stencil test function and operations for both clockwise and + // counter-clockwise faces. This is a bitfield following the following + // description (little-endian addressing): + // bits 0 - 11: clockwise functions/operations + // bits 12 - 15: must be 0. + // bits 16 - 28: counter-clockwise functions/operations + // bits 29 - 32: must be 0. + virtual void SetStencilTest(bool enable, + bool separate_ccw, + unsigned int write_mask, + unsigned int compare_mask, + unsigned int ref, + Uint32 func_ops) = 0; + + // Sets the color write paramters. + // Parameters: + // red: enable red write. + // green: enable green write. + // blue: enable blue write. + // alpha: enable alpha write. + // dither: enable dithering. + virtual void SetColorWrite(bool red, + bool green, + bool blue, + bool alpha, + bool dither) = 0; + + // Sets the blending mode. + // Parameters: + // enable: whether or not to enable blending. + // separate_alpha: whether or not alpha uses separate Equation/Functions + // (if false, it uses the color ones). + // color_eq: the equation for blending of color values. + // color_src_func: the source function for blending of color values. + // color_dst_func: the destination function for blending of color values. + // alpha_eq: the equation for blending of alpha values. + // alpha_src_func: the source function for blending of alpha values. + // alpha_dst_func: the destination function for blending of alpha values. + virtual void SetBlending(bool enable, + bool separate_alpha, + BlendEq color_eq, + BlendFunc color_src_func, + BlendFunc color_dst_func, + BlendEq alpha_eq, + BlendFunc alpha_src_func, + BlendFunc alpha_dst_func) = 0; + + // Sets the blending color. + virtual void SetBlendingColor(const RGBA &color) = 0; + + // Creates a render surface resource. + // Parameters: + // id: the resource ID of the render surface. + // width: the texture width. Must be positive. + // height: the texture height. Must be positive. + // texture_id: the resource id of the texture. + // Returns: + // parse_error::kParseInvalidArguments if invalid arguments are + // passed, parse_error::kParseNoError otherwise. + virtual ParseError CreateRenderSurface(ResourceId id, + unsigned int width, + unsigned int height, + unsigned int mip_level, + unsigned int side, + ResourceId texture_id) = 0; + + // Destroys a render surface resource. + // Parameters: + // id: the resource ID of the render surface. + // Returns: + // parse_error::kParseInvalidArguments if an invalid render + // surface + // resource ID was passed, parse_error::kParseNoError otherwise. + virtual ParseError DestroyRenderSurface(ResourceId id) = 0; + + // Creates a depth stencil surface resource. + // Parameters: + // id: the resource ID of the depth stencil surface. + // width: the texture width. Must be positive. + // height: the texture height. Must be positive. + // Returns: + // parse_error::kParseInvalidArguments if invalid arguments are + // passed, parse_error::kParseNoError otherwise. + virtual ParseError CreateDepthSurface(ResourceId id, + unsigned int width, + unsigned int height) = 0; + + // Destroys a depth stencil surface resource. + // Parameters: + // id: the resource ID of the depth stencil surface. + // Returns: + // parse_error::kParseInvalidArguments if an invalid render + // surface + // resource ID was passed, parse_error::kParseNoError otherwise. + virtual ParseError DestroyDepthSurface(ResourceId id) = 0; + + // Switches the render surface and depth stencil surface to those + // corresponding to the passed in IDs. + // Parameters: + // render_surface_id: the resource ID of the render surface. + // depth_stencil_id: the resource ID of the render depth stencil surface. + // Returns: + // parse_error::kParseInvalidArguments if invalid arguments are + // passed, parse_error::kParseNoError otherwise. + virtual ParseError SetRenderSurface(ResourceId render_surface_id, + ResourceId depth_stencil_id) = 0; + + // Switch the render surface and depth stencil surface back to the main + // surfaces stored in the render + virtual void SetBackSurfaces() = 0; +}; + +} // namespace o3d +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_COMMON_CROSS_GAPI_INTERFACE_H_ diff --git a/o3d/command_buffer/common/logging.h b/o3d/command_buffer/common/logging.h new file mode 100644 index 0000000..a9bbad8 --- /dev/null +++ b/o3d/command_buffer/common/logging.h @@ -0,0 +1,67 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file abstracts differences in logging between NaCl and host +// environment. + +#ifndef GPU_COMMAND_BUFFER_COMMON_CROSS_LOGGING_H_ +#define GPU_COMMAND_BUFFER_COMMON_CROSS_LOGGING_H_ + +#ifndef __native_client__ +#include "base/logging.h" +#else +#include + +// TODO: implement logging through nacl's debug service runtime if +// available. +#define CHECK(X) do {} while (0) +#define CHECK_EQ(X, Y) do {} while (0) +#define CHECK_NE(X, Y) do {} while (0) +#define CHECK_GT(X, Y) do {} while (0) +#define CHECK_GE(X, Y) do {} while (0) +#define CHECK_LT(X, Y) do {} while (0) +#define CHECK_LE(X, Y) do {} while (0) + +#define DCHECK(X) do {} while (0) +#define DCHECK_EQ(X, Y) do {} while (0) +#define DCHECK_NE(X, Y) do {} while (0) +#define DCHECK_GT(X, Y) do {} while (0) +#define DCHECK_GE(X, Y) do {} while (0) +#define DCHECK_LT(X, Y) do {} while (0) +#define DCHECK_LE(X, Y) do {} while (0) + +#define LOG(LEVEL) if (0) std::ostringstream() +#define DLOG(LEVEL) if (0) std::ostringstream() + +#endif + +#endif // GPU_COMMAND_BUFFER_COMMON_CROSS_LOGGING_H_ diff --git a/o3d/command_buffer/common/o3d_cmd_format.cc b/o3d/command_buffer/common/o3d_cmd_format.cc new file mode 100644 index 0000000..c373446 --- /dev/null +++ b/o3d/command_buffer/common/o3d_cmd_format.cc @@ -0,0 +1,57 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the binary format definition of the command buffer and +// command buffer commands. + +#include "command_buffer/common/o3d_cmd_format.h" + +namespace command_buffer { +namespace o3d { + +const char* GetCommandName(CommandId command_id) { + static const char* const names[] = { + #define O3D_COMMAND_BUFFER_CMD_OP(name) # name, + + O3D_COMMAND_BUFFER_CMDS(O3D_COMMAND_BUFFER_CMD_OP) + + #undef O3D_COMMAND_BUFFER_CMD_OP + }; + + int id = static_cast(command_id); + return (id > kStartPoint && id < kNumCommands) ? + names[id - kStartPoint - 1] : "*unknown-command*"; +} + +} // namespace o3d +} // namespace command_buffer + diff --git a/o3d/command_buffer/common/o3d_cmd_format.h b/o3d/command_buffer/common/o3d_cmd_format.h new file mode 100644 index 0000000..937ae0a --- /dev/null +++ b/o3d/command_buffer/common/o3d_cmd_format.h @@ -0,0 +1,3155 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the binary format definition of the command buffer and +// command buffer commands. +// It is recommended you use the CommandBufferHelper object to create commands +// but if you want to go lower level you can use the structures here to help. +// +// A few ways to use them: +// +// Fill out a structure in place: +// +// cmd::SetViewport::Set(ptrToSomeSharedMemory, +// left, right, width, height, z_min, z_max); +// +// Fill out consecutive commands: +// +// Note that each cmd::XXX::Set function returns a pointer to the place +// the next command should go. +// +// void* dest = ptrToSomeSharedMemory; +// dest = cmd::SetViewport::Set(dest, left, right, width, height, min, max); +// dest = cmd::Clear::Set(dest, buffers, r, g, b, a, depth, stencil); +// dest = cmd::Draw::Set(dest, primitive_type, first, count); +// +// NOTE: The types in this file must be POD types. That means they can not have +// constructors, destructors, virtual functions or inheritance and they can only +// use other POD types or intrinsics as members. + +#ifndef GPU_COMMAND_BUFFER_COMMON_CROSS_CMD_BUFFER_FORMAT_H_ +#define GPU_COMMAND_BUFFER_COMMON_CROSS_CMD_BUFFER_FORMAT_H_ + +#include "command_buffer/common/cmd_buffer_common.h" +#include "command_buffer/common/resource.h" + +namespace command_buffer { +namespace o3d { + +// This macro is used to safely and convienently expand the list of commnad +// buffer commands in to various lists and never have them get out of sync. To +// add a new command, add it this list, create the corresponding structure below +// and then add a function in gapi_decoder.cc called Handle_COMMAND_NAME where +// COMMAND_NAME is the name of your command structure. +// +// NOTE: THE ORDER OF THESE MUST NOT CHANGE (their id is derived by order) +#define O3D_COMMAND_BUFFER_CMDS(OP) \ + OP(BeginFrame) /* 1024 */ \ + OP(EndFrame) /* 1025 */ \ + OP(Clear) /* 1026 */ \ + OP(CreateVertexBuffer) /* 1027 */ \ + OP(DestroyVertexBuffer) /* 1028 */ \ + OP(SetVertexBufferData) /* 1029 */ \ + OP(SetVertexBufferDataImmediate) /* 1030 */ \ + OP(GetVertexBufferData) /* 1031 */ \ + OP(CreateIndexBuffer) /* 1032 */ \ + OP(DestroyIndexBuffer) /* 1033 */ \ + OP(SetIndexBufferData) /* 1034 */ \ + OP(SetIndexBufferDataImmediate) /* 1035 */ \ + OP(GetIndexBufferData) /* 1036 */ \ + OP(CreateVertexStruct) /* 1037 */ \ + OP(DestroyVertexStruct) /* 1038 */ \ + OP(SetVertexInput) /* 1039 */ \ + OP(SetVertexStruct) /* 1040 */ \ + OP(Draw) /* 1041 */ \ + OP(DrawIndexed) /* 1042 */ \ + OP(CreateEffect) /* 1043 */ \ + OP(CreateEffectImmediate) /* 1044 */ \ + OP(DestroyEffect) /* 1045 */ \ + OP(SetEffect) /* 1046 */ \ + OP(GetParamCount) /* 1047 */ \ + OP(CreateParam) /* 1048 */ \ + OP(CreateParamByName) /* 1049 */ \ + OP(CreateParamByNameImmediate) /* 1050 */ \ + OP(DestroyParam) /* 1051 */ \ + OP(SetParamData) /* 1052 */ \ + OP(SetParamDataImmediate) /* 1053 */ \ + OP(GetParamDesc) /* 1054 */ \ + OP(GetStreamCount) /* 1055 */ \ + OP(GetStreamDesc) /* 1056 */ \ + OP(DestroyTexture) /* 1057 */ \ + OP(CreateTexture2d) /* 1058 */ \ + OP(CreateTexture3d) /* 1059 */ \ + OP(CreateTextureCube) /* 1060 */ \ + OP(SetTextureData) /* 1061 */ \ + OP(SetTextureDataImmediate) /* 1062 */ \ + OP(GetTextureData) /* 1063 */ \ + OP(CreateSampler) /* 1064 */ \ + OP(DestroySampler) /* 1065 */ \ + OP(SetSamplerStates) /* 1066 */ \ + OP(SetSamplerBorderColor) /* 1067 */ \ + OP(SetSamplerTexture) /* 1068 */ \ + OP(SetViewport) /* 1069 */ \ + OP(SetScissor) /* 1070 */ \ + OP(SetPointLineRaster) /* 1071 */ \ + OP(SetPolygonRaster) /* 1072 */ \ + OP(SetPolygonOffset) /* 1073 */ \ + OP(SetAlphaTest) /* 1074 */ \ + OP(SetDepthTest) /* 1075 */ \ + OP(SetStencilTest) /* 1076 */ \ + OP(SetBlending) /* 1077 */ \ + OP(SetBlendingColor) /* 1078 */ \ + OP(SetColorWrite) /* 1079 */ \ + OP(CreateRenderSurface) /* 1080 */ \ + OP(DestroyRenderSurface) /* 1081 */ \ + OP(CreateDepthSurface) /* 1082 */ \ + OP(DestroyDepthSurface) /* 1083 */ \ + OP(SetRenderSurface) /* 1084 */ \ + OP(SetBackSurfaces) /* 1085 */ \ + + +// GAPI commands. +enum CommandId { + kStartPoint = cmd::kLastCommonId, // All O3D commands start after this. + #define GPU_COMMAND_BUFFER_CMD_OP(name) k ## name, + + O3D_COMMAND_BUFFER_CMDS(GPU_COMMAND_BUFFER_CMD_OP) + + #undef GPU_COMMAND_BUFFER_CMD_OP + + kNumCommands, +}; + +// Bit definitions for buffers to clear. +enum ClearBuffer { + kColor = 0x1, + kDepth = 0x2, + kStencil = 0x4, + kAllBuffers = kColor | kDepth | kStencil +}; + +// Polygon mode for SetPolygonRaster +enum PolygonMode { + kPolygonModePoints, + kPolygonModeLines, + kPolygonModeFill, + kNumPolygonMode +}; + +// Face culling mode for SetPolygonRaster +enum FaceCullMode { + kCullNone, + kCullCW, + kCullCCW, + kNumFaceCullMode +}; + +// Primitive type for Draw and DrawIndexed. +enum PrimitiveType { + kPoints, + kLines, + kLineStrips, + kTriangles, + kTriangleStrips, + kTriangleFans, + kMaxPrimitiveType +}; + +// Comparison function for alpha or depth test +enum Comparison { + kNever, + kLess, + kEqual, + kLEqual, + kGreater, + kNotEqual, + kGEqual, + kAlways, + kNumComparison +}; + +// Stencil operation +enum StencilOp { + kKeep, + kZero, + kReplace, + kIncNoWrap, + kDecNoWrap, + kInvert, + kIncWrap, + kDecWrap, + kNumStencilOp +}; + +// Blend Equation +enum BlendEq { + kBlendEqAdd, + kBlendEqSub, + kBlendEqRevSub, + kBlendEqMin, + kBlendEqMax, + kNumBlendEq +}; + +// Blend Funtion +enum BlendFunc { + kBlendFuncZero, + kBlendFuncOne, + kBlendFuncSrcColor, + kBlendFuncInvSrcColor, + kBlendFuncSrcAlpha, + kBlendFuncInvSrcAlpha, + kBlendFuncDstAlpha, + kBlendFuncInvDstAlpha, + kBlendFuncDstColor, + kBlendFuncInvDstColor, + kBlendFuncSrcAlphaSaturate, + kBlendFuncBlendColor, + kBlendFuncInvBlendColor, + kNumBlendFunc +}; + +const char* GetCommandName(CommandId id); + +// Make sure the compiler does not add extra padding to any of the command +// structures. +#pragma pack(push, 1) + +struct BeginFrame { + typedef BeginFrame ValueType; + static const CommandId kCmdId = kBeginFrame; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init() { + SetHeader(); + } + static void* Set(void* cmd) { + static_cast(cmd)->Init(); + return NextCmdAddress(cmd); + } + + CommandHeader header; +}; + +COMPILE_ASSERT(sizeof(BeginFrame) == 4, Sizeof_BeginFrame_is_not_4); +COMPILE_ASSERT(offsetof(BeginFrame, header) == 0, + OffsetOf_BeginFrame_header_not_0); + +struct EndFrame { + typedef EndFrame ValueType; + static const CommandId kCmdId = kEndFrame; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init() { + SetHeader(); + } + static void* Set(void* cmd) { + static_cast(cmd)->Init(); + return NextCmdAddress(cmd); + } + + CommandHeader header; +}; + +COMPILE_ASSERT(sizeof(EndFrame) == 4, Sizeof_EndFrame_is_not_4); +COMPILE_ASSERT(offsetof(EndFrame, header) == 0, + OffsetOf_EndFrame_header_not_0); + +struct Clear { + typedef Clear ValueType; + static const CommandId kCmdId = kClear; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(uint32 _buffers, float _red, float _green, float _blue, + float _alpha, float _depth, uint32 _stencil) { + SetHeader(); + buffers = _buffers; + red = _red; + green = _green; + blue = _blue; + alpha = _alpha; + depth = _depth; + stencil = _stencil; + } + + static void* Set(void* cmd, uint32 buffers, + float red, float green, float blue, float alpha, + float depth, + uint32 stencil) { + static_cast(cmd)->Init( + buffers, red, green, blue, alpha, depth, stencil); + return NextCmdAddress(cmd); + } + + CommandHeader header; + uint32 buffers; + float red; + float green; + float blue; + float alpha; + float depth; + uint32 stencil; +}; + +COMPILE_ASSERT(sizeof(Clear) == 32, Sizeof_Clear_is_not_32); +COMPILE_ASSERT(offsetof(Clear, header) == 0, + OffsetOf_Clear_header_not_0); +COMPILE_ASSERT(offsetof(Clear, buffers) == 4, + OffsetOf_Clear_buffers_not_4); +COMPILE_ASSERT(offsetof(Clear, red) == 8, + OffsetOf_Clear_red_not_8); +COMPILE_ASSERT(offsetof(Clear, green) == 12, + OffsetOf_Clear_green_not_12); +COMPILE_ASSERT(offsetof(Clear, blue) == 16, + OffsetOf_Clear_blue_not_16); +COMPILE_ASSERT(offsetof(Clear, alpha) == 20, + OffsetOf_Clear_alpha_not_20); +COMPILE_ASSERT(offsetof(Clear, depth) == 24, + OffsetOf_Clear_depth_not_24); +COMPILE_ASSERT(offsetof(Clear, stencil) == 28, + OffsetOf_Clear_stencil_not_28); + +struct SetViewport { + typedef SetViewport ValueType; + static const CommandId kCmdId = kSetViewport; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init( + uint32 _left, + uint32 _top, + uint32 _width, + uint32 _height, + float _z_min, + float _z_max) { + SetHeader(); + left = _left; + top = _top; + width = _width; + height = _height; + z_min = _z_min; + z_max = _z_max; + } + + static void* Set(void* cmd, + uint32 left, + uint32 top, + uint32 width, + uint32 height, + float z_min, + float z_max) { + static_cast(cmd)->Init( + left, + top, + width, + height, + z_min, + z_max); + return NextCmdAddress(cmd); + } + + CommandHeader header; + uint32 left; + uint32 top; + uint32 width; + uint32 height; + float z_min; + float z_max; +}; + +COMPILE_ASSERT(sizeof(SetViewport) == 28, Sizeof_SetViewport_is_not_28); +COMPILE_ASSERT(offsetof(SetViewport, header) == 0, + OffsetOf_SetViewport_header_not_0); +COMPILE_ASSERT(offsetof(SetViewport, left) == 4, + OffsetOf_SetViewport_left_not_4); +COMPILE_ASSERT(offsetof(SetViewport, top) == 8, + OffsetOf_SetViewport_top_not_8); +COMPILE_ASSERT(offsetof(SetViewport, width) == 12, + OffsetOf_SetViewport_width_not_12); +COMPILE_ASSERT(offsetof(SetViewport, height) == 16, + OffsetOf_SetViewport_height_not_16); +COMPILE_ASSERT(offsetof(SetViewport, z_min) == 20, + OffsetOf_SetViewport_z_min_not_20); +COMPILE_ASSERT(offsetof(SetViewport, z_max) == 24, + OffsetOf_SetViewport_z_max_not_24); + +struct CreateVertexBuffer { + typedef CreateVertexBuffer ValueType; + static const CommandId kCmdId = kCreateVertexBuffer; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _vertex_buffer_id, uint32 _size, + vertex_buffer::Flags _flags) { + SetHeader(); + vertex_buffer_id = _vertex_buffer_id; + size = _size; + flags = static_cast(_flags); + } + + static void* Set(void* cmd, ResourceId vertex_buffer_id, + uint32 size, vertex_buffer::Flags flags) { + static_cast(cmd)->Init(vertex_buffer_id, size, flags); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId vertex_buffer_id; + uint32 size; + uint32 flags; +}; + +COMPILE_ASSERT(sizeof(CreateVertexBuffer) == 16, + Sizeof_CreateVertexBuffer_is_not_16); +COMPILE_ASSERT(offsetof(CreateVertexBuffer, header) == 0, + OffsetOf_CreateVertexBuffer_header_not_0); +COMPILE_ASSERT(offsetof(CreateVertexBuffer, vertex_buffer_id) == 4, + OffsetOf_CreateVertexBuffer_vertex_buffer_id_not_4); +COMPILE_ASSERT(offsetof(CreateVertexBuffer, size) == 8, + OffsetOf_CreateVertexBuffer_size_not_8); +COMPILE_ASSERT(offsetof(CreateVertexBuffer, flags) == 12, + OffsetOf_CreateVertexBuffer_flags_not_12); + +struct DestroyVertexBuffer { + typedef DestroyVertexBuffer ValueType; + static const CommandId kCmdId = kDestroyVertexBuffer; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _vertex_buffer_id) { + SetHeader(); + vertex_buffer_id = _vertex_buffer_id; + } + + static void* Set(void* cmd, ResourceId vertex_buffer_id) { + static_cast(cmd)->Init(vertex_buffer_id); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId vertex_buffer_id; +}; + +COMPILE_ASSERT(sizeof(DestroyVertexBuffer) == 8, + Sizeof_DestroyVertexBuffer_is_not_8); +COMPILE_ASSERT(offsetof(DestroyVertexBuffer, header) == 0, + OffsetOf_DestroyVertexBuffer_header_not_0); +COMPILE_ASSERT(offsetof(DestroyVertexBuffer, vertex_buffer_id) == 4, + OffsetOf_DestroyVertexBuffer_vertex_buffer_id_not_4); + +struct SetVertexBufferDataImmediate { + typedef SetVertexBufferDataImmediate ValueType; + static const CommandId kCmdId = kSetVertexBufferDataImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + void SetHeader(uint32 size) { + header.SetCmdBySize(size); + } + + void Init(ResourceId _vertex_buffer_id, uint32 _offset, + const void* data, uint32 size) { + SetHeader(size); + vertex_buffer_id = _vertex_buffer_id; + offset = _offset; + memcpy(ImmediateDataAddress(this), data, size); + } + + static void* Set(void* cmd, ResourceId vertex_buffer_id, uint32 offset, + const void* data, uint32 size) { + static_cast(cmd)->Init(vertex_buffer_id, offset, data, size); + return NextImmediateCmdAddress(cmd, size); + } + + CommandHeader header; + ResourceId vertex_buffer_id; + uint32 offset; +}; + +COMPILE_ASSERT(sizeof(SetVertexBufferDataImmediate) == 12, + Sizeof_SetVertexBufferDataImmediate_is_not_12); +COMPILE_ASSERT(offsetof(SetVertexBufferDataImmediate, header) == 0, + OffsetOf_SetVertexBufferDataImmediate_header_not_0); +COMPILE_ASSERT(offsetof(SetVertexBufferDataImmediate, vertex_buffer_id) == 4, + OffsetOf_SetVertexBufferDataImmediate_vertex_buffer_id_not_4); +COMPILE_ASSERT(offsetof(SetVertexBufferDataImmediate, offset) == 8, + OffsetOf_SetVertexBufferDataImmediate_offset_not_8); + +struct SetVertexBufferData { + typedef SetVertexBufferData ValueType; + static const CommandId kCmdId = kSetVertexBufferData; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _vertex_buffer_id, uint32 _offset, uint32 _size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + SetHeader(); + vertex_buffer_id = _vertex_buffer_id; + offset = _offset; + size = _size; + shared_memory.Init(shared_memory_id, shared_memory_offset); + } + + static void* Set(void* cmd, ResourceId vertex_buffer_id, + uint32 offset, uint32 size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + static_cast(cmd)->Init(vertex_buffer_id, offset, size, + shared_memory_id, shared_memory_offset); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId vertex_buffer_id; + uint32 offset; + uint32 size; + SharedMemory shared_memory; +}; + +COMPILE_ASSERT(sizeof(SetVertexBufferData) == 24, + Sizeof_SetVertexBufferData_is_not_24); +COMPILE_ASSERT(offsetof(SetVertexBufferData, header) == 0, + OffsetOf_SetVertexBufferData_header_not_0); +COMPILE_ASSERT(offsetof(SetVertexBufferData, vertex_buffer_id) == 4, + OffsetOf_SetVertexBufferData_vertex_buffer_id_not_4); +COMPILE_ASSERT(offsetof(SetVertexBufferData, offset) == 8, + OffsetOf_SetVertexBufferData_offset_not_8); +COMPILE_ASSERT(offsetof(SetVertexBufferData, size) == 12, + OffsetOf_SetVertexBufferData_size_not_12); +COMPILE_ASSERT(offsetof(SetVertexBufferData, shared_memory) == 16, + OffsetOf_SetVertexBufferData_shared_memory_not_16); + +struct GetVertexBufferData { + typedef GetVertexBufferData ValueType; + static const CommandId kCmdId = kGetVertexBufferData; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _vertex_buffer_id, uint32 _offset, uint32 _size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + SetHeader(); + vertex_buffer_id = _vertex_buffer_id; + offset = _offset; + size = _size; + shared_memory.Init(shared_memory_id, shared_memory_offset); + } + + static void* Set(void* cmd, ResourceId vertex_buffer_id, + uint32 offset, uint32 size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + static_cast(cmd)->Init(vertex_buffer_id, offset, size, + shared_memory_id, shared_memory_offset); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId vertex_buffer_id; + uint32 offset; + uint32 size; + SharedMemory shared_memory; +}; + +COMPILE_ASSERT(sizeof(GetVertexBufferData) == 24, + Sizeof_GetVertexBufferData_is_not_24); +COMPILE_ASSERT(offsetof(GetVertexBufferData, header) == 0, + OffsetOf_GetVertexBufferData_header_not_0); +COMPILE_ASSERT(offsetof(GetVertexBufferData, vertex_buffer_id) == 4, + OffsetOf_GetVertexBufferData_vertex_buffer_id_not_4); +COMPILE_ASSERT(offsetof(GetVertexBufferData, offset) == 8, + OffsetOf_GetVertexBufferData_offset_not_8); +COMPILE_ASSERT(offsetof(GetVertexBufferData, size) == 12, + OffsetOf_GetVertexBufferData_size_not_12); +COMPILE_ASSERT(offsetof(GetVertexBufferData, shared_memory) == 16, + OffsetOf_GetVertexBufferData_shared_memory_not_16); + +struct CreateIndexBuffer { + typedef CreateIndexBuffer ValueType; + static const CommandId kCmdId = kCreateIndexBuffer; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _index_buffer_id, uint32 _size, + index_buffer::Flags _flags) { + SetHeader(); + index_buffer_id = _index_buffer_id; + size = _size; + flags = static_cast(_flags); + } + + static void* Set(void* cmd, ResourceId index_buffer_id, + uint32 size, index_buffer::Flags flags) { + static_cast(cmd)->Init(index_buffer_id, size, flags); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId index_buffer_id; + uint32 size; + uint32 flags; +}; + +COMPILE_ASSERT(sizeof(CreateIndexBuffer) == 16, + Sizeof_CreateIndexBuffer_is_not_16); +COMPILE_ASSERT(offsetof(CreateIndexBuffer, header) == 0, + OffsetOf_CreateIndexBuffer_header_not_0); +COMPILE_ASSERT(offsetof(CreateIndexBuffer, index_buffer_id) == 4, + OffsetOf_CreateIndexBuffer_index_buffer_id_not_4); +COMPILE_ASSERT(offsetof(CreateIndexBuffer, size) == 8, + OffsetOf_CreateIndexBuffer_size_not_8); +COMPILE_ASSERT(offsetof(CreateIndexBuffer, flags) == 12, + OffsetOf_CreateIndexBuffer_flags_not_12); + +struct DestroyIndexBuffer { + typedef DestroyIndexBuffer ValueType; + static const CommandId kCmdId = kDestroyIndexBuffer; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _index_buffer_id) { + SetHeader(); + index_buffer_id = _index_buffer_id; + } + + static void* Set(void* cmd, ResourceId index_buffer_id) { + static_cast(cmd)->Init(index_buffer_id); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId index_buffer_id; +}; + +COMPILE_ASSERT(sizeof(DestroyIndexBuffer) == 8, + Sizeof_DestroyIndexBuffer_is_not_8); +COMPILE_ASSERT(offsetof(DestroyIndexBuffer, header) == 0, + OffsetOf_DestroyIndexBuffer_header_not_0); +COMPILE_ASSERT(offsetof(DestroyIndexBuffer, index_buffer_id) == 4, + OffsetOf_DestroyIndexBuffer_index_buffer_id_not_4); + +struct SetIndexBufferDataImmediate { + typedef SetIndexBufferDataImmediate ValueType; + static const CommandId kCmdId = kSetIndexBufferDataImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + void SetHeader(uint32 size) { + header.SetCmdBySize(size); + } + + void Init(ResourceId _index_buffer_id, uint32 _offset, + const void* data, uint32 size) { + SetHeader(size); + index_buffer_id = _index_buffer_id; + offset = _offset; + memcpy(ImmediateDataAddress(this), data, size); + } + + static void* Set(void* cmd, ResourceId index_buffer_id, uint32 offset, + const void* data, uint32 size) { + static_cast(cmd)->Init(index_buffer_id, offset, data, size); + return NextImmediateCmdAddress(cmd, size); + } + + CommandHeader header; + ResourceId index_buffer_id; + uint32 offset; +}; + +COMPILE_ASSERT(sizeof(SetIndexBufferDataImmediate) == 12, + Sizeof_SetIndexBufferDataImmediate_is_not_12); +COMPILE_ASSERT(offsetof(SetIndexBufferDataImmediate, header) == 0, + OffsetOf_SetIndexBufferDataImmediate_header_not_0); +COMPILE_ASSERT(offsetof(SetIndexBufferDataImmediate, index_buffer_id) == 4, + OffsetOf_SetIndexBufferDataImmediate_index_buffer_id_not_4); +COMPILE_ASSERT(offsetof(SetIndexBufferDataImmediate, offset) == 8, + OffsetOf_SetIndexBufferDataImmediate_offset_not_8); + +struct SetIndexBufferData { + typedef SetIndexBufferData ValueType; + static const CommandId kCmdId = kSetIndexBufferData; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _index_buffer_id, uint32 _offset, uint32 _size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + SetHeader(); + index_buffer_id = _index_buffer_id; + offset = _offset; + size = _size; + shared_memory.Init(shared_memory_id, shared_memory_offset); + } + + static void* Set(void* cmd, + ResourceId index_buffer_id, uint32 offset, uint32 size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + static_cast(cmd)->Init(index_buffer_id, offset, size, + shared_memory_id, shared_memory_offset); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId index_buffer_id; + uint32 offset; + uint32 size; + SharedMemory shared_memory; +}; + +COMPILE_ASSERT(sizeof(SetIndexBufferData) == 24, + Sizeof_SetIndexBufferData_is_not_24); +COMPILE_ASSERT(offsetof(SetIndexBufferData, header) == 0, + OffsetOf_SetIndexBufferData_header_not_0); +COMPILE_ASSERT(offsetof(SetIndexBufferData, index_buffer_id) == 4, + OffsetOf_SetIndexBufferData_index_buffer_id_not_4); +COMPILE_ASSERT(offsetof(SetIndexBufferData, offset) == 8, + OffsetOf_SetIndexBufferData_offset_not_8); +COMPILE_ASSERT(offsetof(SetIndexBufferData, size) == 12, + OffsetOf_SetIndexBufferData_size_not_12); +COMPILE_ASSERT(offsetof(SetIndexBufferData, shared_memory) == 16, + OffsetOf_SetIndexBufferData_shared_memory_not_16); + +struct GetIndexBufferData { + typedef GetIndexBufferData ValueType; + static const CommandId kCmdId = kGetIndexBufferData; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _index_buffer_id, uint32 _offset, uint32 _size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + SetHeader(); + index_buffer_id = _index_buffer_id; + offset = _offset; + size = _size; + shared_memory.Init(shared_memory_id, shared_memory_offset); + } + + static void* Set(void* cmd, ResourceId index_buffer_id, + uint32 offset, uint32 size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + static_cast(cmd)->Init(index_buffer_id, offset, size, + shared_memory_id, shared_memory_offset); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId index_buffer_id; + uint32 offset; + uint32 size; + SharedMemory shared_memory; +}; + +COMPILE_ASSERT(sizeof(GetIndexBufferData) == 24, + Sizeof_GetIndexBufferData_is_not_24); +COMPILE_ASSERT(offsetof(GetIndexBufferData, header) == 0, + OffsetOf_GetIndexBufferData_header_not_0); +COMPILE_ASSERT(offsetof(GetIndexBufferData, index_buffer_id) == 4, + OffsetOf_GetIndexBufferData_index_buffer_id_not_4); +COMPILE_ASSERT(offsetof(GetIndexBufferData, offset) == 8, + OffsetOf_GetIndexBufferData_offset_not_8); +COMPILE_ASSERT(offsetof(GetIndexBufferData, size) == 12, + OffsetOf_GetIndexBufferData_size_not_12); +COMPILE_ASSERT(offsetof(GetIndexBufferData, shared_memory) == 16, + OffsetOf_GetIndexBufferData_shared_memory_not_16); + +struct CreateVertexStruct { + typedef CreateVertexStruct ValueType; + static const CommandId kCmdId = kCreateVertexStruct; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _vertex_struct_id, uint32 _input_count) { + SetHeader(); + vertex_struct_id = _vertex_struct_id; + input_count = _input_count; + } + + static void* Set(void* cmd, ResourceId vertex_struct_id, uint32 input_count) { + static_cast(cmd)->Init(vertex_struct_id, input_count); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId vertex_struct_id; + uint32 input_count; +}; + +COMPILE_ASSERT(sizeof(CreateVertexStruct) == 12, + Sizeof_CreateVertexStruct_is_not_12); +COMPILE_ASSERT(offsetof(CreateVertexStruct, header) == 0, + OffsetOf_CreateVertexStruct_header_not_0); +COMPILE_ASSERT(offsetof(CreateVertexStruct, vertex_struct_id) == 4, + OffsetOf_CreateVertexStruct_vertex_struct_id_not_4); +COMPILE_ASSERT(offsetof(CreateVertexStruct, input_count) == 8, + OffsetOf_CreateVertexStruct_input_count_not_8); + +struct DestroyVertexStruct { + typedef DestroyVertexStruct ValueType; + static const CommandId kCmdId = kDestroyVertexStruct; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _vertex_struct_id) { + SetHeader(); + vertex_struct_id = _vertex_struct_id; + } + + static void* Set(void* cmd, ResourceId vertex_struct_id) { + static_cast(cmd)->Init(vertex_struct_id); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId vertex_struct_id; +}; + +COMPILE_ASSERT(sizeof(DestroyVertexStruct) == 8, + Sizeof_DestroyVertexStruct_is_not_8); +COMPILE_ASSERT(offsetof(DestroyVertexStruct, header) == 0, + OffsetOf_DestroyVertexStruct_header_not_0); +COMPILE_ASSERT(offsetof(DestroyVertexStruct, vertex_struct_id) == 4, + OffsetOf_DestroyVertexStruct_vertex_struct_id_not_4); + +struct SetVertexInput { + typedef SetVertexInput ValueType; + static const CommandId kCmdId = kSetVertexInput; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + // type_stride_semantic field. + typedef BitField<0, 4> SemanticIndex; + typedef BitField<4, 4> Semantic; + typedef BitField<8, 8> Type; + typedef BitField<16, 16> Stride; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _vertex_struct_id, + uint32 _input_index, + ResourceId _vertex_buffer_id, + uint32 _offset, + vertex_struct::Semantic _semantic, + uint32 _semantic_index, + vertex_struct::Type _type, + uint32 _stride) { + SetHeader(); + vertex_struct_id = _vertex_struct_id; + input_index = _input_index; + vertex_buffer_id = _vertex_buffer_id; + offset = _offset; + type_stride_semantic = + Semantic::MakeValue(_semantic) | + SemanticIndex::MakeValue(_semantic_index) | + Type::MakeValue(_type) | + Stride::MakeValue(_stride); + } + + static void* Set( + void* cmd, + ResourceId vertex_struct_id, + uint32 input_index, + ResourceId vertex_buffer_id, + uint32 offset, + vertex_struct::Semantic semantic, + uint32 semantic_index, + vertex_struct::Type type, + uint32 stride) { + static_cast(cmd)->Init( + vertex_struct_id, + input_index, + vertex_buffer_id, + offset, + semantic, + semantic_index, + type, + stride); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId vertex_struct_id; + uint32 input_index; + ResourceId vertex_buffer_id; + uint32 offset; + uint32 type_stride_semantic; +}; + +COMPILE_ASSERT(sizeof(SetVertexInput) == 24, + Sizeof_SetVertexInput_is_not_24); +COMPILE_ASSERT(offsetof(SetVertexInput, header) == 0, + OffsetOf_SetVertexInput_header_not_0); +COMPILE_ASSERT(offsetof(SetVertexInput, vertex_struct_id) == 4, + OffsetOf_SetVertexInput_vertex_struct_id_not_4); +COMPILE_ASSERT(offsetof(SetVertexInput, input_index) == 8, + OffsetOf_SetVertexInput_input_index_not_8); +COMPILE_ASSERT(offsetof(SetVertexInput, vertex_buffer_id) == 12, + OffsetOf_SetVertexInput_vertex_buffer_id_not_12); +COMPILE_ASSERT(offsetof(SetVertexInput, offset) == 16, + OffsetOf_SetVertexInput_offset_not_16); +COMPILE_ASSERT(offsetof(SetVertexInput, type_stride_semantic) == 20, + OffsetOf_SetVertexInput_type_stride_semantic_not_20); + +struct SetVertexStruct { + typedef SetVertexStruct ValueType; + static const CommandId kCmdId = kSetVertexStruct; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _vertex_struct_id) { + SetHeader(); + vertex_struct_id = _vertex_struct_id; + } + + static void* Set(void* cmd, ResourceId vertex_struct_id) { + static_cast(cmd)->Init(vertex_struct_id); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId vertex_struct_id; +}; + +COMPILE_ASSERT(sizeof(SetVertexStruct) == 8, + Sizeof_SetVertexStruct_is_not_8); +COMPILE_ASSERT(offsetof(SetVertexStruct, header) == 0, + OffsetOf_SetVertexStruct_header_not_0); +COMPILE_ASSERT(offsetof(SetVertexStruct, vertex_struct_id) == 4, + OffsetOf_SetVertexStruct_vertex_struct_id_not_4); + +struct Draw { + typedef Draw ValueType; + static const CommandId kCmdId = kDraw; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(PrimitiveType _primitive_type, uint32 _first, uint32 _count) { + SetHeader(); + primitive_type = _primitive_type; + first = _first; + count = _count; + } + + static void* Set(void* cmd, PrimitiveType primitive_type, uint32 first, + uint32 count) { + static_cast(cmd)->Init(primitive_type, first, count); + return NextCmdAddress(cmd); + } + + CommandHeader header; + uint32 primitive_type; + uint32 first; + uint32 count; +}; + +COMPILE_ASSERT(sizeof(Draw) == 16, Sizeof_DRAW_is_not_16); +COMPILE_ASSERT(offsetof(Draw, header) == 0, + OffsetOf_Draw_header_not_0); +COMPILE_ASSERT(offsetof(Draw, primitive_type) == 4, + OffsetOf_Draw_primitive_type_not_4); +COMPILE_ASSERT(offsetof(Draw, first) == 8, + OffsetOf_Draw_first_not_8); +COMPILE_ASSERT(offsetof(Draw, count) == 12, + OffsetOf_Draw_count_not_12); + +struct DrawIndexed { + typedef DrawIndexed ValueType; + static const CommandId kCmdId = kDrawIndexed; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init( + PrimitiveType _primitive_type, + ResourceId _index_buffer_id, + uint32 _first, + uint32 _count, + uint32 _min_index, + uint32 _max_index) { + SetHeader(); + primitive_type = _primitive_type; + index_buffer_id = _index_buffer_id; + first = _first; + count = _count; + min_index = _min_index; + max_index = _max_index; + } + + static void* Set(void* cmd, + PrimitiveType primitive_type, + ResourceId index_buffer_id, + uint32 first, + uint32 count, + uint32 min_index, + uint32 max_index) { + static_cast(cmd)->Init( + primitive_type, + index_buffer_id, + first, + count, + min_index, + max_index); + return NextCmdAddress(cmd); + } + + CommandHeader header; + uint32 primitive_type; + ResourceId index_buffer_id; + uint32 first; + uint32 count; + uint32 min_index; + uint32 max_index; +}; + +COMPILE_ASSERT(sizeof(DrawIndexed) == 28, Sizeof_DrawIndexed_is_not_28); +COMPILE_ASSERT(offsetof(DrawIndexed, header) == 0, + OffsetOf_DrawIndexed_header_not_0); +COMPILE_ASSERT(offsetof(DrawIndexed, primitive_type) == 4, + OffsetOf_DrawIndexed_primitive_type_not_4); +COMPILE_ASSERT(offsetof(DrawIndexed, index_buffer_id) == 8, + OffsetOf_DrawIndexed_index_buffer_id_not_8); +COMPILE_ASSERT(offsetof(DrawIndexed, first) == 12, + OffsetOf_DrawIndexed_first_not_12); +COMPILE_ASSERT(offsetof(DrawIndexed, count) == 16, + OffsetOf_DrawIndexed_count_not_16); +COMPILE_ASSERT(offsetof(DrawIndexed, min_index) == 20, + OffsetOf_DrawIndexed_min_index_not_20); +COMPILE_ASSERT(offsetof(DrawIndexed, max_index) == 24, + OffsetOf_DrawIndexed_max_index_not_24); + +struct CreateEffect { + typedef CreateEffect ValueType; + static const CommandId kCmdId = kCreateEffect; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _effect_id, uint32 _size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + SetHeader(); + effect_id = _effect_id; + size = _size; + shared_memory.Init(shared_memory_id, shared_memory_offset); + } + + static void* Set(void* cmd, ResourceId effect_id, uint32 size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + static_cast(cmd)->Init(effect_id, size, + shared_memory_id, shared_memory_offset); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId effect_id; + uint32 size; + SharedMemory shared_memory; +}; + +COMPILE_ASSERT(sizeof(CreateEffect) == 20, Sizeof_CreateEffect_is_not_20); +COMPILE_ASSERT(offsetof(CreateEffect, header) == 0, + OffsetOf_CreateEffect_header_not_0); +COMPILE_ASSERT(offsetof(CreateEffect, effect_id) == 4, + OffsetOf_CreateEffect_effect_id_not_4); +COMPILE_ASSERT(offsetof(CreateEffect, size) == 8, + OffsetOf_CreateEffect_size_not_8); +COMPILE_ASSERT(offsetof(CreateEffect, shared_memory) == 12, + OffsetOf_CreateEffect_shared_memory_not_12); + +struct CreateEffectImmediate { + typedef CreateEffectImmediate ValueType; + static const CommandId kCmdId = kCreateEffectImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + void SetHeader(uint32 size) { + header.SetCmdBySize(size); + } + + void Init(ResourceId _effect_id, uint32 _size, const void* data) { + SetHeader(_size); + effect_id = _effect_id; + size = _size; + } + + static void* Set(void* cmd, + ResourceId effect_id, uint32 size, const void* data) { + static_cast(cmd)->Init(effect_id, size, data); + return NextImmediateCmdAddress(cmd, size); + } + + CommandHeader header; + ResourceId effect_id; + uint32 size; +}; + +COMPILE_ASSERT(sizeof(CreateEffectImmediate) == 12, + Sizeof_CreateEffectImmediate_is_not_12); +COMPILE_ASSERT(offsetof(CreateEffectImmediate, header) == 0, + OffsetOf_CreateEffectImmediate_header_not_0); +COMPILE_ASSERT(offsetof(CreateEffectImmediate, effect_id) == 4, + OffsetOf_CreateEffectImmediate_effect_id_not_4); +COMPILE_ASSERT(offsetof(CreateEffectImmediate, size) == 8, + OffsetOf_CreateEffectImmediate_size_not_8); + +struct DestroyEffect { + typedef DestroyEffect ValueType; + static const CommandId kCmdId = kDestroyEffect; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _effect_id) { + SetHeader(); + effect_id = _effect_id; + } + + static void* Set(void* cmd, ResourceId effect_id) { + static_cast(cmd)->Init(effect_id); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId effect_id; +}; + +COMPILE_ASSERT(sizeof(DestroyEffect) == 8, Sizeof_DestroyEffect_is_not_8); +COMPILE_ASSERT(offsetof(DestroyEffect, header) == 0, + OffsetOf_DestroyEffect_header_not_0); +COMPILE_ASSERT(offsetof(DestroyEffect, effect_id) == 4, + OffsetOf_DestroyEffect_effect_id_not_4); + +struct SetEffect { + typedef SetEffect ValueType; + static const CommandId kCmdId = kSetEffect; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _effect_id) { + SetHeader(); + effect_id = _effect_id; + } + + static void* Set(void* cmd, ResourceId effect_id) { + static_cast(cmd)->Init(effect_id); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId effect_id; +}; + +COMPILE_ASSERT(sizeof(SetEffect) == 8, Sizeof_SetEffect_is_not_8); +COMPILE_ASSERT(offsetof(SetEffect, header) == 0, + OffsetOf_SetEffect_header_not_0); +COMPILE_ASSERT(offsetof(SetEffect, effect_id) == 4, + OffsetOf_SetEffect_effect_id_not_4); + +struct GetParamCount { + typedef GetParamCount ValueType; + static const CommandId kCmdId = kGetParamCount; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _effect_id, uint32 _size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + SetHeader(); + effect_id = _effect_id; + size = _size; + shared_memory.Init(shared_memory_id, shared_memory_offset); + } + + static void* Set(void* cmd, ResourceId effect_id, uint32 size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + static_cast(cmd)->Init(effect_id, size, + shared_memory_id, shared_memory_offset); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId effect_id; + uint32 size; + SharedMemory shared_memory; +}; + +COMPILE_ASSERT(sizeof(GetParamCount) == 20, Sizeof_GetParamCount_is_not_20); +COMPILE_ASSERT(offsetof(GetParamCount, header) == 0, + OffsetOf_GetParamCount_header_not_0); +COMPILE_ASSERT(offsetof(GetParamCount, effect_id) == 4, + OffsetOf_GetParamCount_effect_id_not_4); +COMPILE_ASSERT(offsetof(GetParamCount, size) == 8, + OffsetOf_GetParamCount_size_not_8); +COMPILE_ASSERT(offsetof(GetParamCount, shared_memory) == 12, + OffsetOf_GetParamCount_shared_memory_not_12); + +struct CreateParam { + typedef CreateParam ValueType; + static const CommandId kCmdId = kCreateParam; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _param_id, ResourceId _effect_id, uint32 _index) { + SetHeader(); + param_id = _param_id; + effect_id = _effect_id; + index = _index; + } + + static void* Set(void* cmd, + ResourceId param_id, ResourceId effect_id, uint32 index) { + static_cast(cmd)->Init(param_id, effect_id, index); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId param_id; + ResourceId effect_id; + uint32 index; +}; + +COMPILE_ASSERT(sizeof(CreateParam) == 16, Sizeof_CreateParam_is_not_16); +COMPILE_ASSERT(offsetof(CreateParam, header) == 0, + OffsetOf_CreateParam_header_not_0); +COMPILE_ASSERT(offsetof(CreateParam, param_id) == 4, + OffsetOf_CreateParam_param_id_not_4); +COMPILE_ASSERT(offsetof(CreateParam, effect_id) == 8, + OffsetOf_CreateParam_effect_id_not_8); +COMPILE_ASSERT(offsetof(CreateParam, index) == 12, + OffsetOf_CreateParam_index_not_12); + +struct CreateParamByName { + typedef CreateParamByName ValueType; + static const CommandId kCmdId = kCreateParamByName; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _param_id, ResourceId _effect_id, uint32 _size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + SetHeader(); + param_id = _param_id; + effect_id = _effect_id; + size = _size; + shared_memory.Init(shared_memory_id, shared_memory_offset); + } + + static void* Set(void* cmd, ResourceId param_id, ResourceId effect_id, + uint32 size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + static_cast(cmd)->Init(param_id, effect_id, size, + shared_memory_id, shared_memory_offset); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId param_id; + ResourceId effect_id; + uint32 size; + SharedMemory shared_memory; +}; + +COMPILE_ASSERT(sizeof(CreateParamByName) == 24, + Sizeof_CreateParamByName_is_not_24); +COMPILE_ASSERT(offsetof(CreateParamByName, header) == 0, + OffsetOf_CreateParamByName_header_not_0); +COMPILE_ASSERT(offsetof(CreateParamByName, param_id) == 4, + OffsetOf_CreateParamByName_param_id_not_4); +COMPILE_ASSERT(offsetof(CreateParamByName, effect_id) == 8, + OffsetOf_CreateParamByName_effect_id_not_8); +COMPILE_ASSERT(offsetof(CreateParamByName, size) == 12, + OffsetOf_CreateParamByName_size_not_12); +COMPILE_ASSERT(offsetof(CreateParamByName, shared_memory) == 16, + OffsetOf_CreateParamByName_shared_memory_not_16); + +struct CreateParamByNameImmediate { + typedef CreateParamByNameImmediate ValueType; + static const CommandId kCmdId = kCreateParamByNameImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + void SetHeader(uint32 size) { + header.SetCmdBySize(size); + } + + void Init(ResourceId _param_id, ResourceId _effect_id, uint32 _size, + const void* data) { + SetHeader(_size); + param_id = _param_id; + effect_id = _effect_id; + size = _size; + memcpy(ImmediateDataAddress(this), data, _size); + } + + static void* Set(void* cmd, ResourceId param_id, ResourceId effect_id, + uint32 size, const void* data) { + static_cast(cmd)->Init(param_id, effect_id, size, data); + return NextImmediateCmdAddress(cmd, size); + } + + CommandHeader header; + ResourceId param_id; + ResourceId effect_id; + uint32 size; +}; + +COMPILE_ASSERT(sizeof(CreateParamByNameImmediate) == 16, + Sizeof_CreateParamByNameImmediate_is_not_16); +COMPILE_ASSERT(offsetof(CreateParamByNameImmediate, header) == 0, + OffsetOf_CreateParamByNameImmediate_header_not_0); +COMPILE_ASSERT(offsetof(CreateParamByNameImmediate, param_id) == 4, + OffsetOf_CreateParamByNameImmediate_param_id_not_4); +COMPILE_ASSERT(offsetof(CreateParamByNameImmediate, effect_id) == 8, + OffsetOf_CreateParamByNameImmediate_effect_id_not_8); +COMPILE_ASSERT(offsetof(CreateParamByNameImmediate, size) == 12, + OffsetOf_CreateParamByNameImmediate_size_not_12); + +struct DestroyParam { + typedef DestroyParam ValueType; + static const CommandId kCmdId = kDestroyParam; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _param_id) { + SetHeader(); + param_id = _param_id; + } + + static void* Set(void* cmd, ResourceId param_id) { + static_cast(cmd)->Init(param_id); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId param_id; +}; + +COMPILE_ASSERT(sizeof(DestroyParam) == 8, Sizeof_DestroyParam_is_not_8); +COMPILE_ASSERT(offsetof(DestroyParam, header) == 0, + OffsetOf_DestroyParam_header_not_0); +COMPILE_ASSERT(offsetof(DestroyParam, param_id) == 4, + OffsetOf_DestroyParam_param_id_not_4); + +struct SetParamData { + typedef SetParamData ValueType; + static const CommandId kCmdId = kSetParamData; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _param_id, uint32 _size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + SetHeader(); + param_id = _param_id; + size = _size; + shared_memory.Init(shared_memory_id, shared_memory_offset); + } + + static void* Set(void* cmd, ResourceId param_id, uint32 size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + static_cast(cmd)->Init(param_id, size, + shared_memory_id, shared_memory_offset); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId param_id; + uint32 size; + SharedMemory shared_memory; +}; + +COMPILE_ASSERT(sizeof(SetParamData) == 20, Sizeof_SetParamData_is_not_20); +COMPILE_ASSERT(offsetof(SetParamData, header) == 0, + OffsetOf_SetParamData_header_not_0); +COMPILE_ASSERT(offsetof(SetParamData, param_id) == 4, + OffsetOf_SetParamData_param_id_not_4); +COMPILE_ASSERT(offsetof(SetParamData, size) == 8, + OffsetOf_SetParamData_size_not_8); +COMPILE_ASSERT(offsetof(SetParamData, shared_memory) == 12, + OffsetOf_SetParamData_shared_memory_not_12); + +struct SetParamDataImmediate { + typedef SetParamDataImmediate ValueType; + static const CommandId kCmdId = kSetParamDataImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + void SetHeader(uint32 size) { + header.SetCmdBySize(size); + } + + void Init(ResourceId _param_id, uint32 _size, const void* data) { + SetHeader(_size); + param_id = _param_id; + size = _size; + memcpy(ImmediateDataAddress(this), data, _size); + } + + static void* Set(void* cmd, ResourceId param_id, + uint32 size, const void* data) { + static_cast(cmd)->Init(param_id, size, data); + return NextImmediateCmdAddress(cmd, size); + } + + CommandHeader header; + ResourceId param_id; + uint32 size; +}; + +COMPILE_ASSERT(sizeof(SetParamDataImmediate) == 12, + Sizeof_SetParamDataImmediate_is_not_12); +COMPILE_ASSERT(offsetof(SetParamDataImmediate, header) == 0, + OffsetOf_SetParamDataImmediate_header_not_0); +COMPILE_ASSERT(offsetof(SetParamDataImmediate, param_id) == 4, + OffsetOf_SetParamDataImmediate_param_id_not_4); +COMPILE_ASSERT(offsetof(SetParamDataImmediate, size) == 8, + OffsetOf_SetParamDataImmediate_size_not_8); + +struct GetParamDesc { + typedef GetParamDesc ValueType; + static const CommandId kCmdId = kGetParamDesc; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _param_id, uint32 _size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + SetHeader(); + param_id = _param_id; + size = _size; + shared_memory.Init(shared_memory_id, shared_memory_offset); + } + + static void* Set(void* cmd, ResourceId param_id, uint32 size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + static_cast(cmd)->Init(param_id, size, + shared_memory_id, shared_memory_offset); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId param_id; + uint32 size; + SharedMemory shared_memory; +}; + +COMPILE_ASSERT(sizeof(GetParamDesc) == 20, Sizeof_GetParamDesc_is_not_20); +COMPILE_ASSERT(offsetof(GetParamDesc, header) == 0, + OffsetOf_GetParamDesc_header_not_0); +COMPILE_ASSERT(offsetof(GetParamDesc, param_id) == 4, + OffsetOf_GetParamDesc_id_not_4); +COMPILE_ASSERT(offsetof(GetParamDesc, size) == 8, + OffsetOf_GetParamDesc_size_not_8); +COMPILE_ASSERT(offsetof(GetParamDesc, shared_memory) == 12, + OffsetOf_GetParamDesc_shared_memory_not_12); + +struct GetStreamCount { + typedef GetStreamCount ValueType; + static const CommandId kCmdId = kGetStreamCount; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _effect_id, uint32 _size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + SetHeader(); + effect_id = _effect_id; + size = _size; + shared_memory.Init(shared_memory_id, shared_memory_offset); + } + + static void* Set(void* cmd, ResourceId effect_id, uint32 size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + static_cast(cmd)->Init(effect_id, size, + shared_memory_id, shared_memory_offset); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId effect_id; + uint32 size; + SharedMemory shared_memory; +}; + +COMPILE_ASSERT(sizeof(GetStreamCount) == 20, + Sizeof_GetStreamCount_is_not_20); +COMPILE_ASSERT(offsetof(GetStreamCount, header) == 0, + OffsetOf_GetStreamCount_header_not_0); +COMPILE_ASSERT(offsetof(GetStreamCount, effect_id) == 4, + OffsetOf_GetStreamCount_effect_id_not_4); +COMPILE_ASSERT(offsetof(GetStreamCount, size) == 8, + OffsetOf_GetStreamCount_size_not_8); +COMPILE_ASSERT(offsetof(GetStreamCount, shared_memory) == 12, + OffsetOf_GetStreamCount_shared_memory_not_12); + +struct GetStreamDesc { + typedef GetStreamDesc ValueType; + static const CommandId kCmdId = kGetStreamDesc; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _effect_id, uint32 _index, uint32 _size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + SetHeader(); + effect_id = _effect_id; + index = _index; + size = _size; + shared_memory.Init(shared_memory_id, shared_memory_offset); + } + + static void* Set(void* cmd, ResourceId effect_id, uint32 index, uint32 size, + uint32 shared_memory_id, uint32 shared_memory_offset) { + static_cast(cmd)->Init(effect_id, index, size, + shared_memory_id, shared_memory_offset); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId effect_id; + uint32 index; + uint32 size; + SharedMemory shared_memory; +}; + +COMPILE_ASSERT(sizeof(GetStreamDesc) == 24, Sizeof_GetStreamDesc_is_not_24); +COMPILE_ASSERT(offsetof(GetStreamDesc, header) == 0, + OffsetOf_GetStreamDesc_header_not_0); +COMPILE_ASSERT(offsetof(GetStreamDesc, effect_id) ==4 , + OffsetOf_GetStreamDesc_effect_id_not_4); +COMPILE_ASSERT(offsetof(GetStreamDesc, index) == 8, + OffsetOf_GetStreamDesc_index_not_8); +COMPILE_ASSERT(offsetof(GetStreamDesc, size) == 12, + OffsetOf_GetStreamDesc_size_not_12); +COMPILE_ASSERT(offsetof(GetStreamDesc, shared_memory) == 16, + OffsetOf_GetStreamDesc_shared_memory_not_16); + +struct DestroyTexture { + typedef DestroyTexture ValueType; + static const CommandId kCmdId = kDestroyTexture; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _texture_id) { + SetHeader(); + texture_id = _texture_id; + } + + static void* Set(void* cmd, ResourceId texture_id) { + static_cast(cmd)->Init(texture_id); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId texture_id; +}; + +COMPILE_ASSERT(sizeof(DestroyTexture) == 8, Sizeof_DestroyTexture_is_not_8); +COMPILE_ASSERT(offsetof(DestroyTexture, header) == 0, + OffsetOf_DestroyTexture_header_not_0); +COMPILE_ASSERT(offsetof(DestroyTexture, texture_id) == 4, + OffsetOf_DestroyTexture_texture_id_not_4); + +struct CreateTexture2d { + typedef CreateTexture2d ValueType; + static const CommandId kCmdId = kCreateTexture2d; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + // argument 1 + typedef BitField<0, 16> Width; + typedef BitField<16, 16> Height; + // argument 2 + typedef BitField<0, 4> Levels; + typedef BitField<4, 4> Unused; + typedef BitField<8, 8> Format; + typedef BitField<16, 16> Flags; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _texture_id, + uint32 _width, uint32 _height, uint32 _levels, + texture::Format _format, + bool _enable_render_surfaces) { + SetHeader(); + texture_id = _texture_id; + width_height = Width::MakeValue(_width) | Height::MakeValue(_height); + levels_format_flags = + Levels::MakeValue(_levels) | + Format::MakeValue(_format) | + Flags::MakeValue(_enable_render_surfaces ? 1 : 0); + } + + static void* Set(void* cmd, ResourceId texture_id, + uint32 width, uint32 height, uint32 levels, + texture::Format format, + bool enable_render_surfaces) { + static_cast(cmd)->Init(texture_id, + width, height, levels, format, + enable_render_surfaces); + return NextCmdAddress(cmd); + } + + // TODO(gman): fix this to not use obfusticated fields. + CommandHeader header; + ResourceId texture_id; + uint32 width_height; + uint32 levels_format_flags; +}; + +COMPILE_ASSERT(sizeof(CreateTexture2d) == 16, + Sizeof_CreateTexture2d_is_not_16); +COMPILE_ASSERT(offsetof(CreateTexture2d, header) == 0, + OffsetOf_CreateTexture2d_header_not_0); +COMPILE_ASSERT(offsetof(CreateTexture2d, texture_id) == 4, + OffsetOf_CreateTexture2d_texture_id_not_4); +COMPILE_ASSERT(offsetof(CreateTexture2d, width_height) == 8, + OffsetOf_CreateTexture2d_width_height_not_8); +COMPILE_ASSERT(offsetof(CreateTexture2d, levels_format_flags) == 12, + OffsetOf_CreateTexture2d_levels_format_flags_not_12); + +struct CreateTexture3d { + typedef CreateTexture3d ValueType; + static const CommandId kCmdId = kCreateTexture3d; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + // argument 1 + typedef BitField<0, 16> Width; + typedef BitField<16, 16> Height; + // argument 2 + typedef BitField<0, 16> Depth; + typedef BitField<16, 16> Unused1; + // argument 3 + typedef BitField<0, 4> Levels; + typedef BitField<4, 4> Unused2; + typedef BitField<8, 8> Format; + typedef BitField<16, 16> Flags; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _texture_id, + uint32 _width, uint32 _height, uint32 _depth, + uint32 _levels, texture::Format _format, + bool _enable_render_surfaces) { + SetHeader(); + texture_id = _texture_id; + width_height = Width::MakeValue(_width) | Height::MakeValue(_height); + depth_unused = Depth::MakeValue(_depth); + levels_format_flags = + Levels::MakeValue(_levels) | + Format::MakeValue(_format) | + Flags::MakeValue(_enable_render_surfaces ? 1 : 0); + } + + static void* Set(void* cmd, ResourceId texture_id, + uint32 width, uint32 height, uint32 depth, + uint32 levels, texture::Format format, + bool enable_render_surfaces) { + static_cast(cmd)->Init(texture_id, + width, height, depth, + levels, format, + enable_render_surfaces); + return NextCmdAddress(cmd); + } + + // TODO(gman): fix this to not use obfusticated fields. + CommandHeader header; + ResourceId texture_id; + uint32 width_height; + uint32 depth_unused; + uint32 levels_format_flags; +}; + +COMPILE_ASSERT(sizeof(CreateTexture3d) == 20, + Sizeof_CreateTexture3d_is_not_20); +COMPILE_ASSERT(offsetof(CreateTexture3d, header) == 0, + OffsetOf_CreateTexture3d_header_not_0); +COMPILE_ASSERT(offsetof(CreateTexture3d, texture_id) == 4, + OffsetOf_CreateTexture3d_texture_id_not_4); +COMPILE_ASSERT(offsetof(CreateTexture3d, width_height) == 8, + OffsetOf_CreateTexture3d_width_height_not_8); +COMPILE_ASSERT(offsetof(CreateTexture3d, depth_unused) == 12, + OffsetOf_CreateTexture3d_depth_unused_not_12); +COMPILE_ASSERT(offsetof(CreateTexture3d, levels_format_flags) == 16, + OffsetOf_CreateTexture3d_levels_format_flags_not_16); + +struct CreateTextureCube { + typedef CreateTextureCube ValueType; + static const CommandId kCmdId = kCreateTextureCube; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + // argument 1 + typedef BitField<0, 16> Side; + typedef BitField<16, 16> Unused1; + // argument 2 + typedef BitField<0, 4> Levels; + typedef BitField<4, 4> Unused2; + typedef BitField<8, 8> Format; + typedef BitField<16, 16> Flags; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _texture_id, + uint32 _edge_length, uint32 _levels, texture::Format _format, + bool _enable_render_surfaces) { + SetHeader(); + texture_id = _texture_id; + edge_length = _edge_length; + levels_format_flags = + Levels::MakeValue(_levels) | + Format::MakeValue(_format) | + Flags::MakeValue(_enable_render_surfaces ? 1 : 0); + } + + static void* Set(void* cmd, ResourceId texture_id, + uint32 edge_length, uint32 levels, texture::Format format, + bool enable_render_surfaces) { + static_cast(cmd)->Init(texture_id, + edge_length, levels, format, + enable_render_surfaces); + return NextCmdAddress(cmd); + } + + // TODO(gman): fix this to not use obfusticated fields. + CommandHeader header; + ResourceId texture_id; + uint32 edge_length; + uint32 levels_format_flags; +}; + +COMPILE_ASSERT(sizeof(CreateTextureCube) == 16, + Sizeof_CreateTextureCube_is_not_16); +COMPILE_ASSERT(offsetof(CreateTextureCube, header) == 0, + OffsetOf_CreateTextureCube_header_not_0); +COMPILE_ASSERT(offsetof(CreateTextureCube, texture_id) == 4, + OffsetOf_CreateTextureCube_texture_id_not_4); +COMPILE_ASSERT(offsetof(CreateTextureCube, edge_length) == 8, + OffsetOf_CreateTextureCube_edge_length_not_8); +COMPILE_ASSERT(offsetof(CreateTextureCube, levels_format_flags) == 12, + OffsetOf_CreateTextureCube_levels_format_flags_not_12); + +struct SetTextureData { + typedef SetTextureData ValueType; + static const CommandId kCmdId = kSetTextureData; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + // argument 1 + typedef BitField<0, 16> X; + typedef BitField<16, 16> Y; + // argument 2 + typedef BitField<0, 16> Width; + typedef BitField<16, 16> Height; + // argument 3 + typedef BitField<0, 16> Z; + typedef BitField<16, 16> Depth; + // argument 4 + typedef BitField<0, 4> Level; + typedef BitField<4, 3> Face; + typedef BitField<7, 25> Unused; + + void SetHeader() { + header.SetCmd(); + } + + void Init( + ResourceId _texture_id, + uint32 _x, + uint32 _y, + uint32 _z, + uint32 _width, + uint32 _height, + uint32 _depth, + uint32 _level, + texture::Face _face, + uint32 _row_pitch, + uint32 _slice_pitch, + uint32 _size, + uint32 shared_memory_id, + uint32 shared_memory_offset) { + SetHeader(); + texture_id = _texture_id; + x_y = X::MakeValue(_x) | Y::MakeValue(_y); + width_height = Width::MakeValue(_width) | Height::MakeValue(_height); + z_depth = Z::MakeValue(_z) | Depth::MakeValue(_depth); + level_face = Level::MakeValue(_level) | Face::MakeValue(_face); + row_pitch = _row_pitch; + slice_pitch = _slice_pitch; + size = _size; + shared_memory.Init(shared_memory_id, shared_memory_offset); + } + + static void* Set( + void* cmd, + ResourceId texture_id, + uint32 x, + uint32 y, + uint32 z, + uint32 width, + uint32 height, + uint32 depth, + uint32 level, + texture::Face face, + uint32 row_pitch, + uint32 slice_pitch, + uint32 size, + uint32 shared_memory_id, + uint32 shared_memory_offset) { + static_cast(cmd)->Init( + texture_id, + x, + y, + z, + width, + height, + depth, + level, + face, + row_pitch, + slice_pitch, + size, + shared_memory_id, + shared_memory_offset); + return NextCmdAddress(cmd); + } + + // TODO(gman): fix this to not use obfusticated fields. + CommandHeader header; + ResourceId texture_id; + uint32 x_y; + uint32 width_height; + uint32 z_depth; + uint32 level_face; + uint32 row_pitch; + uint32 slice_pitch; + uint32 size; + SharedMemory shared_memory; +}; + +COMPILE_ASSERT(sizeof(SetTextureData) == 44, + Sizeof_SetTextureData_is_not_44); +COMPILE_ASSERT(offsetof(SetTextureData, header) == 0, + OffsetOf_SetTextureData_header_not_0); +COMPILE_ASSERT(offsetof(SetTextureData, texture_id) == 4, + OffsetOf_SetTextureData_texture_id_not_4); +COMPILE_ASSERT(offsetof(SetTextureData, x_y) == 8, + OffsetOf_SetTextureData_x_y_not_8); +COMPILE_ASSERT(offsetof(SetTextureData, width_height) == 12, + OffsetOf_SetTextureData_width_height_not_12); +COMPILE_ASSERT(offsetof(SetTextureData, z_depth) == 16, + OffsetOf_SetTextureData_z_depth_not_16); +COMPILE_ASSERT(offsetof(SetTextureData, level_face) == 20, + OffsetOf_SetTextureData_level_face_not_20); +COMPILE_ASSERT(offsetof(SetTextureData, row_pitch) == 24, + OffsetOf_SetTextureData_row_pitch_not_24); +COMPILE_ASSERT(offsetof(SetTextureData, slice_pitch) == 28, + OffsetOf_SetTextureData_slice_pitch_not_28); +COMPILE_ASSERT(offsetof(SetTextureData, size) == 32, + OffsetOf_SetTextureData_size_not_32); +COMPILE_ASSERT(offsetof(SetTextureData, shared_memory) == 36, + OffsetOf_SetTextureData_shared_memory_not_36); + +struct SetTextureDataImmediate { + typedef SetTextureDataImmediate ValueType; + static const CommandId kCmdId = kSetTextureDataImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + // argument 1 + typedef BitField<0, 16> X; + typedef BitField<16, 16> Y; + // argument 2 + typedef BitField<0, 16> Width; + typedef BitField<16, 16> Height; + // argument 3 + typedef BitField<0, 16> Z; + typedef BitField<16, 16> Depth; + // argument 4 + typedef BitField<0, 4> Level; + typedef BitField<4, 3> Face; + typedef BitField<7, 25> Unused; + + void SetHeader(uint32 size) { + header.SetCmdBySize(size); + } + + void Init( + ResourceId _texture_id, + uint32 _x, + uint32 _y, + uint32 _z, + uint32 _width, + uint32 _height, + uint32 _depth, + uint32 _level, + texture::Face _face, + uint32 _row_pitch, + uint32 _slice_pitch, + uint32 _size, + const void* data) { + SetHeader(_size); + texture_id = _texture_id; + x_y = X::MakeValue(_x) | Y::MakeValue(_y); + width_height = Width::MakeValue(_width) | Height::MakeValue(_height); + z_depth = Z::MakeValue(_z) | Depth::MakeValue(_depth); + level_face = Level::MakeValue(_level) | Face::MakeValue(_face); + row_pitch = _row_pitch; + slice_pitch = _slice_pitch; + size = _size; + memcpy(ImmediateDataAddress(this), data, _size); + } + + static void* Set( + void* cmd, + ResourceId texture_id, + uint32 x, + uint32 y, + uint32 z, + uint32 width, + uint32 height, + uint32 depth, + uint32 level, + texture::Face face, + uint32 row_pitch, + uint32 slice_pitch, + uint32 size, + const void* data) { + static_cast(cmd)->Init( + texture_id, + x, + y, + z, + width, + height, + depth, + level, + face, + row_pitch, + slice_pitch, + size, + data); + return NextImmediateCmdAddress(cmd, size); + } + + // TODO(gman): fix this to not use obfusticated fields. + CommandHeader header; + ResourceId texture_id; + uint32 x_y; + uint32 width_height; + uint32 z_depth; + uint32 level_face; + uint32 row_pitch; + uint32 slice_pitch; + uint32 size; +}; + +COMPILE_ASSERT(sizeof(SetTextureDataImmediate) == 36, + Sizeof_SetTextureDataImmediate_is_not_36); +COMPILE_ASSERT(offsetof(SetTextureDataImmediate, header) == 0, + OffsetOf_SetTextureDataImmediate_header_not_0); +COMPILE_ASSERT(offsetof(SetTextureDataImmediate, texture_id) == 4, + OffsetOf_SetTextureDataImmediate_texture_id_not_4); +COMPILE_ASSERT(offsetof(SetTextureDataImmediate, x_y) == 8, + OffsetOf_SetTextureDataImmediate_x_y_not_8); +COMPILE_ASSERT(offsetof(SetTextureDataImmediate, width_height) == 12, + OffsetOf_SetTextureDataImmediate_width_height_not_12); +COMPILE_ASSERT(offsetof(SetTextureDataImmediate, z_depth) == 16, + OffsetOf_SetTextureDataImmediate_z_depth_not_16); +COMPILE_ASSERT(offsetof(SetTextureDataImmediate, level_face) == 20, + OffsetOf_SetTextureDataImmediate_level_face_not_20); +COMPILE_ASSERT(offsetof(SetTextureDataImmediate, row_pitch) == 24, + OffsetOf_SetTextureDataImmediate_row_pitch_not_24); +COMPILE_ASSERT(offsetof(SetTextureDataImmediate, slice_pitch) == 28, + OffsetOf_SetTextureDataImmediate_slice_pitch_not_28); +COMPILE_ASSERT(offsetof(SetTextureDataImmediate, size) == 32, + OffsetOf_SetTextureDataImmediate_size_not_32); + +struct GetTextureData { + typedef GetTextureData ValueType; + static const CommandId kCmdId = kGetTextureData; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + // argument 1 + typedef BitField<0, 16> X; + typedef BitField<16, 16> Y; + // argument 2 + typedef BitField<0, 16> Width; + typedef BitField<16, 16> Height; + // argument 3 + typedef BitField<0, 16> Z; + typedef BitField<16, 16> Depth; + // argument 4 + typedef BitField<0, 4> Level; + typedef BitField<4, 3> Face; + typedef BitField<7, 25> Unused; + + void SetHeader() { + header.SetCmd(); + } + + void Init( + ResourceId _texture_id, + uint32 _x, + uint32 _y, + uint32 _z, + uint32 _width, + uint32 _height, + uint32 _depth, + uint32 _level, + texture::Face _face, + uint32 _row_pitch, + uint32 _slice_pitch, + uint32 _size, + uint32 shared_memory_id, + uint32 shared_memory_offset) { + SetHeader(); + texture_id = _texture_id; + x_y = X::MakeValue(_x) | Y::MakeValue(_y); + width_height = Width::MakeValue(_width) | Height::MakeValue(_height); + z_depth = Z::MakeValue(_z) | Depth::MakeValue(_depth); + level_face = Level::MakeValue(_level) | Face::MakeValue(_face); + row_pitch = _row_pitch; + slice_pitch = _slice_pitch; + size = _size; + shared_memory.Init(shared_memory_id, shared_memory_offset); + } + + static void* Set( + void* cmd, + ResourceId texture_id, + uint32 x, + uint32 y, + uint32 z, + uint32 width, + uint32 height, + uint32 depth, + uint32 level, + texture::Face face, + uint32 row_pitch, + uint32 slice_pitch, + uint32 size, + uint32 shared_memory_id, + uint32 shared_memory_offset) { + static_cast(cmd)->Init( + texture_id, + x, + y, + z, + width, + height, + depth, + level, + face, + row_pitch, + slice_pitch, + size, + shared_memory_id, + shared_memory_offset); + return NextCmdAddress(cmd); + } + + // TODO(gman): fix this to not use obfusticated fields. + CommandHeader header; + ResourceId texture_id; + uint32 x_y; + uint32 width_height; + uint32 z_depth; + uint32 level_face; + uint32 row_pitch; + uint32 slice_pitch; + uint32 size; + SharedMemory shared_memory; +}; + +COMPILE_ASSERT(sizeof(GetTextureData) == 44, + Sizeof_GetTextureData_is_not_44); +COMPILE_ASSERT(offsetof(GetTextureData, header) == 0, + OffsetOf_GetTextureData_header_not_0); +COMPILE_ASSERT(offsetof(GetTextureData, texture_id) == 4, + OffsetOf_GetTextureData_texture_id_not_4); +COMPILE_ASSERT(offsetof(GetTextureData, x_y) == 8, + OffsetOf_GetTextureData_x_y_not_8); +COMPILE_ASSERT(offsetof(GetTextureData, width_height) == 12, + OffsetOf_GetTextureData_width_height_not_12); +COMPILE_ASSERT(offsetof(GetTextureData, z_depth) == 16, + OffsetOf_GetTextureData_z_depth_not_16); +COMPILE_ASSERT(offsetof(GetTextureData, level_face) == 20, + OffsetOf_GetTextureData_level_face_not_20); +COMPILE_ASSERT(offsetof(GetTextureData, row_pitch) == 24, + OffsetOf_GetTextureData_row_pitch_not_24); +COMPILE_ASSERT(offsetof(GetTextureData, slice_pitch) == 28, + OffsetOf_GetTextureData_slice_pitch_not_28); +COMPILE_ASSERT(offsetof(GetTextureData, size) == 32, + OffsetOf_GetTextureData_size_not_32); +COMPILE_ASSERT(offsetof(GetTextureData, shared_memory) == 36, + OffsetOf_GetTextureData_shared_memory_not_36); + +struct CreateSampler { + typedef CreateSampler ValueType; + static const CommandId kCmdId = kCreateSampler; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _sampler_id) { + SetHeader(); + sampler_id = _sampler_id; + } + + static void* Set(void* cmd, ResourceId sampler_id) { + static_cast(cmd)->Init(sampler_id); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId sampler_id; +}; + +COMPILE_ASSERT(sizeof(CreateSampler) == 8, Sizeof_CreateSampler_is_not_8); +COMPILE_ASSERT(offsetof(CreateSampler, header) == 0, + OffsetOf_CreateSampler_header_not_0); +COMPILE_ASSERT(offsetof(CreateSampler, sampler_id) == 4, + OffsetOf_CreateSampler_sampler_id_not_4); + +struct DestroySampler { + typedef DestroySampler ValueType; + static const CommandId kCmdId = kDestroySampler; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _sampler_id) { + SetHeader(); + sampler_id = _sampler_id; + } + + static void* Set(void* cmd, ResourceId sampler_id) { + static_cast(cmd)->Init(sampler_id); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId sampler_id; +}; + +COMPILE_ASSERT(sizeof(DestroySampler) == 8, Sizeof_DestroySampler_is_not_8); +COMPILE_ASSERT(offsetof(DestroySampler, header) == 0, + OffsetOf_DestroySampler_header_not_0); +COMPILE_ASSERT(offsetof(DestroySampler, sampler_id) == 4, + OffsetOf_DestroySampler_sampler_id_not_4); + +struct SetSamplerStates { + typedef SetSamplerStates ValueType; + static const CommandId kCmdId = kSetSamplerStates; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + // argument 2 + typedef BitField<0, 3> AddressingU; + typedef BitField<3, 3> AddressingV; + typedef BitField<6, 3> AddressingW; + typedef BitField<9, 3> MagFilter; + typedef BitField<12, 3> MinFilter; + typedef BitField<15, 3> MipFilter; + typedef BitField<18, 6> Unused; + typedef BitField<24, 8> MaxAnisotropy; + + void SetHeader() { + header.SetCmd(); + } + + void Init( + ResourceId _sampler_id, + sampler::AddressingMode _address_u_value, + sampler::AddressingMode _address_v_value, + sampler::AddressingMode _address_w_value, + sampler::FilteringMode _mag_filter_value, + sampler::FilteringMode _min_filter_value, + sampler::FilteringMode _mip_filter_value, + uint8 _max_anisotropy) { + SetHeader(); + sampler_id = _sampler_id; + sampler_states = + AddressingU::MakeValue(_address_u_value) | + AddressingV::MakeValue(_address_v_value) | + AddressingW::MakeValue(_address_w_value) | + MagFilter::MakeValue(_mag_filter_value) | + MinFilter::MakeValue(_min_filter_value) | + MipFilter::MakeValue(_mip_filter_value) | + MaxAnisotropy::MakeValue(_max_anisotropy); + } + + static void* Set(void* cmd, + ResourceId sampler_id, + sampler::AddressingMode address_u_value, + sampler::AddressingMode address_v_value, + sampler::AddressingMode address_w_value, + sampler::FilteringMode mag_filter_value, + sampler::FilteringMode min_filter_value, + sampler::FilteringMode mip_filter_value, + uint8 max_anisotropy) { + static_cast(cmd)->Init( + sampler_id, + address_u_value, + address_v_value, + address_w_value, + mag_filter_value, + min_filter_value, + mip_filter_value, + max_anisotropy); + return NextCmdAddress(cmd); + } + + // TODO(gman): fix this to not use obfusticated fields. + CommandHeader header; + ResourceId sampler_id; + uint32 sampler_states; +}; + +COMPILE_ASSERT(sizeof(SetSamplerStates) == 12, + Sizeof_SetSamplerStates_is_not_12); +COMPILE_ASSERT(offsetof(SetSamplerStates, header) == 0, + OffsetOf_SetSamplerStates_header_not_0); +COMPILE_ASSERT(offsetof(SetSamplerStates, sampler_id) == 4, + OffsetOf_SetSamplerStates_sampler_id_not_4); +COMPILE_ASSERT(offsetof(SetSamplerStates, sampler_states) == 8, + OffsetOf_SetSamplerStates_sampler_states_not_8); + +struct SetSamplerBorderColor { + typedef SetSamplerBorderColor ValueType; + static const CommandId kCmdId = kSetSamplerBorderColor; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _sampler_id, + float _red, float _green, float _blue, float _alpha) { + SetHeader(); + sampler_id = _sampler_id; + red = _red; + green = _green; + blue = _blue; + alpha = _alpha; + } + + static void* Set(void* cmd, ResourceId sampler_id, + float red, float green, float blue, float alpha) { + static_cast(cmd)->Init(sampler_id, red, green, blue, alpha); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId sampler_id; + float red; + float blue; + float green; + float alpha; +}; + +COMPILE_ASSERT(sizeof(SetSamplerBorderColor) == 24, + Sizeof_SetSamplerBorderColor_is_not_24); +COMPILE_ASSERT(offsetof(SetSamplerBorderColor, header) == 0, + OffsetOf_SetSamplerBorderColor_header_not_0); +COMPILE_ASSERT(offsetof(SetSamplerBorderColor, sampler_id) == 4, + OffsetOf_SetSamplerBorderColor_sampler_id_not_4); +COMPILE_ASSERT(offsetof(SetSamplerBorderColor, red) == 8, + OffsetOf_SetSamplerBorderColor_red_not_8); +COMPILE_ASSERT(offsetof(SetSamplerBorderColor, blue) == 12, + OffsetOf_SetSamplerBorderColor_blue_not_12); +COMPILE_ASSERT(offsetof(SetSamplerBorderColor, green) == 16, + OffsetOf_SetSamplerBorderColor_green_not_16); +COMPILE_ASSERT(offsetof(SetSamplerBorderColor, alpha) == 20, + OffsetOf_SetSamplerBorderColor_alpha_not_20); + +struct SetSamplerTexture { + typedef SetSamplerTexture ValueType; + static const CommandId kCmdId = kSetSamplerTexture; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _sampler_id, ResourceId _texture_id) { + SetHeader(); + sampler_id = _sampler_id; + texture_id = _texture_id; + } + + static void* Set(void* cmd, ResourceId sampler_id, ResourceId texture_id) { + static_cast(cmd)->Init(sampler_id, texture_id); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId sampler_id; + ResourceId texture_id; +}; + +COMPILE_ASSERT(sizeof(SetSamplerTexture) == 12, + Sizeof_SetSamplerTexture_is_not_12); +COMPILE_ASSERT(offsetof(SetSamplerTexture, header) == 0, + OffsetOf_SetSamplerTexture_header_not_0); +COMPILE_ASSERT(offsetof(SetSamplerTexture, sampler_id) == 4, + OffsetOf_SetSamplerTexture_sampler_id_not_4); +COMPILE_ASSERT(offsetof(SetSamplerTexture, texture_id) == 8, + OffsetOf_SetSamplerTexture_texture_id_not_8); + +struct SetScissor { + typedef SetScissor ValueType; + static const CommandId kCmdId = kSetScissor; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + // argument 0 + typedef BitField<0, 15> X; + typedef BitField<15, 1> Unused; + typedef BitField<16, 15> Y; + typedef BitField<31, 1> Enable; + // argument 1 + typedef BitField<0, 16> Width; + typedef BitField<16, 16> Height; + + void SetHeader() { + header.SetCmd(); + } + + void Init(uint32 _x, + uint32 _y, + uint32 _width, + uint32 _height, + bool _enable) { + SetHeader(); + x_y_enable = + X::MakeValue(_x) | + Y::MakeValue(_y) | + Enable::MakeValue(_enable ? 1 : 0); + width_height = Width::MakeValue(_width) | Height::MakeValue(_height); + } + + static void* Set( + void* cmd, + uint32 x, + uint32 y, + uint32 width, + uint32 height, + bool enable) { + static_cast(cmd)->Init( + x, + y, + width, + height, + enable); + return NextCmdAddress(cmd); + } + + // TODO(gman): fix this to not use obfusticated fields. + CommandHeader header; + uint32 x_y_enable; + uint32 width_height; +}; + +COMPILE_ASSERT(sizeof(SetScissor) == 12, Sizeof_SetScissor_is_not_12); +COMPILE_ASSERT(offsetof(SetScissor, header) == 0, + OffsetOf_SetScissor_header_not_0); +COMPILE_ASSERT(offsetof(SetScissor, x_y_enable) == 4, + OffsetOf_SetScissor_x_y_enable_not_4); +COMPILE_ASSERT(offsetof(SetScissor, width_height) == 8, + OffsetOf_SetScissor_width_height_not_8); + +struct SetPolygonOffset { + typedef SetPolygonOffset ValueType; + static const CommandId kCmdId = kSetPolygonOffset; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(float _slope_factor, float _units) { + SetHeader(); + slope_factor = _slope_factor; + units = _units; + } + + static void* Set(void* cmd, float slope_factor, float units) { + static_cast(cmd)->Init(slope_factor, units); + return NextCmdAddress(cmd); + } + + CommandHeader header; + float slope_factor; + float units; +}; + +COMPILE_ASSERT(sizeof(SetPolygonOffset) == 12, + Sizeof_SetPolygonOffset_is_not_12); +COMPILE_ASSERT(offsetof(SetPolygonOffset, header) == 0, + OffsetOf_SetPolygonOffset_header_not_0); +COMPILE_ASSERT(offsetof(SetPolygonOffset, slope_factor) == 4, + OffsetOf_SetPolygonOffset_slope_factor_not_4); +COMPILE_ASSERT(offsetof(SetPolygonOffset, units) == 8, + OffsetOf_SetPolygonOffset_units_not_8); + +struct SetPointLineRaster { + typedef SetPointLineRaster ValueType; + static const CommandId kCmdId = kSetPointLineRaster; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + // argument 0 + typedef BitField<0, 1> LineSmoothEnable; + typedef BitField<1, 1> PointSpriteEnable; + typedef BitField<2, 30> Unused; + + void SetHeader() { + header.SetCmd(); + } + + void Init(bool _line_smooth_enable, bool _point_sprite_enable, + float _point_size) { + SetHeader(); + enables = + LineSmoothEnable::MakeValue(_line_smooth_enable ? 1 : 0) | + PointSpriteEnable::MakeValue(_point_sprite_enable ? 1 : 0); + point_size = _point_size; + } + + static void* Set(void* cmd, bool line_smooth_enable, bool point_sprite_enable, + float point_size) { + static_cast(cmd)->Init(line_smooth_enable, point_sprite_enable, + point_size); + return NextCmdAddress(cmd); + } + + // TODO(gman): fix this to not use obfusticated fields. + CommandHeader header; + uint32 enables; + float point_size; +}; + +COMPILE_ASSERT(sizeof(SetPointLineRaster) == 12, + Sizeof_SetPointLineRaster_is_not_12); +COMPILE_ASSERT(offsetof(SetPointLineRaster, header) == 0, + OffsetOf_SetPointLineRaster_header_not_0); +COMPILE_ASSERT(offsetof(SetPointLineRaster, enables) == 4, + OffsetOf_SetPointLineRaster_enables_not_4); +COMPILE_ASSERT(offsetof(SetPointLineRaster, point_size) == 8, + OffsetOf_SetPointLineRaster_point_size_not_8); + +struct SetPolygonRaster { + typedef SetPolygonRaster ValueType; + static const CommandId kCmdId = kSetPolygonRaster; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + // argument 0 + typedef BitField<0, 2> FillMode; + typedef BitField<2, 2> CullMode; + typedef BitField<4, 28> Unused; + + void SetHeader() { + header.SetCmd(); + } + + void Init(PolygonMode _fill_mode, FaceCullMode _cull_mode) { + SetHeader(); + fill_cull = FillMode::MakeValue(_fill_mode) | + CullMode::MakeValue(_cull_mode); + } + + static void* Set(void* cmd, PolygonMode fill_mode, FaceCullMode cull_mode) { + static_cast(cmd)->Init(fill_mode, cull_mode); + return NextCmdAddress(cmd); + } + + // TODO(gman): fix this to not use obfusticated fields. + CommandHeader header; + uint32 fill_cull; +}; + +COMPILE_ASSERT(sizeof(SetPolygonRaster) == 8, + Sizeof_SetPolygonRaster_is_not_8); +COMPILE_ASSERT(offsetof(SetPolygonRaster, header) == 0, + OffsetOf_SetPolygonRaster_header_not_0); +COMPILE_ASSERT(offsetof(SetPolygonRaster, fill_cull) == 4, + OffsetOf_SetPolygonRaster_fill_cull_not_4); + +struct SetAlphaTest { + typedef SetAlphaTest ValueType; + static const CommandId kCmdId = kSetAlphaTest; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + // argument 0 + typedef BitField<0, 3> Func; + typedef BitField<3, 28> Unused; + typedef BitField<31, 1> Enable; + + void SetHeader() { + header.SetCmd(); + } + + void Init(Comparison _func, bool _enable, float _value) { + SetHeader(); + func_enable = Func::MakeValue(_func) | Enable::MakeValue(_enable ? 1 : 0); + value = _value; + } + + static void* Set(void* cmd, Comparison func, bool enable, float value) { + static_cast(cmd)->Init(func, enable, value); + return NextCmdAddress(cmd); + } + + // TODO(gman): fix this to not use obfusticated fields. + CommandHeader header; + uint32 func_enable; + float value; +}; + +COMPILE_ASSERT(sizeof(SetAlphaTest) == 12, Sizeof_SetAlphaTest_is_not_12); +COMPILE_ASSERT(offsetof(SetAlphaTest, header) == 0, + OffsetOf_SetAlphaTest_header_not_0); +COMPILE_ASSERT(offsetof(SetAlphaTest, func_enable) == 4, + OffsetOf_SetAlphaTest_func_enable_not_4); +COMPILE_ASSERT(offsetof(SetAlphaTest, value) == 8, + OffsetOf_SetAlphaTest_value_not_8); + +struct SetDepthTest { + typedef SetDepthTest ValueType; + static const CommandId kCmdId = kSetDepthTest; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + // argument 0 + typedef BitField<0, 3> Func; + typedef BitField<3, 27> Unused; + typedef BitField<30, 1> WriteEnable; + typedef BitField<31, 1> Enable; + + void SetHeader() { + header.SetCmd(); + } + + void Init(Comparison _func, bool _write_enable, bool _enable) { + SetHeader(); + func_enable = + Func::MakeValue(_func) | + WriteEnable::MakeValue(_write_enable ? 1 : 0) | + Enable::MakeValue(_enable ? 1 : 0); + } + + static void* Set(void* cmd, + Comparison func, bool write_enable, bool enable) { + static_cast(cmd)->Init(func, write_enable, enable); + return NextCmdAddress(cmd); + } + + // TODO(gman): fix this to not use obfusticated fields. + CommandHeader header; + uint32 func_enable; +}; + +COMPILE_ASSERT(sizeof(SetDepthTest) == 8, Sizeof_SetDepthTest_is_not_8); +COMPILE_ASSERT(offsetof(SetDepthTest, header) == 0, + OffsetOf_SetDepthTest_header_not_0); +COMPILE_ASSERT(offsetof(SetDepthTest, func_enable) == 4, + OffsetOf_SetDepthTest_func_enable_not_4); + +struct SetStencilTest { + typedef SetStencilTest ValueType; + static const CommandId kCmdId = kSetStencilTest; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + // argument 0 + typedef BitField<0, 8> WriteMask; + typedef BitField<8, 8> CompareMask; + typedef BitField<16, 8> ReferenceValue; + typedef BitField<24, 6> Unused0; + typedef BitField<30, 1> SeparateCCW; + typedef BitField<31, 1> Enable; + // argument 1 + typedef BitField<0, 3> CWFunc; + typedef BitField<3, 3> CWPassOp; + typedef BitField<6, 3> CWFailOp; + typedef BitField<9, 3> CWZFailOp; + typedef BitField<12, 4> Unused1; + typedef BitField<16, 3> CCWFunc; + typedef BitField<19, 3> CCWPassOp; + typedef BitField<22, 3> CCWFailOp; + typedef BitField<25, 3> CCWZFailOp; + typedef BitField<28, 4> Unused2; + + void SetHeader() { + header.SetCmd(); + } + + void Init(uint8 _write_mask, + uint8 _compare_mask, + uint8 _reference_value, + bool _separate_ccw, + bool _enable, + Comparison _cw_func, + StencilOp _cw_pass_op, + StencilOp _cw_fail_op, + StencilOp _cw_z_fail_op, + Comparison _ccw_func, + StencilOp _ccw_pass_op, + StencilOp _ccw_fail_op, + StencilOp _ccw_z_fail_op) { + SetHeader(); + stencil_args0 = + WriteMask::MakeValue(_write_mask) | + CompareMask::MakeValue(_compare_mask) | + ReferenceValue::MakeValue(_reference_value) | + SeparateCCW::MakeValue(_separate_ccw ? 1 : 0) | + Enable::MakeValue(_enable ? 1 : 0); + stencil_args1 = + CWFunc::MakeValue(_cw_func) | + CWPassOp::MakeValue(_cw_pass_op) | + CWFailOp::MakeValue(_cw_fail_op) | + CWZFailOp::MakeValue(_cw_z_fail_op) | + CCWFunc::MakeValue(_ccw_func) | + CCWPassOp::MakeValue(_ccw_pass_op) | + CCWFailOp::MakeValue(_ccw_fail_op) | + CCWZFailOp::MakeValue(_ccw_z_fail_op); + } + + static void* Set( + void* cmd, + uint8 write_mask, + uint8 compare_mask, + uint8 reference_value, + bool separate_ccw, + bool enable, + Comparison cw_func, + StencilOp cw_pass_op, + StencilOp cw_fail_op, + StencilOp cw_z_fail_op, + Comparison ccw_func, + StencilOp ccw_pass_op, + StencilOp ccw_fail_op, + StencilOp ccw_z_fail_op) { + static_cast(cmd)->Init( + write_mask, + compare_mask, + reference_value, + separate_ccw, + enable, + cw_func, + cw_pass_op, + cw_fail_op, + cw_z_fail_op, + ccw_func, + ccw_pass_op, + ccw_fail_op, + ccw_z_fail_op); + return NextCmdAddress(cmd); + } + + // TODO(gman): fix this to not use obfusticated fields. + CommandHeader header; + uint32 stencil_args0; + uint32 stencil_args1; +}; + +COMPILE_ASSERT(sizeof(SetStencilTest) == 12, + Sizeof_SetStencilTest_is_not_12); +COMPILE_ASSERT(offsetof(SetStencilTest, header) == 0, + OffsetOf_SetStencilTest_header_not_0); +COMPILE_ASSERT(offsetof(SetStencilTest, stencil_args0) == 4, + OffsetOf_SetStencilTest_stencil_args0_not_4); +COMPILE_ASSERT(offsetof(SetStencilTest, stencil_args1) == 8, + OffsetOf_SetStencilTest_stencil_args1_not_8); + +struct SetColorWrite { + typedef SetColorWrite ValueType; + static const CommandId kCmdId = kSetColorWrite; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + // argument 0 + typedef BitField<0, 1> RedMask; + typedef BitField<1, 1> GreenMask; + typedef BitField<2, 1> BlueMask; + typedef BitField<3, 1> AlphaMask; + typedef BitField<0, 4> AllColorsMask; // alias for RGBA + typedef BitField<4, 27> Unused; + typedef BitField<31, 1> DitherEnable; + + void SetHeader() { + header.SetCmd(); + } + + void Init(uint8 _mask, bool _dither_enable) { + SetHeader(); + flags = + RedMask::MakeValue((_mask | 0x01) != 0 ? 1 : 0) | + GreenMask::MakeValue((_mask | 0x02) != 0 ? 1 : 0) | + BlueMask::MakeValue((_mask | 0x02) != 0 ? 1 : 0) | + AlphaMask::MakeValue((_mask | 0x02) != 0 ? 1 : 0) | + DitherEnable::MakeValue(_dither_enable ? 1 : 0); + } + + static void* Set(void* cmd, uint8 mask, bool dither_enable) { + static_cast(cmd)->Init(mask, dither_enable); + return NextCmdAddress(cmd); + } + + CommandHeader header; + uint32 flags; +}; + +COMPILE_ASSERT(sizeof(SetColorWrite) == 8, Sizeof_SetColorWrite_is_not_8); +COMPILE_ASSERT(offsetof(SetColorWrite, header) == 0, + OffsetOf_SetColorWrite_header_not_0); +COMPILE_ASSERT(offsetof(SetColorWrite, flags) == 4, + OffsetOf_SetColorWrite_flags_not_4); + +struct SetBlending { + typedef SetBlending ValueType; + static const CommandId kCmdId = kSetBlending; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + // argument 0 + typedef BitField<0, 4> ColorSrcFunc; + typedef BitField<4, 4> ColorDstFunc; + typedef BitField<8, 3> ColorEq; + typedef BitField<11, 5> Unused0; + typedef BitField<16, 4> AlphaSrcFunc; + typedef BitField<20, 4> AlphaDstFunc; + typedef BitField<24, 3> AlphaEq; + typedef BitField<27, 3> Unused1; + typedef BitField<30, 1> SeparateAlpha; + typedef BitField<31, 1> Enable; + + void SetHeader() { + header.SetCmd(); + } + + void Init( + BlendFunc _color_src_func, + BlendFunc _color_dst_func, + BlendEq _color_eq, + BlendFunc _alpha_src_func, + BlendFunc _alpha_dst_func, + BlendEq _alpha_eq, + bool _separate_alpha, + bool _enable) { + SetHeader(); + blend_settings = + ColorSrcFunc::MakeValue(_color_src_func) | + ColorDstFunc::MakeValue(_color_dst_func) | + ColorEq::MakeValue(_color_eq) | + AlphaSrcFunc::MakeValue(_alpha_src_func) | + AlphaDstFunc::MakeValue(_alpha_dst_func) | + AlphaEq::MakeValue(_alpha_eq) | + SeparateAlpha::MakeValue(_separate_alpha ? 1 : 0) | + Enable::MakeValue(_enable ? 1 : 0); + } + + static void* Set( + void* cmd, + BlendFunc color_src_func, + BlendFunc color_dst_func, + BlendEq color_eq, + BlendFunc alpha_src_func, + BlendFunc alpha_dst_func, + BlendEq alpha_eq, + bool separate_alpha, + bool enable) { + static_cast(cmd)->Init( + color_src_func, + color_dst_func, + color_eq, + alpha_src_func, + alpha_dst_func, + alpha_eq, + separate_alpha, + enable); + return NextCmdAddress(cmd); + } + + // TODO(gman): fix this to not use obfusticated fields. + CommandHeader header; + uint32 blend_settings; +}; + +COMPILE_ASSERT(sizeof(SetBlending) == 8, Sizeof_SetBlending_is_not_8); +COMPILE_ASSERT(offsetof(SetBlending, header) == 0, + OffsetOf_SetBlending_header_not_0); +COMPILE_ASSERT(offsetof(SetBlending, blend_settings) == 4, + OffsetOf_SetBlending_blend_settings_not_4); + +struct SetBlendingColor { + typedef SetBlendingColor ValueType; + static const CommandId kCmdId = kSetBlendingColor; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(float _red, float _green, float _blue, float _alpha) { + SetHeader(); + red = _red; + green = _green; + blue = _blue; + alpha = _alpha; + } + + static void* Set(void* cmd, + float red, float green, float blue, float alpha) { + static_cast(cmd)->Init(red, green, blue, alpha); + return NextCmdAddress(cmd); + } + + CommandHeader header; + float red; + float blue; + float green; + float alpha; +}; + +COMPILE_ASSERT(sizeof(SetBlendingColor) == 20, + Sizeof_SetBlendingColor_is_not_20); +COMPILE_ASSERT(offsetof(SetBlendingColor, header) == 0, + OffsetOf_SetBlendingColor_header_not_0); +COMPILE_ASSERT(offsetof(SetBlendingColor, red) == 4, + OffsetOf_SetBlendingColor_red_not_4); +COMPILE_ASSERT(offsetof(SetBlendingColor, blue) == 8, + OffsetOf_SetBlendingColor_blue_not_8); +COMPILE_ASSERT(offsetof(SetBlendingColor, green) == 12, + OffsetOf_SetBlendingColor_green_not_12); +COMPILE_ASSERT(offsetof(SetBlendingColor, alpha) == 16, + OffsetOf_SetBlendingColor_alpha_not_16); + +struct CreateRenderSurface { + typedef CreateRenderSurface ValueType; + static const CommandId kCmdId = kCreateRenderSurface; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + // argument 1 + typedef BitField<0, 16> Width; + typedef BitField<16, 16> Height; + // argument 2 may refer to side or depth + typedef BitField<0, 16> Levels; + typedef BitField<16, 16> Side; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _render_surface_id, + ResourceId _texture_id, uint32 _width, uint32 _height, + uint32 _level, uint32 _side) { + SetHeader(); + render_surface_id = _render_surface_id; + // TODO(gman): Why does this need a width and height. It's inherited from + // the texture isn't it? + width_height = Width::MakeValue(_width) | Height::MakeValue(_height); + levels_side = Levels::MakeValue(_level) | Side::MakeValue(_side); + texture_id = _texture_id; + } + + static void* Set(void* cmd, + ResourceId render_surface_id, ResourceId texture_id, + uint32 width, uint32 height, + uint32 level, uint32 side) { + static_cast(cmd)->Init(render_surface_id, texture_id, + width, height, + level, side); + return NextCmdAddress(cmd); + } + + // TODO(gman): fix this to not use obfusticated fields. + CommandHeader header; + ResourceId render_surface_id; + uint32 width_height; + uint32 levels_side; + ResourceId texture_id; +}; + +COMPILE_ASSERT(sizeof(CreateRenderSurface) == 20, + Sizeof_CreateRenderSurface_is_not_20); +COMPILE_ASSERT(offsetof(CreateRenderSurface, header) == 0, + OffsetOf_CreateRenderSurface_header_not_0); +COMPILE_ASSERT(offsetof(CreateRenderSurface, render_surface_id) == 4, + OffsetOf_CreateRenderSurface_render_surface_id_not_4); +COMPILE_ASSERT(offsetof(CreateRenderSurface, width_height) == 8, + OffsetOf_CreateRenderSurface_width_height_not_8); +COMPILE_ASSERT(offsetof(CreateRenderSurface, levels_side) == 12, + OffsetOf_CreateRenderSurface_levels_side_not_12); +COMPILE_ASSERT(offsetof(CreateRenderSurface, texture_id) == 16, + OffsetOf_CreateRenderSurface_texture_id_not_16); + +struct DestroyRenderSurface { + typedef DestroyRenderSurface ValueType; + static const CommandId kCmdId = kDestroyRenderSurface; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _render_surface_id) { + SetHeader(); + render_surface_id = _render_surface_id; + } + + static void* Set(void* cmd, ResourceId render_surface_id) { + static_cast(cmd)->Init(render_surface_id); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId render_surface_id; +}; + +COMPILE_ASSERT(sizeof(DestroyRenderSurface) == 8, + Sizeof_DestroyRenderSurface_is_not_8); +COMPILE_ASSERT(offsetof(DestroyRenderSurface, header) == 0, + OffsetOf_DestroyRenderSurface_header_not_0); +COMPILE_ASSERT(offsetof(DestroyRenderSurface, render_surface_id) == 4, + OffsetOf_DestroyRenderSurface_render_surface_id_not_4); + +struct CreateDepthSurface { + typedef CreateDepthSurface ValueType; + static const CommandId kCmdId = kCreateDepthSurface; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + // argument 1 + typedef BitField<0, 16> Width; + typedef BitField<16, 16> Height; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _depth_surface_id, uint32 _width, uint32 _height) { + SetHeader(); + depth_surface_id = _depth_surface_id; + width_height = Width::MakeValue(_width) | Height::MakeValue(_height); + } + + static void* Set(void* cmd, ResourceId depth_surface_id, + uint32 width, uint32 height) { + static_cast(cmd)->Init(depth_surface_id, width, height); + return NextCmdAddress(cmd); + } + + // TODO(gman): fix this to not use obfusticated fields. + CommandHeader header; + ResourceId depth_surface_id; + uint32 width_height; +}; + +COMPILE_ASSERT(sizeof(CreateDepthSurface) == 12, + Sizeof_CreateDepthSurface_is_not_12); +COMPILE_ASSERT(offsetof(CreateDepthSurface, header) == 0, + OffsetOf_CreateDepthSurface_header_not_0); +COMPILE_ASSERT(offsetof(CreateDepthSurface, depth_surface_id) == 4, + OffsetOf_CreateDepthSurface_depth_surface_id_not_4); +COMPILE_ASSERT(offsetof(CreateDepthSurface, width_height) == 8, + OffsetOf_CreateDepthSurface_width_height_not_8); + +struct DestroyDepthSurface { + typedef DestroyDepthSurface ValueType; + static const CommandId kCmdId = kDestroyDepthSurface; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _depth_surface_id) { + SetHeader(); + depth_surface_id = _depth_surface_id; + } + + static void* Set(void* cmd, ResourceId depth_surface_id) { + static_cast(cmd)->Init(depth_surface_id); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId depth_surface_id; +}; + +COMPILE_ASSERT(sizeof(DestroyDepthSurface) == 8, + Sizeof_DestroyDepthSurface_is_not_8); +COMPILE_ASSERT(offsetof(DestroyDepthSurface, header) == 0, + OffsetOf_DestroyDepthSurface_header_not_0); +COMPILE_ASSERT(offsetof(DestroyDepthSurface, depth_surface_id) == 4, + OffsetOf_DestroyDepthdepth_surface_id_not_4); + +struct SetRenderSurface { + typedef SetRenderSurface ValueType; + static const CommandId kCmdId = kSetRenderSurface; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init(ResourceId _render_surface_id, ResourceId _depth_surface_id) { + SetHeader(); + render_surface_id = _render_surface_id; + depth_surface_id = _depth_surface_id; + } + + static void* Set(void* cmd, + ResourceId render_surface_id, ResourceId depth_surface_id) { + static_cast(cmd)->Init(render_surface_id, depth_surface_id); + return NextCmdAddress(cmd); + } + + CommandHeader header; + ResourceId render_surface_id; + ResourceId depth_surface_id; +}; + +COMPILE_ASSERT(sizeof(SetRenderSurface) == 12, + Sizeof_SetRenderSurface_is_not_12); +COMPILE_ASSERT(offsetof(SetRenderSurface, header) == 0, + OffsetOf_SetRenderSurface_header_not_0); +COMPILE_ASSERT(offsetof(SetRenderSurface, render_surface_id) == 4, + OffsetOf_SetRenderSurface_render_surface_id_not_4); +COMPILE_ASSERT(offsetof(SetRenderSurface, depth_surface_id) == 8, + OffsetOf_SetRenderSurface_depth_surface_id_not_8); + +struct SetBackSurfaces { + typedef SetBackSurfaces ValueType; + static const CommandId kCmdId = kSetBackSurfaces; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd(); + } + + void Init() { + SetHeader(); + } + + static void* Set(void* cmd) { + static_cast(cmd)->Init(); + return NextCmdAddress(cmd); + } + + CommandHeader header; +}; + +COMPILE_ASSERT(sizeof(SetBackSurfaces) == 4, + Sizeof_SetBackSurfaces_is_not_4); +COMPILE_ASSERT(offsetof(SetBackSurfaces, header) == 0, + OffsetOf_SetBackSurfaces_header_not_0); + +#pragma pack(pop) + +} // namespace o3d +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_COMMON_CROSS_CMD_BUFFER_FORMAT_H_ diff --git a/o3d/command_buffer/common/resource.cc b/o3d/command_buffer/common/resource.cc new file mode 100644 index 0000000..08a5957 --- /dev/null +++ b/o3d/command_buffer/common/resource.cc @@ -0,0 +1,120 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the implementation of the helper functions for resources. + +#include "command_buffer/common/resource.h" + +namespace command_buffer { + +namespace texture { + +// Gets the number of bytes per block for a given format. +unsigned int GetBytesPerBlock(Format format) { + switch (format) { + case kXRGB8: + case kARGB8: + case kR32F: + return 4; + case kABGR16F: + return 8; + case kABGR32F: + return 16; + case kDXT1: + return 8; + default: + // TODO(petersont): Add DXT3/5 support. + LOG(FATAL) << "Invalid format"; + return 1; + } +} + +// Gets the width of a block for a given format. +unsigned int GetBlockSizeX(Format format) { + switch (format) { + case kXRGB8: + case kARGB8: + case kABGR16F: + case kR32F: + case kABGR32F: + return 1; + case kDXT1: + return 4; + default: + // TODO(petersont): Add DXT3/5 support. + LOG(FATAL) << "Invalid format"; + return 1; + } +} + +// Gets the height of a block for a given format. +unsigned int GetBlockSizeY(Format format) { + // NOTE: currently only supported formats use square blocks. + return GetBlockSizeX(format); +} + +} // namespace texture + +namespace effect_param { + +// Gets the size of the data of a given parameter type. +unsigned int GetDataSize(DataType type) { + switch (type) { + case kUnknown: + return 0; + case kFloat1: + return sizeof(float); // NOLINT + case kFloat2: + return sizeof(float) * 2; // NOLINT + case kFloat3: + return sizeof(float) * 3; // NOLINT + case kFloat4: + return sizeof(float) * 4; // NOLINT + case kMatrix4: + return sizeof(float) * 16; // NOLINT + case kInt: + return sizeof(int); // NOLINT + case kBool: + return sizeof(bool); // NOLINT + case kSampler: + return sizeof(ResourceId); // NOLINT + case kTexture: + return sizeof(ResourceId); // NOLINT + default: + LOG(FATAL) << "Invalid type."; + return 0; + } +} + +} // namespace effect_param + +} // namespace command_buffer diff --git a/o3d/command_buffer/common/resource.h b/o3d/command_buffer/common/resource.h new file mode 100644 index 0000000..851198b --- /dev/null +++ b/o3d/command_buffer/common/resource.h @@ -0,0 +1,229 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains definitions for resource flags, enums, and helper +// functions. + +#ifndef GPU_COMMAND_BUFFER_COMMON_CROSS_RESOURCE_H_ +#define GPU_COMMAND_BUFFER_COMMON_CROSS_RESOURCE_H_ + +#include +#include "base/basictypes.h" +#include "base/scoped_ptr.h" +#include "command_buffer/common/types.h" +#include "command_buffer/common/logging.h" + +namespace command_buffer { + +// A resource ID, key to the resource maps. +typedef uint32 ResourceId; +// Invalid resource ID. +static const ResourceId kInvalidResource = 0xffffffffU; + +namespace vertex_buffer { +// Vertex buffer flags. +enum Flags { + kNone = 0x00, + kDynamic = 0x01, // This vertex buffer is dynamic and is expected to have + // its data updated often. +}; +} // namespace vertex_buffer + +namespace index_buffer { +// Index buffer flags. +enum Flags { + kNone = 0x00, + kDynamic = 0x01, // This index buffer is dynamic and is expected to have + // its data updated often. + kIndex32Bit = 0x02, // Indices contained in this index buffer are 32 bits + // (unsigned int) instead of 16 bit (unsigned short). +}; +} // namespace index_buffer + +namespace vertex_struct { +// Semantics for input data. +enum Semantic { + kUnknownSemantic = -1, + kPosition = 0, + kNormal, + kColor, + kTexCoord, + kNumSemantics +}; + +// Input data types. +enum Type { + kFloat1, + kFloat2, + kFloat3, + kFloat4, + kUChar4N, + kNumTypes +}; +} // namespace vertex_struct + +namespace effect_param { +enum DataType { + kUnknown, // A parameter exists in the effect, but the type is not + // representable (e.g. MATRIX3x4). + kFloat1, + kFloat2, + kFloat3, + kFloat4, + kMatrix4, + kInt, + kBool, + kSampler, + kTexture, + kNumTypes, + kMake32Bit = 0x7fffffff, +}; +COMPILE_ASSERT(sizeof(DataType) == 4, DataType_should_be_32_bits); + +// Gets the size of the data of a particular type. +unsigned int GetDataSize(DataType type); + +// Structure describing a parameter, filled in by the +// GAPIInterface::GetParamDesc call. +struct Desc { + Uint32 size; // the total memory size needed for the complete + // description. + Uint32 name_offset; // the offset of the parameter name, relative to + // the beginning of the structure. May be 0 if the + // name doesn't fit into the memory buffer. + Uint32 name_size; // the size of the parameter name, including the + // terminating nul character. Will always be set + // even if the name doesn't fit into the buffer. + Uint32 semantic_offset; // the offset of the parameter semantic, relative + // to the beginning of the structure. May be 0 if + // the semantic doesn't fit into the memory + // buffer. + Uint32 semantic_size; // the size of the parameter semantic, including + // the terminating nul character. Will always be + // set even if the semantic doesn't fit into the + // buffer. + Uint32 num_elements; // the number of entries if the parameter is an array + // 0 otherwise. + DataType data_type; // the data type of the parameter. + Uint32 data_size; // the size of the parameter data, in bytes. +}; +} // namespace effect_param + +namespace effect_stream { +struct Desc { + Desc() + : semantic(vertex_struct::kUnknownSemantic), + semantic_index(0) {} + Desc(Uint32 semantic, Uint32 semantic_index) + : semantic(semantic), + semantic_index(semantic_index) {} + Uint32 semantic; // the semantic type + Uint32 semantic_index; +}; +} // namespace effect_stream + +namespace texture { +// Texture flags. +enum Flags { + kNone = 0x00, + kDynamic = 0x01, // This texture is dynamic and is expected to have + // its data updated often. +}; + +// Texel formats. +enum Format { + kUnknown, + kXRGB8, + kARGB8, + kABGR16F, + kR32F, + kABGR32F, + kDXT1 +}; + +// Texture type. +enum Type { + kTexture2d, + kTexture3d, + kTextureCube, +}; + +// Cube map face. +enum Face { + kFacePositiveX, + kFaceNegativeX, + kFacePositiveY, + kFaceNegativeY, + kFacePositiveZ, + kFaceNegativeZ, + kFaceNone = kFacePositiveX, // For non-cube maps. +}; + +// Gets the number of bytes per block for a given texture format. For most +// texture formats, a block is 1x1 texels, but DXT* formats have 4x4 blocks. +unsigned int GetBytesPerBlock(Format format); +// Gets the x dimension of a texel block for a given texture format. For most +// texture formats, a block is 1x1 texels, but DXT* formats have 4x4 blocks. +unsigned int GetBlockSizeX(Format format); +// Gets the y dimension of a texel block for a given texture format. For most +// texture formats, a block is 1x1 texels, but DXT* formats have 4x4 blocks. +unsigned int GetBlockSizeY(Format format); +// Gets the dimension of a mipmap level given the dimension of the base +// level. Every mipmap level is half the size of the previous level, rounding +// down. +inline unsigned int GetMipMapDimension(unsigned int base, + unsigned int level) { + DCHECK_GT(base, 0U); + return std::max(1U, base >> level); +} +} // namespace texture + +namespace sampler { +enum AddressingMode { + kWrap, + kMirrorRepeat, + kClampToEdge, + kClampToBorder, + kNumAddressingMode +}; + +enum FilteringMode { + kNone, + kPoint, + kLinear, + kNumFilteringMode +}; +} // namespace sampler + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_COMMON_CROSS_RESOURCE_H_ diff --git a/o3d/command_buffer/common/types.h b/o3d/command_buffer/common/types.h new file mode 100644 index 0000000..daa01cb --- /dev/null +++ b/o3d/command_buffer/common/types.h @@ -0,0 +1,60 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains cross-platform basic type definitions + +#ifndef GPU_COMMAND_BUFFER_COMMON_CROSS_TYPES_H_ +#define GPU_COMMAND_BUFFER_COMMON_CROSS_TYPES_H_ + +#include +#if !defined(COMPILER_MSVC) +#include +#endif +#include + +namespace command_buffer { +#if defined(COMPILER_MSVC) +typedef short Int16; +typedef unsigned short Uint16; +typedef int Int32; +typedef unsigned int Uint32; +#else +typedef int16_t Int16; +typedef uint16_t Uint16; +typedef int32_t Int32; +typedef uint32_t Uint32; +#endif + +typedef std::string String; +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_COMMON_CROSS_TYPES_H_ diff --git a/o3d/command_buffer/service/big_test_main.cc b/o3d/command_buffer/service/big_test_main.cc new file mode 100644 index 0000000..656f908 --- /dev/null +++ b/o3d/command_buffer/service/big_test_main.cc @@ -0,0 +1,123 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the entry to the big test program, for linux. + +#include "command_buffer/service/cross/big_test_helpers.h" +#include "command_buffer/service/cross/gl/gapi_gl.h" +#include "command_buffer/service/linux/x_utils.h" + +namespace command_buffer { + +String *g_program_path = NULL; +GAPIInterface *g_gapi = NULL; + +bool ProcessSystemMessages() { + return true; +} + +} // namespace command_buffer + +using o3d::String; +using o3d::command_buffer::g_program_path; +using o3d::command_buffer::g_gapi; +using o3d::command_buffer::GAPIGL; +using o3d::command_buffer::XWindowWrapper; + + +// Creates a GL-compatible window of specified dimensions. +Window CreateWindow(Display *display, unsigned int width, unsigned int height) { + int attribs[] = { + GLX_RGBA, + GLX_DOUBLEBUFFER, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + None + }; + XVisualInfo *visualInfo = glXChooseVisual(display, + DefaultScreen(display), + attribs); + Window root_window = RootWindow(display, visualInfo->screen); + Colormap colorMap = XCreateColormap(display, root_window, visualInfo->visual, + AllocNone); + + XSetWindowAttributes windowAttributes; + windowAttributes.colormap = colorMap; + windowAttributes.border_pixel = 0; + windowAttributes.event_mask = StructureNotifyMask; + Window window = XCreateWindow(display, root_window, + 0, 0, width, height, 0, visualInfo->depth, + InputOutput, visualInfo->visual, + CWBorderPixel|CWColormap|CWEventMask, + &windowAttributes); + if (!window) return 0; + XMapWindow(display, window); + XSync(display, True); + return window; +} + +// Creates a window, initializes the GAPI instance. +int main(int argc, char *argv[]) { + String program_path = argv[0]; + + // Remove all characters starting with last '/'. + size_t backslash_pos = program_path.rfind('/'); + if (backslash_pos != String::npos) { + program_path.erase(backslash_pos); + } + g_program_path = &program_path; + + GAPIGL gl_gapi; + g_gapi = &gl_gapi; + + Display *display = XOpenDisplay(0); + if (!display) { + LOG(FATAL) << "Could not open the display."; + return 1; + } + + Window window = CreateWindow(display, 300, 300); + if (!window) { + LOG(FATAL) << "Could not create a window."; + return 1; + } + + XWindowWrapper wrapper(display, window); + gl_gapi.set_window_wrapper(&wrapper); + + int ret = big_test_main(argc, argv); + + g_gapi = NULL; + g_program_path = NULL; + return ret; +} diff --git a/o3d/command_buffer/service/cmd_buffer_engine.h b/o3d/command_buffer/service/cmd_buffer_engine.h new file mode 100644 index 0000000..74ad649 --- /dev/null +++ b/o3d/command_buffer/service/cmd_buffer_engine.h @@ -0,0 +1,70 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file defines the CommandBufferEngine class, providing the main loop for +// the service, exposing the RPC API, managing the command parser. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_CMD_BUFFER_ENGINE_H_ +#define GPU_COMMAND_BUFFER_SERVICE_CROSS_CMD_BUFFER_ENGINE_H_ + +#include "base/basictypes.h" + +namespace command_buffer { + +class CommandBufferEngine { + public: + CommandBufferEngine() { + } + + virtual ~CommandBufferEngine() { + } + + // Gets the base address of a registered shared memory buffer. + // Parameters: + // shm_id: the identifier for the shared memory buffer. + virtual void *GetSharedMemoryAddress(int32 shm_id) = 0; + + // Gets the size of a registered shared memory buffer. + // Parameters: + // shm_id: the identifier for the shared memory buffer. + virtual size_t GetSharedMemorySize(int32 shm_id) = 0; + + // Sets the token value. + virtual void set_token(int32 token) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(CommandBufferEngine); +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_CMD_BUFFER_ENGINE_H_ diff --git a/o3d/command_buffer/service/cmd_parser.cc b/o3d/command_buffer/service/cmd_parser.cc new file mode 100644 index 0000000..0108953 --- /dev/null +++ b/o3d/command_buffer/service/cmd_parser.cc @@ -0,0 +1,111 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the implementation of the command parser. + +#include "command_buffer/service/cmd_parser.h" +// TODO(gman): remove this so we can use this code for different formats. +#include "command_buffer/common/o3d_cmd_format.h" + +namespace command_buffer { + +CommandParser::CommandParser(void *shm_address, + size_t shm_size, + ptrdiff_t offset, + size_t size, + CommandBufferOffset start_get, + AsyncAPIInterface *handler) + : get_(start_get), + put_(start_get), + handler_(handler) { + // check proper alignments. + DCHECK_EQ(0, (reinterpret_cast(shm_address)) % 4); + DCHECK_EQ(0, offset % 4); + DCHECK_EQ(0u, size % 4); + // check that the command buffer fits into the memory buffer. + DCHECK_GE(shm_size, offset + size); + char * buffer_begin = static_cast(shm_address) + offset; + buffer_ = reinterpret_cast(buffer_begin); + entry_count_ = size / 4; +} + +// Process one command, reading the header from the command buffer, and +// forwarding the command index and the arguments to the handler. +// Note that: +// - validation needs to happen on a copy of the data (to avoid race +// conditions). This function only validates the header, leaving the arguments +// validation to the handler, so it can pass a reference to them. +// - get_ is modified *after* the command has been executed. +parse_error::ParseError CommandParser::ProcessCommand() { + CommandBufferOffset get = get_; + if (get == put_) return parse_error::kParseNoError; + + CommandHeader header = buffer_[get].value_header; + if (header.size == 0) { + DLOG(INFO) << "Error: zero sized command in command buffer"; + return parse_error::kParseInvalidSize; + } + + if (header.size + get > entry_count_) { + DLOG(INFO) << "Error: get offset out of bounds"; + return parse_error::kParseOutOfBounds; + } + + parse_error::ParseError result = handler_->DoCommand( + header.command, header.size - 1, buffer_ + get); + // TODO(gman): If you want to log errors this is the best place to catch them. + // It seems like we need an official way to turn on a debug mode and + // get these errors. + if (result != parse_error::kParseNoError) { + ReportError(header.command, result); + } + get_ = (get + header.size) % entry_count_; + return result; +} + +void CommandParser::ReportError(unsigned int command_id, + parse_error::ParseError result) { + DLOG(INFO) << "Error: " << result << " for Command " + << handler_->GetCommandName(command_id); +} + +// Processes all the commands, while the buffer is not empty. Stop if an error +// is encountered. +parse_error::ParseError CommandParser::ProcessAllCommands() { + while (!IsEmpty()) { + parse_error::ParseError error = ProcessCommand(); + if (error) return error; + } + return parse_error::kParseNoError; +} + +} // namespace command_buffer diff --git a/o3d/command_buffer/service/cmd_parser.h b/o3d/command_buffer/service/cmd_parser.h new file mode 100644 index 0000000..4147c78 --- /dev/null +++ b/o3d/command_buffer/service/cmd_parser.h @@ -0,0 +1,115 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the command parser class. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_CMD_PARSER_H_ +#define GPU_COMMAND_BUFFER_SERVICE_CROSS_CMD_PARSER_H_ + +#include "command_buffer/common/constants.h" +#include "command_buffer/common/cmd_buffer_common.h" + +namespace command_buffer { + +class AsyncAPIInterface; + +// Command parser class. This class parses commands from a shared memory +// buffer, to implement some asynchronous RPC mechanism. +class CommandParser { + public: + CommandParser(void *shm_address, + size_t shm_size, + ptrdiff_t offset, + size_t size, + CommandBufferOffset start_get, + AsyncAPIInterface *handler); + + // Gets the "get" pointer. The get pointer is an index into the command + // buffer considered as an array of CommandBufferEntry. + CommandBufferOffset get() const { return get_; } + + // Sets the "put" pointer. The put pointer is an index into the command + // buffer considered as an array of CommandBufferEntry. + void set_put(CommandBufferOffset put) { put_ = put; } + + // Gets the "put" pointer. The put pointer is an index into the command + // buffer considered as an array of CommandBufferEntry. + CommandBufferOffset put() const { return put_; } + + // Checks whether there are commands to process. + bool IsEmpty() const { return put_ == get_; } + + // Processes one command, updating the get pointer. This will return an error + // if there are no commands in the buffer. + parse_error::ParseError ProcessCommand(); + + // Processes all commands until get == put. + parse_error::ParseError ProcessAllCommands(); + + // Reports an error. + void ReportError(unsigned int command_id, parse_error::ParseError result); + + private: + CommandBufferOffset get_; + CommandBufferOffset put_; + CommandBufferEntry *buffer_; + size_t entry_count_; + AsyncAPIInterface *handler_; +}; + +// This class defines the interface for an asynchronous API handler, that +// is responsible for de-multiplexing commands and their arguments. +class AsyncAPIInterface { + public: + AsyncAPIInterface() {} + virtual ~AsyncAPIInterface() {} + + // Executes a command. + // Parameters: + // command: the command index. + // arg_count: the number of CommandBufferEntry arguments. + // cmd_data: the command data. + // Returns: + // parse_error::NO_ERROR if no error was found, one of + // parse_error::ParseError otherwise. + virtual parse_error::ParseError DoCommand( + unsigned int command, + unsigned int arg_count, + const void* cmd_data) = 0; + + // Returns a name for a command. Useful for logging / debuging. + virtual const char* GetCommandName(unsigned int command_id) const = 0; +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_CMD_PARSER_H_ diff --git a/o3d/command_buffer/service/cmd_parser_test.cc b/o3d/command_buffer/service/cmd_parser_test.cc new file mode 100644 index 0000000..153c20a --- /dev/null +++ b/o3d/command_buffer/service/cmd_parser_test.cc @@ -0,0 +1,314 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// Tests for the command parser. + +#include "tests/common/win/testing_common.h" +#include "command_buffer/service/cmd_parser.h" +#include "command_buffer/service/mocks.h" +#include "base/scoped_ptr.h" + +namespace command_buffer { + +using testing::Return; +using testing::Mock; +using testing::Truly; +using testing::Sequence; +using testing::_; + +// Test fixture for CommandParser test - Creates a mock AsyncAPIInterface, and +// a fixed size memory buffer. Also provides a simple API to create a +// CommandParser. +class CommandParserTest : public testing::Test { + protected: + virtual void SetUp() { + api_mock_.reset(new AsyncAPIMock); + buffer_entry_count_ = 20; + buffer_.reset(new CommandBufferEntry[buffer_entry_count_]); + } + virtual void TearDown() {} + + // Adds a DoCommand expectation in the mock. + void AddDoCommandExpect(parse_error::ParseError _return, + unsigned int command, + unsigned int arg_count, + CommandBufferEntry *args) { + EXPECT_CALL(*api_mock(), DoCommand(command, arg_count, + Truly(AsyncAPIMock::IsArgs(arg_count, args)))) + .InSequence(sequence_) + .WillOnce(Return(_return)); + } + + // Creates a parser, with a buffer of the specified size (in entries). + CommandParser *MakeParser(unsigned int entry_count) { + size_t shm_size = buffer_entry_count_ * + sizeof(CommandBufferEntry); // NOLINT + size_t command_buffer_size = entry_count * + sizeof(CommandBufferEntry); // NOLINT + DCHECK_LE(command_buffer_size, shm_size); + return new CommandParser(buffer(), + shm_size, + 0, + command_buffer_size, + 0, + api_mock()); + } + + unsigned int buffer_entry_count() { return 20; } + AsyncAPIMock *api_mock() { return api_mock_.get(); } + CommandBufferEntry *buffer() { return buffer_.get(); } + private: + unsigned int buffer_entry_count_; + scoped_ptr api_mock_; + scoped_array buffer_; + Sequence sequence_; +}; + +// Tests initialization conditions. +TEST_F(CommandParserTest, TestInit) { + scoped_ptr parser(MakeParser(10)); + EXPECT_EQ(0u, parser->get()); + EXPECT_EQ(0u, parser->put()); + EXPECT_TRUE(parser->IsEmpty()); +} + +// Tests simple commands. +TEST_F(CommandParserTest, TestSimple) { + scoped_ptr parser(MakeParser(10)); + CommandBufferOffset put = parser->put(); + CommandHeader header; + + // add a single command, no args + header.size = 1; + header.command = 123; + buffer()[put++].value_header = header; + + parser->set_put(put); + EXPECT_EQ(put, parser->put()); + + AddDoCommandExpect(parse_error::kParseNoError, 123, 0, NULL); + EXPECT_EQ(parse_error::kParseNoError, parser->ProcessCommand()); + EXPECT_EQ(put, parser->get()); + Mock::VerifyAndClearExpectations(api_mock()); + + // add a single command, 2 args + header.size = 3; + header.command = 456; + buffer()[put++].value_header = header; + buffer()[put++].value_int32 = 2134; + buffer()[put++].value_float = 1.f; + + parser->set_put(put); + EXPECT_EQ(put, parser->put()); + + CommandBufferEntry param_array[2]; + param_array[0].value_int32 = 2134; + param_array[1].value_float = 1.f; + AddDoCommandExpect(parse_error::kParseNoError, 456, 2, param_array); + EXPECT_EQ(parse_error::kParseNoError, parser->ProcessCommand()); + EXPECT_EQ(put, parser->get()); + Mock::VerifyAndClearExpectations(api_mock()); +} + +// Tests having multiple commands in the buffer. +TEST_F(CommandParserTest, TestMultipleCommands) { + scoped_ptr parser(MakeParser(10)); + CommandBufferOffset put = parser->put(); + CommandHeader header; + + // add 2 commands, test with single ProcessCommand() + header.size = 2; + header.command = 789; + buffer()[put++].value_header = header; + buffer()[put++].value_int32 = 5151; + + CommandBufferOffset put_cmd2 = put; + header.size = 2; + header.command = 2121; + buffer()[put++].value_header = header; + buffer()[put++].value_int32 = 3434; + + parser->set_put(put); + EXPECT_EQ(put, parser->put()); + + CommandBufferEntry param_array[2]; + param_array[0].value_int32 = 5151; + AddDoCommandExpect(parse_error::kParseNoError, 789, 1, param_array); + param_array[1].value_int32 = 3434; + AddDoCommandExpect(parse_error::kParseNoError, 2121, 1, + param_array+1); + + EXPECT_EQ(parse_error::kParseNoError, parser->ProcessCommand()); + EXPECT_EQ(put_cmd2, parser->get()); + EXPECT_EQ(parse_error::kParseNoError, parser->ProcessCommand()); + EXPECT_EQ(put, parser->get()); + Mock::VerifyAndClearExpectations(api_mock()); + + // add 2 commands again, test with ProcessAllCommands() + header.size = 2; + header.command = 4545; + buffer()[put++].value_header = header; + buffer()[put++].value_int32 = 5656; + + header.size = 2; + header.command = 6767; + buffer()[put++].value_header = header; + buffer()[put++].value_int32 = 7878; + + parser->set_put(put); + EXPECT_EQ(put, parser->put()); + + param_array[0].value_int32 = 5656; + AddDoCommandExpect(parse_error::kParseNoError, 4545, 1, param_array); + param_array[1].value_int32 = 7878; + AddDoCommandExpect(parse_error::kParseNoError, 6767, 1, + param_array+1); + + EXPECT_EQ(parse_error::kParseNoError, parser->ProcessAllCommands()); + EXPECT_EQ(put, parser->get()); + Mock::VerifyAndClearExpectations(api_mock()); +} + +// Tests that the parser will wrap correctly at the end of the buffer. +TEST_F(CommandParserTest, TestWrap) { + scoped_ptr parser(MakeParser(5)); + CommandBufferOffset put = parser->put(); + CommandHeader header; + + // add 3 commands with no args (1 word each) + for (unsigned int i = 0; i < 3; ++i) { + header.size = 1; + header.command = i; + buffer()[put++].value_header = header; + AddDoCommandExpect(parse_error::kParseNoError, i, 0, NULL); + } + parser->set_put(put); + EXPECT_EQ(put, parser->put()); + EXPECT_EQ(parse_error::kParseNoError, parser->ProcessAllCommands()); + EXPECT_EQ(put, parser->get()); + Mock::VerifyAndClearExpectations(api_mock()); + + // add 1 command with 1 arg (2 words). That should put us at the end of the + // buffer. + header.size = 2; + header.command = 3; + buffer()[put++].value_header = header; + buffer()[put++].value_int32 = 5; + CommandBufferEntry param; + param.value_int32 = 5; + AddDoCommandExpect(parse_error::kParseNoError, 3, 1, ¶m); + + DCHECK_EQ(5u, put); + put = 0; + parser->set_put(put); + EXPECT_EQ(put, parser->put()); + EXPECT_EQ(parse_error::kParseNoError, parser->ProcessAllCommands()); + EXPECT_EQ(put, parser->get()); + Mock::VerifyAndClearExpectations(api_mock()); + + // add 1 command with 1 arg (2 words). + header.size = 2; + header.command = 4; + buffer()[put++].value_header = header; + buffer()[put++].value_int32 = 6; + param.value_int32 = 6; + AddDoCommandExpect(parse_error::kParseNoError, 4, 1, ¶m); + parser->set_put(put); + EXPECT_EQ(put, parser->put()); + EXPECT_EQ(parse_error::kParseNoError, parser->ProcessAllCommands()); + EXPECT_EQ(put, parser->get()); + Mock::VerifyAndClearExpectations(api_mock()); +} + +// Tests error conditions. +TEST_F(CommandParserTest, TestError) { + scoped_ptr parser(MakeParser(5)); + CommandBufferOffset put = parser->put(); + CommandHeader header; + + // Generate a command with size 0. + header.size = 0; + header.command = 3; + buffer()[put++].value_header = header; + + parser->set_put(put); + EXPECT_EQ(put, parser->put()); + EXPECT_EQ(parse_error::kParseInvalidSize, + parser->ProcessAllCommands()); + // check that no DoCommand call was made. + Mock::VerifyAndClearExpectations(api_mock()); + + parser.reset(MakeParser(5)); + put = parser->put(); + + // Generate a command with size 6, extends beyond the end of the buffer. + header.size = 6; + header.command = 3; + buffer()[put++].value_header = header; + + parser->set_put(put); + EXPECT_EQ(put, parser->put()); + EXPECT_EQ(parse_error::kParseOutOfBounds, + parser->ProcessAllCommands()); + // check that no DoCommand call was made. + Mock::VerifyAndClearExpectations(api_mock()); + + parser.reset(MakeParser(5)); + put = parser->put(); + + // Generates 2 commands. + header.size = 1; + header.command = 3; + buffer()[put++].value_header = header; + CommandBufferOffset put_post_fail = put; + header.size = 1; + header.command = 4; + buffer()[put++].value_header = header; + + parser->set_put(put); + EXPECT_EQ(put, parser->put()); + // have the first command fail to parse. + AddDoCommandExpect(parse_error::kParseUnknownCommand, 3, 0, NULL); + EXPECT_EQ(parse_error::kParseUnknownCommand, + parser->ProcessAllCommands()); + // check that only one command was executed, and that get reflects that + // correctly. + EXPECT_EQ(put_post_fail, parser->get()); + Mock::VerifyAndClearExpectations(api_mock()); + // make the second one succeed, and check that the parser recovered fine. + AddDoCommandExpect(parse_error::kParseNoError, 4, 0, NULL); + EXPECT_EQ(parse_error::kParseNoError, parser->ProcessAllCommands()); + EXPECT_EQ(put, parser->get()); + Mock::VerifyAndClearExpectations(api_mock()); +} + +} // namespace command_buffer diff --git a/o3d/command_buffer/service/common_decoder.cc b/o3d/command_buffer/service/common_decoder.cc new file mode 100644 index 0000000..3d53c1f --- /dev/null +++ b/o3d/command_buffer/service/common_decoder.cc @@ -0,0 +1,121 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "command_buffer/service/common_decoder.h" +#include "command_buffer/service/cmd_buffer_engine.h" + +namespace command_buffer { + +void* CommonDecoder::GetAddressAndCheckSize(unsigned int shm_id, + unsigned int offset, + unsigned int size) { + void* shm_addr = engine_->GetSharedMemoryAddress(shm_id); + if (!shm_addr) return NULL; + size_t shm_size = engine_->GetSharedMemorySize(shm_id); + unsigned int end = offset + size; + if (end > shm_size || end < offset) { + return NULL; + } + return static_cast(shm_addr) + offset; +} + +const char* CommonDecoder::GetCommonCommandName( + cmd::CommandId command_id) const { + return cmd::GetCommandName(command_id); +} + +namespace { + +// A struct to hold info about each command. +struct CommandInfo { + int arg_flags; // How to handle the arguments for this command + int arg_count; // How many arguments are expected for this command. +}; + +// A table of CommandInfo for all the commands. +const CommandInfo g_command_info[] = { + #define COMMON_COMMAND_BUFFER_CMD_OP(name) { \ + cmd::name::kArgFlags, \ + sizeof(cmd::name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ \ + + COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP) + + #undef COMMON_COMMAND_BUFFER_CMD_OP +}; + +} // anonymous namespace. + +// Decode command with its arguments, and call the corresponding method. +// Note: args is a pointer to the command buffer. As such, it could be changed +// by a (malicious) client at any time, so if validation has to happen, it +// should operate on a copy of them. +parse_error::ParseError CommonDecoder::DoCommonCommand( + unsigned int command, + unsigned int arg_count, + const void* cmd_data) { + if (command < arraysize(g_command_info)) { + const CommandInfo& info = g_command_info[command]; + unsigned int info_arg_count = static_cast(info.arg_count); + if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) || + (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) { + switch (command) { + #define COMMON_COMMAND_BUFFER_CMD_OP(name) \ + case cmd::name::kCmdId: \ + return Handle ## name( \ + arg_count, \ + *static_cast(cmd_data)); \ + + COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP) + + #undef COMMON_COMMAND_BUFFER_CMD_OP + } + } else { + return parse_error::kParseInvalidArguments; + } + } + return DoCommonCommand(command, arg_count, cmd_data); + return parse_error::kParseUnknownCommand; +} + +parse_error::ParseError CommonDecoder::HandleNoop( + uint32 arg_count, + const cmd::Noop& args) { + return parse_error::kParseNoError; +} + +parse_error::ParseError CommonDecoder::HandleSetToken( + uint32 arg_count, + const cmd::SetToken& args) { + engine_->set_token(args.token); + return parse_error::kParseNoError; +} + +} // namespace command_buffer diff --git a/o3d/command_buffer/service/common_decoder.h b/o3d/command_buffer/service/common_decoder.h new file mode 100644 index 0000000..9b77e77 --- /dev/null +++ b/o3d/command_buffer/service/common_decoder.h @@ -0,0 +1,107 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_COMMON_DECODER_H_ +#define GPU_COMMAND_BUFFER_SERVICE_CROSS_COMMON_DECODER_H_ + +#include "command_buffer/service/cmd_parser.h" + +namespace command_buffer { + +class CommandBufferEngine; + +// This class is a helper base class for implementing the common parts of the +// o3d/gl2 command buffer decoder. +class CommonDecoder : public AsyncAPIInterface { + public: + typedef parse_error::ParseError ParseError; + + CommonDecoder() : engine_(NULL) { + } + virtual ~CommonDecoder() { + } + + // Sets the engine, to get shared memory buffers from, and to set the token + // to. + void set_engine(CommandBufferEngine* engine) { + engine_ = engine; + } + + protected: + // Executes a common command. + // Parameters: + // command: the command index. + // arg_count: the number of CommandBufferEntry arguments. + // cmd_data: the command data. + // Returns: + // parse_error::NO_ERROR if no error was found, one of + // parse_error::ParseError otherwise. + parse_error::ParseError DoCommonCommand( + unsigned int command, + unsigned int arg_count, + const void* cmd_data); + + // Gets the address of shared memory data, given a shared memory ID and an + // offset. Also checks that the size is consistent with the shared memory + // size. + // Parameters: + // shm_id: the id of the shared memory buffer. + // offset: the offset of the data in the shared memory buffer. + // size: the size of the data. + // Returns: + // NULL if shm_id isn't a valid shared memory buffer ID or if the size + // check fails. Return a pointer to the data otherwise. + void* GetAddressAndCheckSize(unsigned int shm_id, + unsigned int offset, + unsigned int size); + + // Gets an name for a common command. + const char* GetCommonCommandName(cmd::CommandId command_id) const; + + private: + // Generate a member function prototype for each command in an automated and + // typesafe way. + #define COMMON_COMMAND_BUFFER_CMD_OP(name) \ + parse_error::ParseError Handle ## name( \ + unsigned int arg_count, \ + const cmd::name& args); \ + + COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP) + + #undef COMMON_COMMAND_BUFFER_CMD_OP + + CommandBufferEngine* engine_; +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_COMMON_DECODER_H_ + diff --git a/o3d/command_buffer/service/d3d9_utils.h b/o3d/command_buffer/service/d3d9_utils.h new file mode 100644 index 0000000..714be3f --- /dev/null +++ b/o3d/command_buffer/service/d3d9_utils.h @@ -0,0 +1,145 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file defines a few utilities for Direct3D. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_WIN_D3D9_D3D9_UTILS_H_ +#define GPU_COMMAND_BUFFER_SERVICE_WIN_D3D9_D3D9_UTILS_H_ + +#ifndef NOMINMAX +// windows.h defines min() and max() as macros, conflicting with std::min and +// std::max unless NOMINMAX is defined. +#define NOMINMAX +#endif +#include +#include +#include +#include +#include +#include "command_buffer/common/gapi_interface.h" + +#if defined (_DEBUG) + +#ifndef HR +#define HR(x) { \ + HRESULT hr = x; \ + if (FAILED(hr)) { \ + LOG(ERROR) << "DirectX error at " << __FILE__ << ":" << __LINE__ \ + << " when calling " << #x << ": " << DXGetErrorStringA(hr); \ + } \ + } +#endif + +#else // _DEBUG + +#ifndef HR +#define HR(x) x; +#endif + +#endif // _DEBUG + +namespace command_buffer { + +union FloatAndDWORD { + float float_value; + DWORD dword_value; +}; + +// Bit casts a float into a DWORD. That's what D3D expects for some values. +inline DWORD FloatAsDWORD(float value) { + volatile FloatAndDWORD float_and_dword; + float_and_dword.float_value = value; + return float_and_dword.dword_value; +} + +// Clamps a float to [0 .. 1] and maps it to [0 .. 255] +inline unsigned int FloatToClampedByte(float value) { + value = std::min(1.f, std::max(0.f, value)); + return static_cast(value * 255); +} + +// Converts a RGBA color into a D3DCOLOR +inline D3DCOLOR RGBAToD3DCOLOR(const o3d::RGBA &color) { + return D3DCOLOR_RGBA(FloatToClampedByte(color.red), + FloatToClampedByte(color.green), + FloatToClampedByte(color.blue), + FloatToClampedByte(color.alpha)); +} + +static bool D3DSemanticToCBSemantic( + D3DDECLUSAGE semantic, + unsigned int semantic_index, + vertex_struct::Semantic *out_semantic, + unsigned int *out_semantic_index) { + // TODO: what meaning do we really want to put to our semantics ? How + // do they match the semantics that are set in the effect ? What combination + // of (semantic, index) are supposed to work ? + // TODO(gman): This is just plain wrong! Fix it. Converting binormal to + // texcoord 7 means there will be conflicts if I have both a Binormal and a + // texcoord 7 or 2 binormals both of which we have examples of already in O3D! + switch (semantic) { + case D3DDECLUSAGE_POSITION: + if (semantic_index != 0) return false; + *out_semantic = vertex_struct::kPosition; + *out_semantic_index = 0; + return true; + case D3DDECLUSAGE_NORMAL: + if (semantic_index != 0) return false; + *out_semantic = vertex_struct::kNormal; + *out_semantic_index = 0; + return true; + case D3DDECLUSAGE_TANGENT: + if (semantic_index != 0) return false; + *out_semantic = vertex_struct::kTexCoord; + *out_semantic_index = 6; + return true; + case D3DDECLUSAGE_BINORMAL: + if (semantic_index != 0) return false; + *out_semantic = vertex_struct::kTexCoord; + *out_semantic_index = 7; + return true; + case D3DDECLUSAGE_COLOR: + if (semantic_index > 1) return false; + *out_semantic = vertex_struct::kColor; + *out_semantic_index = semantic_index; + return true; + case D3DDECLUSAGE_TEXCOORD: + *out_semantic = vertex_struct::kTexCoord; + *out_semantic_index = semantic_index; + return true; + default: + return false; + } +} +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_WIN_D3D9_D3D9_UTILS_H_ diff --git a/o3d/command_buffer/service/effect_d3d9.cc b/o3d/command_buffer/service/effect_d3d9.cc new file mode 100644 index 0000000..6ed3bc4 --- /dev/null +++ b/o3d/command_buffer/service/effect_d3d9.cc @@ -0,0 +1,677 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the implementation of the D3D9 versions of the +// Effect resource. +// This file also contains the related GAPID3D9 function implementations. + +#include +#include "command_buffer/service/d3d9_utils.h" +#include "command_buffer/service/geometry_d3d9.h" +#include "command_buffer/service/gapi_d3d9.h" +#include "command_buffer/service/effect_d3d9.h" +#include "command_buffer/service/sampler_d3d9.h" +#include "command_buffer/service/effect_utils.h" + +// TODO: remove link-dependency on D3DX. + +namespace command_buffer { +namespace o3d { + +// Logs the D3D effect error, from either the buffer, or GetLastError(). +static void LogFXError(LPD3DXBUFFER error_buffer) { + if (error_buffer) { + LPVOID compile_errors = error_buffer->GetBufferPointer(); + LOG(ERROR) << "Failed to compile effect: " + << static_cast(compile_errors); + } else { + HLOCAL hLocal = NULL; + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + GetLastError(), + 0, + reinterpret_cast(&hLocal), + 0, + NULL); + wchar_t* msg = reinterpret_cast(LocalLock(hLocal)); + LOG(ERROR) << "Failed to compile effect: " << msg; + LocalFree(hLocal); + } +} + +EffectD3D9::EffectD3D9(GAPID3D9 *gapi, + ID3DXEffect *d3d_effect, + ID3DXConstantTable *fs_constant_table, + IDirect3DVertexShader9 *d3d_vertex_shader) + : gapi_(gapi), + d3d_effect_(d3d_effect), + fs_constant_table_(fs_constant_table), + d3d_vertex_shader_(d3d_vertex_shader), + sync_parameters_(false) { + for (unsigned int i = 0; i < kMaxSamplerUnits; ++i) { + samplers_[i] = kInvalidResource; + } + SetStreams(); +} +// Releases the D3D effect. +EffectD3D9::~EffectD3D9() { + for (ParamList::iterator it = params_.begin(); it != params_.end(); ++it) { + (*it)->ResetEffect(); + } + DCHECK(d3d_effect_); + d3d_effect_->Release(); + DCHECK(fs_constant_table_); + fs_constant_table_->Release(); + DCHECK(d3d_vertex_shader_); + d3d_vertex_shader_->Release(); +} + +// Compiles the effect, and checks that the effect conforms to what we expect +// (no extra technique or pass in the effect code, since one is implicitly added +// using the program entry points) and that it validates. If successful, wrap +// the D3D effect into a new EffectD3D9. +EffectD3D9 *EffectD3D9::Create(GAPID3D9 *gapi, + const String& effect_code, + const String& vertex_program_entry, + const String& fragment_program_entry) { + String prepared_effect = effect_code + + "technique Shaders { " + " pass p0 { " + " VertexShader = compile vs_2_0 " + vertex_program_entry + "();" + " PixelShader = compile ps_2_0 " + fragment_program_entry + "();" + " }" + "};"; + ID3DXEffect *d3d_effect = NULL; + LPD3DXBUFFER error_buffer; + IDirect3DDevice9 *device = gapi->d3d_device(); + if (gapi->D3DXCreateEffect(device, + prepared_effect.c_str(), + prepared_effect.size(), + NULL, + NULL, + 0, + NULL, + &d3d_effect, + &error_buffer) != D3D_OK) { + LogFXError(error_buffer); + return NULL; + } + // check that . + D3DXEFFECT_DESC effect_desc; + HR(d3d_effect->GetDesc(&effect_desc)); + if (effect_desc.Techniques != 1) { + LOG(ERROR) << "Only 1 technique is allowed in an effect."; + d3d_effect->Release(); + return NULL; + } + D3DXHANDLE technique = d3d_effect->GetTechnique(0); + DCHECK(technique); + if (d3d_effect->ValidateTechnique(technique) != D3D_OK) { + LOG(ERROR) << "Technique doesn't validate."; + d3d_effect->Release(); + return NULL; + } + D3DXTECHNIQUE_DESC technique_desc; + HR(d3d_effect->GetTechniqueDesc(technique, &technique_desc)); + if (technique_desc.Passes != 1) { + LOG(ERROR) << "Only 1 pass is allowed in an effect."; + d3d_effect->Release(); + return NULL; + } + d3d_effect->SetTechnique(technique); + D3DXHANDLE pass = d3d_effect->GetPass(technique, 0); + D3DXPASS_DESC pass_desc; + HR(d3d_effect->GetPassDesc(pass, &pass_desc)); + ID3DXConstantTable *table = NULL; + HR(gapi->D3DXGetShaderConstantTable(pass_desc.pPixelShaderFunction, + &table)); + if (!table) { + LOG(ERROR) << "Could not get the constant table."; + d3d_effect->Release(); + return NULL; + } + IDirect3DVertexShader9 *d3d_vertex_shader = NULL; + HR(device->CreateVertexShader(pass_desc.pVertexShaderFunction, + &d3d_vertex_shader)); + if (!d3d_vertex_shader) { + d3d_effect->Release(); + table->Release(); + DLOG(ERROR) << "Failed to create vertex shader"; + return NULL; + } + + return new EffectD3D9(gapi, d3d_effect, table, d3d_vertex_shader); +} + +// Begins rendering with the effect, setting all the appropriate states. +bool EffectD3D9::Begin() { + UINT numpasses; + HR(d3d_effect_->Begin(&numpasses, 0)); + HR(d3d_effect_->BeginPass(0)); + sync_parameters_ = false; + return SetSamplers(); +} + +// Terminates rendering with the effect, resetting all the appropriate states. +void EffectD3D9::End() { + HR(d3d_effect_->EndPass()); + HR(d3d_effect_->End()); +} + +// Gets the parameter count from the D3D effect description. +unsigned int EffectD3D9::GetParamCount() { + D3DXEFFECT_DESC effect_desc; + HR(d3d_effect_->GetDesc(&effect_desc)); + return effect_desc.Parameters; +} + +// Gets the number of input streams from the shader. +unsigned int EffectD3D9::GetStreamCount() { + return streams_.size(); +} + +// Retrieves the matching DataType from a D3D parameter description. +static effect_param::DataType GetDataTypeFromD3D( + const D3DXPARAMETER_DESC &desc) { + switch (desc.Type) { + case D3DXPT_FLOAT: + switch (desc.Class) { + case D3DXPC_SCALAR: + return effect_param::kFloat1; + case D3DXPC_VECTOR: + switch (desc.Columns) { + case 2: + return effect_param::kFloat2; + case 3: + return effect_param::kFloat3; + case 4: + return effect_param::kFloat4; + default: + return effect_param::kUnknown; + } + case D3DXPC_MATRIX_ROWS: + case D3DXPC_MATRIX_COLUMNS: + if (desc.Columns == 4 && desc.Rows == 4) { + return effect_param::kMatrix4; + } else { + return effect_param::kUnknown; + } + default: + return effect_param::kUnknown; + } + case D3DXPT_INT: + if (desc.Class == D3DXPC_SCALAR) { + return effect_param::kInt; + } else { + return effect_param::kUnknown; + } + case D3DXPT_BOOL: + if (desc.Class == D3DXPC_SCALAR) { + return effect_param::kBool; + } else { + return effect_param::kUnknown; + } + case D3DXPT_SAMPLER: + case D3DXPT_SAMPLER2D: + case D3DXPT_SAMPLER3D: + case D3DXPT_SAMPLERCUBE: + if (desc.Class == D3DXPC_OBJECT) { + return effect_param::kSampler; + } else { + return effect_param::kUnknown; + } + case D3DXPT_TEXTURE: + case D3DXPT_TEXTURE1D: + case D3DXPT_TEXTURE2D: + case D3DXPT_TEXTURE3D: + case D3DXPT_TEXTURECUBE: + if (desc.Class == D3DXPC_OBJECT) { + return effect_param::kTexture; + } else { + return effect_param::kUnknown; + } + default: + return effect_param::kUnknown; + } +} + +// Gets a handle to the selected parameter, and wraps it into an +// EffectParamD3D9 if successful. +EffectParamD3D9 *EffectD3D9::CreateParam(unsigned int index) { + D3DXHANDLE handle = d3d_effect_->GetParameter(NULL, index); + if (!handle) return NULL; + return EffectParamD3D9::Create(this, handle); +} + +// Gets a handle to the selected parameter, and wraps it into an +// EffectParamD3D9 if successful. +EffectParamD3D9 *EffectD3D9::CreateParamByName(const char *name) { + D3DXHANDLE handle = d3d_effect_->GetParameterByName(NULL, name); + if (!handle) return NULL; + return EffectParamD3D9::Create(this, handle); +} + +bool EffectD3D9::CommitParameters() { + if (sync_parameters_) { + sync_parameters_ = false; + d3d_effect_->CommitChanges(); + return SetSamplers(); + } else { + return true; + } +} + +bool EffectD3D9::SetSamplers() { + IDirect3DDevice9 *d3d_device = gapi_->d3d_device(); + bool result = true; + for (unsigned int i = 0; i < kMaxSamplerUnits; ++i) { + SamplerD3D9 *sampler = gapi_->GetSampler(samplers_[i]); + if (sampler) { + result &= sampler->ApplyStates(gapi_, i); + } else { + HR(d3d_device->SetTexture(i, NULL)); + } + } + return result; +} + +bool EffectD3D9::SetStreams() { + if (!d3d_vertex_shader_) { + return false; + } + UINT size; + d3d_vertex_shader_->GetFunction(NULL, &size); + scoped_array function(new DWORD[size]); + d3d_vertex_shader_->GetFunction(function.get(), &size); + + UINT num_semantics; + HR(gapi_->D3DXGetShaderInputSemantics(function.get(), + NULL, + &num_semantics)); + scoped_array semantics(new D3DXSEMANTIC[num_semantics]); + HR(gapi_->D3DXGetShaderInputSemantics(function.get(), + semantics.get(), + &num_semantics)); + + streams_.resize(num_semantics); + for (UINT i = 0; i < num_semantics; ++i) { + vertex_struct::Semantic semantic; + unsigned int semantic_index; + if (D3DSemanticToCBSemantic(static_cast(semantics[i].Usage), + static_cast(semantics[i].UsageIndex), + &semantic, &semantic_index)) { + streams_[i].semantic = semantic; + streams_[i].semantic_index = semantic_index; + } + } + return true; +} + +void EffectD3D9::LinkParam(EffectParamD3D9 *param) { + params_.push_back(param); +} + +void EffectD3D9::UnlinkParam(EffectParamD3D9 *param) { + std::remove(params_.begin(), params_.end(), param); +} + +// Fills the Desc structure, appending name and semantic if any, and if enough +// room is available in the buffer. +bool EffectD3D9::GetStreamDesc(unsigned int index, + unsigned int size, + void *data) { + using effect_stream::Desc; + if (size < sizeof(Desc)) // NOLINT + return false; + + Desc *desc = static_cast(data); + *desc = streams_[index]; + return true; +} + +EffectParamD3D9::EffectParamD3D9(effect_param::DataType data_type, + EffectD3D9 *effect, + D3DXHANDLE handle) + : EffectParam(data_type), + effect_(effect), + handle_(handle), + sampler_units_(NULL), + sampler_unit_count_(0) { + DCHECK(effect_); + effect_->LinkParam(this); +} + +EffectParamD3D9::~EffectParamD3D9() { + if (effect_) effect_->UnlinkParam(this); +} + +EffectParamD3D9 *EffectParamD3D9::Create(EffectD3D9 *effect, + D3DXHANDLE handle) { + DCHECK(effect); + D3DXPARAMETER_DESC desc; + HR(effect->d3d_effect_->GetParameterDesc(handle, &desc)); + effect_param::DataType data_type = GetDataTypeFromD3D(desc); + EffectParamD3D9 *param = new EffectParamD3D9(data_type, effect, handle); + if (data_type == effect_param::kSampler) { + ID3DXConstantTable *table = effect->fs_constant_table_; + DCHECK(table); + D3DXHANDLE sampler_handle = table->GetConstantByName(NULL, desc.Name); + if (sampler_handle) { + D3DXCONSTANT_DESC desc_array[kMaxSamplerUnits]; + unsigned int num_desc = kMaxSamplerUnits; + table->GetConstantDesc(sampler_handle, desc_array, &num_desc); + // We have no good way of querying how many descriptions would really be + // returned as we're capping the number to kMaxSamplerUnits (which should + // be more than sufficient). If however we do end up with the max number + // there's a chance that there were actually more so let's log it. + if (num_desc == kMaxSamplerUnits) { + DLOG(WARNING) << "Number of constant descriptions might have exceeded " + << "the maximum of " << kMaxSamplerUnits; + } + param->sampler_unit_count_ = 0; + if (num_desc > 0) { + param->sampler_units_.reset(new unsigned int[num_desc]); + for (unsigned int desc_index = 0; desc_index < num_desc; desc_index++) { + D3DXCONSTANT_DESC constant_desc = desc_array[desc_index]; + if (constant_desc.Class == D3DXPC_OBJECT && + (constant_desc.Type == D3DXPT_SAMPLER || + constant_desc.Type == D3DXPT_SAMPLER2D || + constant_desc.Type == D3DXPT_SAMPLER3D || + constant_desc.Type == D3DXPT_SAMPLERCUBE)) { + param->sampler_units_[param->sampler_unit_count_++] = + constant_desc.RegisterIndex; + } + } + } + } + // if the sampler hasn't been found in the constant table, that means it + // isn't referenced, hence it doesn't use any sampler unit. + } + return param; +} + +// Fills the Desc structure, appending name and semantic if any, and if enough +// room is available in the buffer. +bool EffectParamD3D9::GetDesc(unsigned int size, void *data) { + using effect_param::Desc; + if (size < sizeof(Desc)) // NOLINT + return false; + if (!effect_) + return false; + ID3DXEffect *d3d_effect = effect_->d3d_effect_; + D3DXPARAMETER_DESC d3d_desc; + HR(d3d_effect->GetParameterDesc(handle_, &d3d_desc)); + unsigned int name_size = + d3d_desc.Name ? static_cast(strlen(d3d_desc.Name)) + 1 : 0; + unsigned int semantic_size = d3d_desc.Semantic ? + static_cast(strlen(d3d_desc.Semantic)) + 1 : 0; + unsigned int total_size = sizeof(Desc) + name_size + semantic_size; // NOLINT + + Desc *desc = static_cast(data); + memset(desc, 0, sizeof(*desc)); + desc->size = total_size; + desc->data_type = data_type(); + desc->data_size = GetDataSize(data_type()); + desc->name_offset = 0; + desc->name_size = name_size; + desc->num_elements = d3d_desc.Elements; + desc->semantic_offset = 0; + desc->semantic_size = semantic_size; + unsigned int current_offset = sizeof(Desc); + if (d3d_desc.Name && current_offset + name_size <= size) { + desc->name_offset = current_offset; + memcpy(static_cast(data) + current_offset, + d3d_desc.Name, name_size); + current_offset += name_size; + } + if (d3d_desc.Semantic && current_offset + semantic_size <= size) { + desc->semantic_offset = current_offset; + memcpy(static_cast(data) + current_offset, + d3d_desc.Semantic, semantic_size); + current_offset += semantic_size; + } + return true; +} + +// Sets the data into the D3D effect parameter, using the appropriate D3D call. +bool EffectParamD3D9::SetData(GAPID3D9 *gapi, + unsigned int size, + const void * data) { + if (!effect_) + return false; + ID3DXEffect *d3d_effect = effect_->d3d_effect_; + effect_param::DataType type = data_type(); + if (size < effect_param::GetDataSize(type)) return false; + switch (type) { + case effect_param::kFloat1: + HR(d3d_effect->SetFloat(handle_, *static_cast(data))); + break; + case effect_param::kFloat2: + HR(d3d_effect->SetFloatArray(handle_, static_cast(data), + 2)); + break; + case effect_param::kFloat3: + HR(d3d_effect->SetFloatArray(handle_, static_cast(data), + 3)); + break; + case effect_param::kFloat4: + HR(d3d_effect->SetFloatArray(handle_, static_cast(data), + 4)); + break; + case effect_param::kMatrix4: + HR(d3d_effect->SetMatrix(handle_, + reinterpret_cast(data))); + break; + case effect_param::kInt: + HR(d3d_effect->SetInt(handle_, *static_cast(data))); + break; + case effect_param::kBool: + HR(d3d_effect->SetBool(handle_, *static_cast(data)?1:0)); + break; + case effect_param::kSampler: { + ResourceId id = *static_cast(data); + for (unsigned int i = 0; i < sampler_unit_count_; ++i) { + effect_->samplers_[sampler_units_[i]] = id; + } + break; + } + case effect_param::kTexture: { + // TODO(rlp): finish + break; + } + default: + DLOG(ERROR) << "Invalid parameter type."; + return false; + } + if (effect_ == gapi->current_effect()) { + effect_->sync_parameters_ = true; + } + return true; +} + +// Calls EffectD3D9::Create, and assign the result to the resource ID. +// If changing the current effect, dirty it. +parse_error::ParseError GAPID3D9::CreateEffect( + ResourceId id, + unsigned int size, + const void *data) { + if (id == current_effect_id_) DirtyEffect(); + // Even though Assign would Destroy the effect at id, we do it explicitly in + // case the creation fails. + effects_.Destroy(id); + // Data is vp_main \0 fp_main \0 effect_text. + String vertex_program_entry; + String fragment_program_entry; + String effect_code; + if (!ParseEffectData(size, data, + &vertex_program_entry, + &fragment_program_entry, + &effect_code)) { + return parse_error::kParseInvalidArguments; + } + EffectD3D9 * effect = EffectD3D9::Create(this, effect_code, + vertex_program_entry, + fragment_program_entry); + if (!effect) return parse_error::kParseInvalidArguments; + effects_.Assign(id, effect); + return parse_error::kParseNoError; +} + +// Destroys the Effect resource. +// If destroying the current effect, dirty it. +parse_error::ParseError GAPID3D9::DestroyEffect(ResourceId id) { + if (id == current_effect_id_) DirtyEffect(); + return effects_.Destroy(id) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +// Sets the current effect ID, dirtying the current effect. +parse_error::ParseError GAPID3D9::SetEffect(ResourceId id) { + DirtyEffect(); + current_effect_id_ = id; + return parse_error::kParseNoError; +} + +// Gets the param count from the effect and store it in the memory buffer. +parse_error::ParseError GAPID3D9::GetParamCount( + ResourceId id, + unsigned int size, + void *data) { + EffectD3D9 *effect = effects_.Get(id); + if (!effect || size < sizeof(Uint32)) // NOLINT + return parse_error::kParseInvalidArguments; + *static_cast(data) = effect->GetParamCount(); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPID3D9::CreateParam( + ResourceId param_id, + ResourceId effect_id, + unsigned int index) { + EffectD3D9 *effect = effects_.Get(effect_id); + if (!effect) return parse_error::kParseInvalidArguments; + EffectParamD3D9 *param = effect->CreateParam(index); + if (!param) return parse_error::kParseInvalidArguments; + effect_params_.Assign(param_id, param); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPID3D9::CreateParamByName( + ResourceId param_id, + ResourceId effect_id, + unsigned int size, + const void *name) { + EffectD3D9 *effect = effects_.Get(effect_id); + if (!effect) return parse_error::kParseInvalidArguments; + std::string string_name(static_cast(name), size); + EffectParamD3D9 *param = effect->CreateParamByName(string_name.c_str()); + if (!param) return parse_error::kParseInvalidArguments; + effect_params_.Assign(param_id, param); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPID3D9::DestroyParam(ResourceId id) { + return effect_params_.Destroy(id) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +parse_error::ParseError GAPID3D9::SetParamData( + ResourceId id, + unsigned int size, + const void *data) { + EffectParamD3D9 *param = effect_params_.Get(id); + if (!param) return parse_error::kParseInvalidArguments; + return param->SetData(this, size, data) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +parse_error::ParseError GAPID3D9::GetParamDesc( + ResourceId id, + unsigned int size, + void *data) { + EffectParamD3D9 *param = effect_params_.Get(id); + if (!param) return parse_error::kParseInvalidArguments; + return param->GetDesc(size, data) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +// Gets the stream count from the effect and stores it in the memory buffer. +parse_error::ParseError GAPID3D9::GetStreamCount( + ResourceId id, + unsigned int size, + void *data) { + EffectD3D9 *effect = effects_.Get(id); + if (!effect || size < sizeof(Uint32)) // NOLINT + return parse_error::kParseInvalidArguments; + *static_cast(data) = effect->GetStreamCount(); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPID3D9::GetStreamDesc( + ResourceId id, + unsigned int index, + unsigned int size, + void *data) { + EffectD3D9 *effect = effects_.Get(id); + if (!effect) return parse_error::kParseInvalidArguments; + return effect->GetStreamDesc(index, size, data) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + + +// If the current effect is valid, call End on it, and tag for revalidation. +void GAPID3D9::DirtyEffect() { + if (validate_effect_) return; + DCHECK(current_effect_); + current_effect_->End(); + current_effect_ = NULL; + validate_effect_ = true; +} + +// Gets the current effect, and calls Begin on it (if successful). +// Should only be called if the current effect is not valid. +bool GAPID3D9::ValidateEffect() { + DCHECK(validate_effect_); + DCHECK(!current_effect_); + current_effect_ = effects_.Get(current_effect_id_); + if (!current_effect_) return false; + validate_effect_ = false; + return current_effect_->Begin(); +} + +} // namespace o3d +} // namespace command_buffer diff --git a/o3d/command_buffer/service/effect_d3d9.h b/o3d/command_buffer/service/effect_d3d9.h new file mode 100644 index 0000000..cbe32a3 --- /dev/null +++ b/o3d/command_buffer/service/effect_d3d9.h @@ -0,0 +1,139 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the definition of the D3D9 versions of effect-related +// resource classes. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_WIN_D3D9_EFFECT_D3D9_H_ +#define GPU_COMMAND_BUFFER_SERVICE_WIN_D3D9_EFFECT_D3D9_H_ + +#include +#include "command_buffer/common/gapi_interface.h" +#include "command_buffer/service/d3d9_utils.h" +#include "command_buffer/service/resource.h" + +namespace command_buffer { +namespace o3d { + +class GAPID3D9; +class EffectD3D9; + +// ps_2_0 limit +static const unsigned int kMaxSamplerUnits = 16; + +// D3D version of EffectParam. This class keeps a reference to the D3D effect. +class EffectParamD3D9: public EffectParam { + public: + EffectParamD3D9(effect_param::DataType data_type, + EffectD3D9 *effect, + D3DXHANDLE handle); + virtual ~EffectParamD3D9(); + + // Sets the data into the D3D effect parameter. + bool SetData(GAPID3D9 *gapi, unsigned int size, const void * data); + + // Gets the description of the parameter. + bool GetDesc(unsigned int size, void *data); + + // Resets the effect back-pointer. This is called when the effect gets + // destroyed, to invalidate the parameter. + void ResetEffect() { effect_ = NULL; } + + static EffectParamD3D9 *Create(EffectD3D9 *effect, D3DXHANDLE handle); + private: + EffectD3D9 *effect_; + D3DXHANDLE handle_; + unsigned int sampler_unit_count_; + scoped_array sampler_units_; +}; + +// D3D9 version of Effect. +class EffectD3D9 : public Effect { + public: + EffectD3D9(GAPID3D9 *gapi, + ID3DXEffect *d3d_effect, + ID3DXConstantTable *fs_constant_table, + IDirect3DVertexShader9 *d3d_vertex_shader); + virtual ~EffectD3D9(); + // Compiles and creates an effect from source code. + static EffectD3D9 *Create(GAPID3D9 *gapi, + const String &effect_code, + const String &vertex_program_entry, + const String &fragment_program_entry); + // Applies the effect states (vertex shader, pixel shader) to D3D. + bool Begin(); + // Resets the effect states (vertex shader, pixel shader) to D3D. + void End(); + // Commits parameters to D3D, if they were modified while the effect is + // active. + bool CommitParameters(); + + // Gets the number of parameters in the effect. + unsigned int GetParamCount(); + // Creates an effect parameter with the specified index. + EffectParamD3D9 *CreateParam(unsigned int index); + // Creates an effect parameter of the specified name. + EffectParamD3D9 *CreateParamByName(const char *name); + // Gets the number of stream inputs for the effect. + unsigned int GetStreamCount(); + // Gets the stream data with the specified index. + bool GetStreamDesc(unsigned int index, unsigned int size, void *data); + private: + typedef std::vector ParamList; + typedef std::vector StreamList; + + // Links a param into this effect. + void LinkParam(EffectParamD3D9 *param); + // Unlinks a param into this effect. + void UnlinkParam(EffectParamD3D9 *param); + // Sets sampler states. + bool SetSamplers(); + // Sets streams vector. + bool SetStreams(); + + GAPID3D9* gapi_; + ID3DXEffect *d3d_effect_; + IDirect3DVertexShader9 *d3d_vertex_shader_; + ID3DXConstantTable *fs_constant_table_; + ParamList params_; + StreamList streams_; + bool sync_parameters_; + ResourceId samplers_[kMaxSamplerUnits]; + + friend class EffectParamD3D9; + DISALLOW_COPY_AND_ASSIGN(EffectD3D9); +}; + +} // namespace o3d +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_WIN_D3D9_EFFECT_D3D9_H_ diff --git a/o3d/command_buffer/service/effect_gl.cc b/o3d/command_buffer/service/effect_gl.cc new file mode 100644 index 0000000..881f6b7 --- /dev/null +++ b/o3d/command_buffer/service/effect_gl.cc @@ -0,0 +1,850 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the implementation of the EffectParamGL and EffectGL +// classes, as well as the effect-related GAPI functions on GL. + +#include + +#include "base/cross/std_functional.h" +#include "command_buffer/service/effect_gl.h" +#include "command_buffer/service/gapi_gl.h" +#include "command_buffer/service/effect_utils.h" + +namespace command_buffer { +namespace o3d { + +EffectParamGL::EffectParamGL(effect_param::DataType data_type, + EffectGL *effect, + unsigned int param_index) + : EffectParam(data_type), + effect_(effect), + low_level_param_index_(param_index) { + DCHECK(effect_); + effect_->LinkParam(this); +} + +EffectParamGL::~EffectParamGL() { + if (effect_) + effect_->UnlinkParam(this); +} + +static effect_param::DataType CgTypeToCBType(CGtype cg_type) { + switch (cg_type) { + case CG_FLOAT: + case CG_FLOAT1: + return effect_param::kFloat1; + case CG_FLOAT2: + return effect_param::kFloat2; + case CG_FLOAT3: + return effect_param::kFloat3; + case CG_FLOAT4: + return effect_param::kFloat4; + case CG_INT: + case CG_INT1: + return effect_param::kInt; + case CG_BOOL: + case CG_BOOL1: + return effect_param::kBool; + case CG_FLOAT4x4: + return effect_param::kMatrix4; + case CG_SAMPLER: + case CG_SAMPLER1D: + case CG_SAMPLER2D: + case CG_SAMPLER3D: + case CG_SAMPLERCUBE: + return effect_param::kSampler; + case CG_TEXTURE: + return effect_param::kTexture; + default : { + DLOG(INFO) << "Cannot convert CGtype " + << cgGetTypeString(cg_type) + << " to a Param type."; + return effect_param::kUnknown; + } + } +} + +EffectParamGL *EffectParamGL::Create(EffectGL *effect, + unsigned int index) { + DCHECK(effect); + const EffectGL::LowLevelParam &low_level_param = + effect->low_level_params_[index]; + CGparameter cg_param = EffectGL::GetEitherCgParameter(low_level_param); + CGtype cg_type = cgGetParameterType(cg_param); + if (cg_type == CG_ARRAY) { + cg_type = cgGetParameterType(cgGetArrayParameter(cg_param, 0)); + } + effect_param::DataType type = CgTypeToCBType(cg_type); + + if (type == effect_param::kUnknown) + return NULL; + return new EffectParamGL(type, effect, index); +} + +// Fills the Desc structure, appending name and semantic if any, and if enough +// room is available in the buffer. +bool EffectParamGL::GetDesc(unsigned int size, void *data) { + using effect_param::Desc; + if (size < sizeof(Desc)) // NOLINT + return false; + if (!effect_) + return false; + const EffectGL::LowLevelParam &low_level_param = + effect_->low_level_params_[low_level_param_index_]; + CGparameter cg_param = EffectGL::GetEitherCgParameter(low_level_param); + const char *name = low_level_param.name; + const char* semantic = cgGetParameterSemantic(cg_param); + int num_elements = cgGetArraySize(cg_param, 0); + unsigned int name_size = + name ? static_cast(strlen(name)) + 1 : 0; + unsigned int semantic_size = semantic ? + static_cast(strlen(semantic)) + 1 : 0; + unsigned int total_size = sizeof(Desc) + name_size + semantic_size; // NOLINT + + Desc *desc = static_cast(data); + memset(desc, 0, sizeof(*desc)); + desc->size = total_size; + desc->data_type = data_type(); + desc->data_size = GetDataSize(data_type()); + desc->name_offset = 0; + desc->name_size = name_size; + desc->semantic_offset = 0; + desc->num_elements = num_elements; + desc->semantic_size = semantic_size; + unsigned int current_offset = sizeof(Desc); + if (name && current_offset + name_size <= size) { + desc->name_offset = current_offset; + memcpy(static_cast(data) + current_offset, name, name_size); + current_offset += name_size; + } + if (semantic && current_offset + semantic_size <= size) { + desc->semantic_offset = current_offset; + memcpy(static_cast(data) + current_offset, semantic, semantic_size); + current_offset += semantic_size; + } + return true; +} + +// Sets the data into the Cg effect parameter, using the appropriate Cg call. +bool EffectParamGL::SetData(GAPIGL *gapi, + unsigned int size, + const void * data) { + if (!effect_) + return false; + + EffectGL::LowLevelParam &low_level_param = + effect_->low_level_params_[low_level_param_index_]; + + if (low_level_param.num_elements != 0) { + DLOG(ERROR) << "Attempt to set array parameter to value."; + return false; + } + + CGparameter vp_param = low_level_param.vp_param; + CGparameter fp_param = low_level_param.fp_param; + effect_param::DataType type = data_type(); + if (size < effect_param::GetDataSize(type)) + return false; + + switch (type) { + case effect_param::kFloat1: + if (vp_param) + cgSetParameter1f(vp_param, *static_cast(data)); + if (fp_param) + cgSetParameter1f(fp_param, *static_cast(data)); + break; + case effect_param::kFloat2: + if (vp_param) + cgSetParameter2fv(vp_param, static_cast(data)); + if (fp_param) + cgSetParameter2fv(fp_param, static_cast(data)); + break; + case effect_param::kFloat3: + if (vp_param) + cgSetParameter3fv(vp_param, static_cast(data)); + if (fp_param) + cgSetParameter3fv(fp_param, static_cast(data)); + break; + case effect_param::kFloat4: + if (vp_param) + cgSetParameter4fv(vp_param, static_cast(data)); + if (fp_param) + cgSetParameter4fv(fp_param, static_cast(data)); + break; + case effect_param::kMatrix4: + if (vp_param) + cgSetMatrixParameterfr(vp_param, static_cast(data)); + if (fp_param) + cgSetMatrixParameterfr(fp_param, static_cast(data)); + break; + case effect_param::kInt: + if (vp_param) cgSetParameter1i(vp_param, *static_cast(data)); + if (fp_param) cgSetParameter1i(fp_param, *static_cast(data)); + break; + case effect_param::kBool: { + int bool_value = *static_cast(data)?1:0; + if (vp_param) cgSetParameter1i(vp_param, bool_value); + if (fp_param) cgSetParameter1i(fp_param, bool_value); + break; + } + case effect_param::kSampler: { + DCHECK_GE(low_level_param.sampler_ids.size(), 1U); + low_level_param.sampler_ids[0] = *static_cast(data); + if (effect_ == gapi->current_effect()) { + gapi->DirtyEffect(); + } + break; + } + default: + DLOG(ERROR) << "Invalid parameter type."; + return false; + } + return true; +} +EffectGL::EffectGL(CGprogram vertex_program, + CGprogram fragment_program) + : vertex_program_(vertex_program), + fragment_program_(fragment_program), + update_samplers_(true) { +} + +EffectGL::~EffectGL() { + for (ParamList::iterator it = params_.begin(); + it != params_.end(); ++it) { + (*it)->ResetEffect(); + } +} + +void EffectGL::LinkParam(EffectParamGL *param) { + params_.push_back(param); +} + +void EffectGL::UnlinkParam(EffectParamGL *param) { + std::remove(params_.begin(), params_.end(), param); +} + +// Rewrites vertex program assembly code to match GL semantics for clipping. +// This parses the source, breaking it down into pieces: +// - declaration ("!!ARBvp1.0") +// - comments (that contain the parameter information) +// - instructions +// - "END" token. +// Then it rewrites the instructions so that 'result.position' doesn't get +// written directly, instead it is written to a temporary variable. Then a +// transformation is done on that variable before outputing to +// 'result.position': +// - offset x an y by half a pixel (times w). +// - remap z from [0..w] to [-w..w]. +// +// Note that for the 1/2 pixel offset, we need a parameter that depends on the +// current viewport. This is done through 'program.env[0]' which is shared +// across all programs (so we only have to update it once when we change the +// viewport), because Cg won't use them currently (it uses 'program.local' +// instead). +static bool RewriteVertexProgramSource(String *source) { + String::size_type pos = source->find('\n'); + if (pos == String::npos) { + DLOG(ERROR) << "could not find program declaration"; + return false; + } + String decl(*source, 0, pos + 1); + String::size_type start_comments = pos + 1; + // skip the comments that contain the parameters etc. + for (; pos < source->size(); pos = source->find('\n', pos)) { + ++pos; + if (pos >= source->size()) + break; + if ((*source)[pos] != '#') + break; + } + if (pos >= source->size()) { + // we only found comments. + return false; + } + String comments(*source, start_comments, pos - start_comments); + + String::size_type end_token = source->find("\nEND", pos + 1); + if (end_token == String::npos) { + DLOG(ERROR) << "Compiled shader doesn't have an END token"; + return false; + } + String instructions(*source, pos, end_token + 1 - pos); + + // Replace accesses to 'result.position' by accesses to our temp variable + // '$O3D_HPOS'. + // '$' is a valid symbol for identifiers, but Cg doesn't seem to be using + // it, so we can use it to ensure we don't have name conflicts. + static const char kOutPositionRegister[] = "result.position"; + for (String::size_type i = instructions.find(kOutPositionRegister); + i < String::npos; i = instructions.find(kOutPositionRegister, i)) { + instructions.replace(i, strlen(kOutPositionRegister), "$O3D_HPOS"); + } + + *source = decl + + comments + + // .x = 1/viewport.width; .y = 1/viewport.height; .z = 2.0; + "PARAM $O3D_HELPER = program.env[0];\n" + "TEMP $O3D_HPOS;\n" + + instructions + + // hpos.x <- hpos.x + hpos.w / viewport.width; + // hpos.y <- hpos.y - hpos.w / viewport.height; + "MAD $O3D_HPOS.xy, $O3D_HELPER.xyyy, $O3D_HPOS.w, $O3D_HPOS.xyyy;\n" + // hpos.z <- hpos.z * 2 - hpos.w + "MAD $O3D_HPOS.z, $O3D_HPOS.z, $O3D_HELPER.z, -$O3D_HPOS.w;\n" + "MOV result.position, $O3D_HPOS;\n" + "END\n"; + return true; +} + +EffectGL *EffectGL::Create(GAPIGL *gapi, + const String& effect_code, + const String& vertex_program_entry, + const String& fragment_program_entry) { + CGcontext context = gapi->cg_context(); + // Compile the original vertex program once, to get the ARBVP1 assembly code. + CGprogram original_vp = cgCreateProgram( + context, CG_SOURCE, effect_code.c_str(), CG_PROFILE_ARBVP1, + vertex_program_entry.c_str(), NULL); + const char* listing = cgGetLastListing(context); + if (original_vp == NULL) { + DLOG(ERROR) << "Effect Compile Error: " << cgGetErrorString(cgGetError()) + << " : " << listing; + return NULL; + } + + if (listing && listing[0] != 0) { + DLOG(WARNING) << "Effect Compile Warnings: " << listing; + } + + String vp_assembly = cgGetProgramString(original_vp, CG_COMPILED_PROGRAM); + cgDestroyProgram(original_vp); + if (!RewriteVertexProgramSource(&vp_assembly)) { + return NULL; + } + CGprogram vertex_program = cgCreateProgram( + context, CG_OBJECT, vp_assembly.c_str(), CG_PROFILE_ARBVP1, + vertex_program_entry.c_str(), NULL); + listing = cgGetLastListing(context); + if (vertex_program == NULL) { + DLOG(ERROR) << "Effect post-rewrite Compile Error: " + << cgGetErrorString(cgGetError()) << " : " << listing; + return false; + } + + if (listing && listing[0] != 0) { + DLOG(WARNING) << "Effect post-rewrite compile warnings: " << listing; + } + + CHECK_GL_ERROR(); + + // If the program rewrite introduced some syntax or semantic errors, we won't + // know it until we load the program (through a GL error). + // So flush all GL errors first... + do {} while (glGetError() != GL_NO_ERROR); + + // ... Then load the program ... + cgGLLoadProgram(vertex_program); + + // ... And check for GL errors. + if (glGetError() != GL_NO_ERROR) { + DLOG(ERROR) << "Effect post-rewrite GL Error: " + << glGetString(GL_PROGRAM_ERROR_STRING_ARB) + << "\nSource: \n" + << vp_assembly; + return NULL; + } + + CGprogram fragment_program = cgCreateProgram( + context, CG_SOURCE, effect_code.c_str(), CG_PROFILE_ARBFP1, + fragment_program_entry.c_str(), NULL); + listing = cgGetLastListing(context); + if (fragment_program == NULL) { + DLOG(ERROR) << "Effect Compile Error: " + << cgGetErrorString(cgGetError()) << " : " + << listing; + return NULL; + } + + if (listing && listing[0] != 0) { + DLOG(WARNING) << "Effect Compile Warnings: " << listing; + } + + cgGLLoadProgram(fragment_program); + + // Also check for GL errors, in case Cg managed to compile, but generated a + // bad program. + if (glGetError() != GL_NO_ERROR) { + DLOG(ERROR) << "Effect GL Error: " + << glGetString(GL_PROGRAM_ERROR_STRING_ARB); + return false; + } + EffectGL *effect = new EffectGL(vertex_program, fragment_program); + effect->Initialize(); + return effect; +} + +int EffectGL::GetLowLevelParamIndexByName(const char *name) { + DCHECK(name); + for (unsigned int index = 0; index < low_level_params_.size(); ++index) { + if (!strcmp(name, low_level_params_[index].name)) { + return index; + } + } + return -1; +} + +void EffectGL::AddLowLevelParams(CGprogram prog, CGenum name_space, bool vp) { + // Iterate through parameters and add them to the vector of low level + // parameters, visiting only CGparameters that have had storage allocated to + // them, and add the params to the low_level_params_ vector. + for (CGparameter cg_param = cgGetFirstParameter(prog, name_space); + cg_param != NULL; + cg_param = cgGetNextParameter(cg_param)) { + CGenum variability = cgGetParameterVariability(cg_param); + if (variability != CG_UNIFORM) + continue; + CGenum direction = cgGetParameterDirection(cg_param); + if (direction != CG_IN) + continue; + const char *name = cgGetParameterName(cg_param); + if (!name) + continue; + + CGtype cg_type = cgGetParameterType(cg_param); + + int num_elements; + if (cg_type == CG_ARRAY) { + num_elements = cgGetArraySize(cg_param, 0); + // Substitute the first element's type for our type. + cg_type = cgGetParameterType(cgGetArrayParameter(cg_param, 0)); + } else { + num_elements = 0; + } + + int index = GetLowLevelParamIndexByName(name); + if (index < 0) { + LowLevelParam param; + param.name = name; + param.vp_param = NULL; + param.fp_param = NULL; + param.num_elements = num_elements; + + index = low_level_params_.size(); + if (cg_type == CG_SAMPLER || + cg_type == CG_SAMPLER1D || + cg_type == CG_SAMPLER2D || + cg_type == CG_SAMPLER3D || + cg_type == CG_SAMPLERCUBE) { + sampler_params_.push_back(index); + if (num_elements == 0) { + param.sampler_ids.push_back(kInvalidResource); + } else { + param.sampler_ids.resize(num_elements); + std::vector::iterator iter; + for (iter = param.sampler_ids.begin(); + iter != param.sampler_ids.end(); + ++iter) { + *iter = kInvalidResource; + } + } + } + low_level_params_.push_back(param); + } + + if (vp) { + low_level_params_[index].vp_param = cg_param; + } else { + low_level_params_[index].fp_param = cg_param; + } + } +} + +typedef std::pair SemanticMapElement; +typedef std::map SemanticMap; + +// The map batween the semantics on vertex program varying parameters names +// and vertex attribute indices under the VP_30 profile. +// TODO(gman): remove this. +SemanticMapElement semantic_map_array[] = { + SemanticMapElement("POSITION", + effect_stream::Desc(vertex_struct::kPosition, 0)), + SemanticMapElement("ATTR0", + effect_stream::Desc(vertex_struct::kPosition, 0)), + SemanticMapElement("BLENDWEIGHT", + effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)), + SemanticMapElement("ATTR1", + effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)), + SemanticMapElement("NORMAL", + effect_stream::Desc(vertex_struct::kNormal, 0)), + SemanticMapElement("ATTR2", + effect_stream::Desc(vertex_struct::kNormal, 0)), + SemanticMapElement("COLOR0", + effect_stream::Desc(vertex_struct::kColor, 0)), + SemanticMapElement("DIFFUSE", + effect_stream::Desc(vertex_struct::kColor, 0)), + SemanticMapElement("ATTR3", + effect_stream::Desc(vertex_struct::kColor, 0)), + SemanticMapElement("COLOR1", + effect_stream::Desc(vertex_struct::kColor, 1)), + SemanticMapElement("SPECULAR", + effect_stream::Desc(vertex_struct::kColor, 1)), + SemanticMapElement("ATTR4", + effect_stream::Desc(vertex_struct::kColor, 1)), + SemanticMapElement("TESSFACTOR", + effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)), + SemanticMapElement("FOGCOORD", + effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)), + SemanticMapElement("ATTR5", + effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)), + SemanticMapElement("PSIZE", + effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)), + SemanticMapElement("ATTR6", + effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)), + SemanticMapElement("BLENDINDICES", + effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)), + SemanticMapElement("ATTR7", + effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)), + SemanticMapElement("TEXCOORD0", + effect_stream::Desc(vertex_struct::kTexCoord, 0)), + SemanticMapElement("ATTR8", + effect_stream::Desc(vertex_struct::kTexCoord, 0)), + SemanticMapElement("TEXCOORD1", + effect_stream::Desc(vertex_struct::kTexCoord, 1)), + SemanticMapElement("ATTR9", + effect_stream::Desc(vertex_struct::kTexCoord, 1)), + SemanticMapElement("TEXCOORD2", + effect_stream::Desc(vertex_struct::kTexCoord, 2)), + SemanticMapElement("ATTR10", + effect_stream::Desc(vertex_struct::kTexCoord, 2)), + SemanticMapElement("TEXCOORD3", + effect_stream::Desc(vertex_struct::kTexCoord, 3)), + SemanticMapElement("ATTR11", + effect_stream::Desc(vertex_struct::kTexCoord, 3)), + SemanticMapElement("TEXCOORD4", + effect_stream::Desc(vertex_struct::kTexCoord, 4)), + SemanticMapElement("ATTR12", + effect_stream::Desc(vertex_struct::kTexCoord, 4)), + SemanticMapElement("TEXCOORD5", + effect_stream::Desc(vertex_struct::kTexCoord, 5)), + SemanticMapElement("ATTR13", + effect_stream::Desc(vertex_struct::kTexCoord, 5)), + SemanticMapElement("TEXCOORD6", + effect_stream::Desc(vertex_struct::kTexCoord, 6)), + SemanticMapElement("TANGENT", + effect_stream::Desc(vertex_struct::kTexCoord, 6)), + SemanticMapElement("ATTR14", + effect_stream::Desc(vertex_struct::kTexCoord, 7)), + SemanticMapElement("TEXCOORD7", + effect_stream::Desc(vertex_struct::kTexCoord, 7)), + SemanticMapElement("BINORMAL", + effect_stream::Desc(vertex_struct::kTexCoord, 8)), + SemanticMapElement("ATTR15", + effect_stream::Desc(vertex_struct::kTexCoord, 8)) +}; + +static SemanticMap semantic_map(semantic_map_array, + semantic_map_array + + arraysize(semantic_map_array)); + +void EffectGL::Initialize() { + AddLowLevelParams(vertex_program_, CG_PROGRAM, true); + AddLowLevelParams(vertex_program_, CG_GLOBAL, true); + AddLowLevelParams(fragment_program_, CG_PROGRAM, false); + AddLowLevelParams(fragment_program_, CG_GLOBAL, false); + + AddStreams(vertex_program_, CG_PROGRAM); + AddStreams(vertex_program_, CG_GLOBAL); +} + +// Loop over all leaf parameters, and find the ones that are bound to a +// semantic. +void EffectGL::AddStreams(CGprogram prog, CGenum name_space) { + for (CGparameter cg_param = cgGetFirstLeafParameter(prog, name_space); + cg_param != NULL; + cg_param = cgGetNextLeafParameter(cg_param)) { + CGenum variability = cgGetParameterVariability(cg_param); + if (variability != CG_VARYING) + continue; + CGenum direction = cgGetParameterDirection(cg_param); + if (direction != CG_IN) + continue; + const char* cg_semantic = cgGetParameterSemantic(cg_param); + if (cg_semantic == NULL) + continue; + + SemanticMap::iterator iter = semantic_map.find(String(cg_semantic)); + if (iter == semantic_map.end()) { + streams_.push_back(effect_stream::Desc( + vertex_struct::kUnknownSemantic, 0)); + } else { + streams_.push_back(iter->second); + } + } +} + +// Begins rendering with the effect, setting all the appropriate states. +bool EffectGL::Begin(GAPIGL *gapi) { + cgGLBindProgram(vertex_program_); + cgGLBindProgram(fragment_program_); + + // sampler->ApplyStates will mess with the texture binding on unit 0, so we + // do 2 passes. + // First to set the sampler states on the texture + for (unsigned int i = 0; i < sampler_params_.size(); ++i) { + unsigned int param_index = sampler_params_[i]; + std::vector &ids = low_level_params_[param_index].sampler_ids; + for (std::vector::iterator iter = ids.begin(); + iter != ids.end(); + ++iter) { + ResourceId id = *iter; + if (id != kInvalidResource) { + SamplerGL *sampler = gapi->GetSampler(id); + if (!sampler->ApplyStates(gapi)) { + return false; + } + } + } + } + // Second to enable/disable the sampler params. + for (unsigned int i = 0; i < sampler_params_.size(); ++i) { + unsigned int param_index = sampler_params_[i]; + const LowLevelParam &ll_param = low_level_params_[param_index]; + std::vector &ids = low_level_params_[param_index].sampler_ids; + // TODO(petersont): Rewrite the following so it handles arrays of samplers + // instead of simply bailing. + if (cgGetParameterType(ll_param.fp_param) == CG_ARRAY) + return false; + for (std::vector::iterator iter = ids.begin(); + iter != ids.end(); + ++iter) { + ResourceId id = *iter; + if (id != kInvalidResource) { + SamplerGL *sampler = gapi->GetSampler(id); + GLuint gl_texture = sampler->gl_texture(); + cgGLSetTextureParameter(ll_param.fp_param, gl_texture); + cgGLEnableTextureParameter(ll_param.fp_param); + } else { + cgGLSetTextureParameter(ll_param.fp_param, 0); + cgGLDisableTextureParameter(ll_param.fp_param); + } + } + } + return true; +} + +// Terminates rendering with the effect, resetting all the appropriate states. +void EffectGL::End(GAPIGL *gapi) { +} + +// Gets the parameter count from the list. +unsigned int EffectGL::GetParamCount() const { + return low_level_params_.size(); +} + +// Gets the number of input streams from the shader. +unsigned int EffectGL::GetStreamCount() const { + return streams_.size(); +} + +// Gets a handle to the selected parameter, and wraps it into an +// EffectParamGL if successful. +EffectParamGL *EffectGL::CreateParam(unsigned int index) { + if (index >= GetParamCount()) + return NULL; + return EffectParamGL::Create(this, index); +} + +// Provided enough room is available in the buffer, fills the Desc structure, +// appending name and semantic if any. +bool EffectGL::GetStreamDesc(unsigned int index, + unsigned int size, + void *data) { + using effect_stream::Desc; + if (size < sizeof(Desc) || index >= streams_.size()) // NOLINT + return false; + + Desc *desc = static_cast(data); + *desc = streams_[index]; + return true; +} + +// Gets a handle to the selected parameter, and wraps it into an +// EffectParamGL if successful. +EffectParamGL *EffectGL::CreateParamByName(const char *name) { + int index = GetLowLevelParamIndexByName(name); + if (index < 0) return NULL; + return EffectParamGL::Create(this, index); +} + +parse_error::ParseError GAPIGL::CreateEffect(ResourceId id, + unsigned int size, + const void *data) { + if (id == current_effect_id_) DirtyEffect(); + // Even though Assign would Destroy the effect at id, we do it explicitly in + // case the creation fails. + effects_.Destroy(id); + // Data is vp_main \0 fp_main \0 effect_text. + String vertex_program_entry; + String fragment_program_entry; + String effect_code; + if (!ParseEffectData(size, data, + &vertex_program_entry, + &fragment_program_entry, + &effect_code)) { + return parse_error::kParseInvalidArguments; + } + EffectGL * effect = EffectGL::Create(this, effect_code, + vertex_program_entry, + fragment_program_entry); + if (!effect) return parse_error::kParseInvalidArguments; + effects_.Assign(id, effect); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIGL::DestroyEffect(ResourceId id) { + if (id == current_effect_id_) DirtyEffect(); + return effects_.Destroy(id) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +parse_error::ParseError GAPIGL::SetEffect(ResourceId id) { + DirtyEffect(); + current_effect_id_ = id; + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIGL::GetParamCount(ResourceId id, + unsigned int size, + void *data) { + EffectGL *effect = effects_.Get(id); + if (!effect || size < sizeof(Uint32)) // NOLINT + return parse_error::kParseInvalidArguments; + *static_cast(data) = effect->GetParamCount(); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIGL::CreateParam(ResourceId param_id, + ResourceId effect_id, + unsigned int index) { + EffectGL *effect = effects_.Get(effect_id); + if (!effect) return parse_error::kParseInvalidArguments; + EffectParamGL *param = effect->CreateParam(index); + if (!param) return parse_error::kParseInvalidArguments; + effect_params_.Assign(param_id, param); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIGL::CreateParamByName(ResourceId param_id, + ResourceId effect_id, + unsigned int size, + const void *name) { + EffectGL *effect = effects_.Get(effect_id); + if (!effect) return parse_error::kParseInvalidArguments; + std::string string_name(static_cast(name), size); + EffectParamGL *param = effect->CreateParamByName(string_name.c_str()); + if (!param) return parse_error::kParseInvalidArguments; + effect_params_.Assign(param_id, param); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIGL::DestroyParam(ResourceId id) { + return effect_params_.Destroy(id) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +parse_error::ParseError GAPIGL::SetParamData(ResourceId id, + unsigned int size, + const void *data) { + EffectParamGL *param = effect_params_.Get(id); + if (!param) return parse_error::kParseInvalidArguments; + return param->SetData(this, size, data) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +parse_error::ParseError GAPIGL::GetParamDesc(ResourceId id, + unsigned int size, + void *data) { + EffectParamGL *param = effect_params_.Get(id); + if (!param) return parse_error::kParseInvalidArguments; + return param->GetDesc(size, data) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +parse_error::ParseError GAPIGL::GetStreamCount( + ResourceId id, + unsigned int size, + void *data) { + EffectGL *effect = effects_.Get(id); + if (!effect || size < sizeof(Uint32)) // NOLINT + return parse_error::kParseInvalidArguments; + *static_cast(data) = effect->GetStreamCount(); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIGL::GetStreamDesc(ResourceId id, + unsigned int index, + unsigned int size, + void *data) { + EffectGL *effect = effects_.Get(id); + if (!effect) return parse_error::kParseInvalidArguments; + return effect->GetStreamDesc(index, size, data) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +// If the current effect is valid, call End on it, and tag for revalidation. +void GAPIGL::DirtyEffect() { + if (validate_effect_) return; + DCHECK(current_effect_); + current_effect_->End(this); + current_effect_ = NULL; + validate_effect_ = true; +} + +// Gets the current effect, and calls Begin on it (if successful). +// Should only be called if the current effect is not valid. +bool GAPIGL::ValidateEffect() { + DCHECK(validate_effect_); + DCHECK(!current_effect_); + current_effect_ = effects_.Get(current_effect_id_); + if (!current_effect_) return false; + validate_effect_ = false; + return current_effect_->Begin(this); +} + +} // namespace o3d +} // namespace command_buffer diff --git a/o3d/command_buffer/service/effect_gl.h b/o3d/command_buffer/service/effect_gl.h new file mode 100644 index 0000000..b639489 --- /dev/null +++ b/o3d/command_buffer/service/effect_gl.h @@ -0,0 +1,162 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the declaration of the EffectParamGL and EffectGL classes. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_GL_EFFECT_GL_H_ +#define GPU_COMMAND_BUFFER_SERVICE_CROSS_GL_EFFECT_GL_H_ + +#include + +#include "command_buffer/common/gapi_interface.h" +#include "command_buffer/service/resource.h" +#include "command_buffer/service/gl_utils.h" + +namespace command_buffer { +namespace o3d { + +class GAPIGL; +class EffectGL; + +// GL version of EffectParam. +class EffectParamGL: public EffectParam { + public: + EffectParamGL(effect_param::DataType data_type, + EffectGL *effect, + unsigned int param_index); + virtual ~EffectParamGL(); + + // Sets the data into the GL effect parameter. + bool SetData(GAPIGL *gapi, unsigned int size, const void * data); + + // Gets the description of the parameter. + bool GetDesc(unsigned int size, void *data); + + // Resets the effect back-pointer. This is called when the effect gets + // destroyed, to invalidate the parameter. + void ResetEffect() { effect_ = NULL; } + + // Creates an EffectParamGL from the EffectGL, by index. + static EffectParamGL *Create(EffectGL *effect, + unsigned int index); + private: + EffectGL *effect_; + unsigned int low_level_param_index_; + DISALLOW_COPY_AND_ASSIGN(EffectParamGL); +}; + +// GL version of Effect. +class EffectGL : public Effect { + public: + EffectGL(CGprogram vertex_program, + CGprogram fragment_program); + virtual ~EffectGL(); + + // Compiles and creates an effect from source code. + static EffectGL *Create(GAPIGL *gapi, + const String &effect_code, + const String &vertex_program_entry, + const String &fragment_program_entry); + + // Applies the effect states (vertex shader, pixel shader) to GL. + bool Begin(GAPIGL *gapi); + + // Resets the effect states (vertex shader, pixel shader) to GL. + void End(GAPIGL *gapi); + + // Gets the number of parameters in the effect. + unsigned int GetParamCount() const; + + // Gets the number of streams in the effect. + unsigned int GetStreamCount() const; + + // Creates an effect parameter with the specified index. + EffectParamGL *CreateParam(unsigned int index); + + // Gets the stream data with the specified index. + bool GetStreamDesc(unsigned int index, unsigned int size, void *data); + + // Creates an effect parameter of the specified name. + EffectParamGL *CreateParamByName(const char *name); + + private: + struct LowLevelParam { + const char *name; + CGparameter vp_param; + CGparameter fp_param; + int num_elements; + std::vector sampler_ids; + }; + typedef std::vector LowLevelParamList; + typedef std::vector ParamList; + typedef std::vector StreamList; + + static CGparameter GetEitherCgParameter( + const LowLevelParam &low_level_param) { + return low_level_param.vp_param ? + low_level_param.vp_param : low_level_param.fp_param; + } + + int GetLowLevelParamIndexByName(const char *name); + void AddLowLevelParams(CGprogram prog, CGenum name_space, bool vp); + void AddStreams(CGprogram prog, CGenum name_space); + + // Creates the low level structures. + void Initialize(); + + // Links a param into this effect. + void LinkParam(EffectParamGL *param); + + // Unlinks a param into this effect. + void UnlinkParam(EffectParamGL *param); + + CGprogram vertex_program_; + CGprogram fragment_program_; + // List of all the Params created. + ParamList params_; + StreamList streams_; + // List of all the Cg parameters present in either the vertex program or the + // fragment program. + LowLevelParamList low_level_params_; + + // List of the indices of the low level params that are samplers. + std::vector sampler_params_; + bool update_samplers_; + + friend class EffectParamGL; + DISALLOW_COPY_AND_ASSIGN(EffectGL); +}; + +} // namespace o3d +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_GL_EFFECT_GL_H_ diff --git a/o3d/command_buffer/service/effect_utils.cc b/o3d/command_buffer/service/effect_utils.cc new file mode 100644 index 0000000..203aa1b --- /dev/null +++ b/o3d/command_buffer/service/effect_utils.cc @@ -0,0 +1,68 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file implements effect related utilities. + +#include "command_buffer/service/effect_utils.h" + +namespace command_buffer { + +bool ParseEffectData(unsigned int size, + const void *data, + String *vertex_program_entry, + String *fragment_program_entry, + String *effect_code) { + const char *data_char = static_cast(data); + unsigned int index = 0; + + for (; index < size && data_char[index]; ++index) { } + if (index >= size) return false; + *vertex_program_entry = String(data_char, index); + ++index; // skip \0 + unsigned int fragment_program_entry_begin = index; + + for (; index < size && data_char[index]; ++index) { } + if (index >= size) return false; + *fragment_program_entry = String(data_char + fragment_program_entry_begin, + index - fragment_program_entry_begin); + ++index; // skip \0 + unsigned int effect_code_begin = index; + + // text doesn't have to be 0-terminated, but look for one so that we don't + // construct a std::string with a '\0' in it. + for (; index < size && data_char[index]; ++index) { } + *effect_code = String(data_char + effect_code_begin, + index - effect_code_begin); + return true; +} + +} // namespace command_buffer diff --git a/o3d/command_buffer/service/effect_utils.h b/o3d/command_buffer/service/effect_utils.h new file mode 100644 index 0000000..dcfe718 --- /dev/null +++ b/o3d/command_buffer/service/effect_utils.h @@ -0,0 +1,54 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file declares some effect related utilities. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_EFFECT_UTILS_H_ +#define GPU_COMMAND_BUFFER_SERVICE_CROSS_EFFECT_UTILS_H_ + +#include "command_buffer/common/types.h" + +namespace command_buffer { + +// This function parses the data passed to the CreateEffect commands, which +// follows the following format: +// vertex_program_entry \0 fragment_program_entry \0 effect_code +// It returns the various components. +bool ParseEffectData(unsigned int size, + const void *data, + String *vertex_program_entry, + String *fragment_program_entry, + String *effect_code); + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_EFFECT_UTILS_H_ diff --git a/o3d/command_buffer/service/effect_utils_test.cc b/o3d/command_buffer/service/effect_utils_test.cc new file mode 100644 index 0000000..d37db9d --- /dev/null +++ b/o3d/command_buffer/service/effect_utils_test.cc @@ -0,0 +1,86 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the unit tests for the effect utilities. + +#include "tests/common/win/testing_common.h" +#include "command_buffer/service/cross/effect_utils.h" + +namespace o3d { +namespace command_buffer { + +TEST(ParseEffectDataTest, ValidData) { + // Tests well-formed data. + const char kEffect[] = "vertex_entry\0fragment_entry\0effect code"; + String vertex_program_entry; + String fragment_program_entry; + String effect_code; + EXPECT_TRUE(ParseEffectData(sizeof(kEffect), kEffect, &vertex_program_entry, + &fragment_program_entry, &effect_code)); + EXPECT_EQ(vertex_program_entry, "vertex_entry"); + EXPECT_EQ(fragment_program_entry, "fragment_entry"); + EXPECT_EQ(effect_code, "effect code"); + + // The terminal \0 isn't needed, check that we parse correctly without it. + EXPECT_TRUE(ParseEffectData(sizeof(kEffect)-1, kEffect, + &vertex_program_entry, &fragment_program_entry, + &effect_code)); + EXPECT_EQ(vertex_program_entry, "vertex_entry"); + EXPECT_EQ(fragment_program_entry, "fragment_entry"); + EXPECT_EQ(effect_code, "effect code"); +} + +TEST(ParseEffectDataTest, InvalidData) { + const char kEffect[] = "vertex_entry\0fragment_entry\0effect code"; + String vertex_program_entry; + String fragment_program_entry; + String effect_code; + // 0-size + EXPECT_FALSE(ParseEffectData(0, kEffect, + &vertex_program_entry, &fragment_program_entry, + &effect_code)); + // Only vertex_entry, no \0 + EXPECT_FALSE(ParseEffectData(strlen("vertex_entry"), kEffect, + &vertex_program_entry, &fragment_program_entry, + &effect_code)); + // Only vertex_entry\0 + EXPECT_FALSE(ParseEffectData(strlen("vertex_entry") + 1, kEffect, + &vertex_program_entry, &fragment_program_entry, + &effect_code)); + // Only vertex_entry\0fragment_entry, no \0 + EXPECT_FALSE(ParseEffectData(strlen("vertex_entry.fragment_entry"), kEffect, + &vertex_program_entry, &fragment_program_entry, + &effect_code)); +} + +} // namespace command_buffer +} // namespace o3d diff --git a/o3d/command_buffer/service/gapi_d3d9.cc b/o3d/command_buffer/service/gapi_d3d9.cc new file mode 100644 index 0000000..1d840eb --- /dev/null +++ b/o3d/command_buffer/service/gapi_d3d9.cc @@ -0,0 +1,392 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the implementation of the GAPID3D9 class. + +#include "command_buffer/service/gapi_d3d9.h" + +namespace command_buffer { +namespace o3d { + +GAPID3D9::GAPID3D9() + : d3d_module_(NULL), + d3dx_module_(NULL), + d3d_(NULL), + d3d_device_(NULL), + hwnd_(NULL), + current_vertex_struct_(0), + validate_streams_(true), + max_vertices_(0), + current_effect_id_(0), + validate_effect_(true), + current_effect_(NULL), + vertex_buffers_(), + index_buffers_(), + vertex_structs_(), + back_buffer_surface_(NULL), + back_buffer_depth_surface_(NULL), + current_surface_id_(kInvalidResource), + current_depth_surface_id_(kInvalidResource), + direct3d_create9_(NULL), + get_shader_constant_table_(NULL), + create_effect_(NULL), + get_shader_input_semantics_(NULL) {} + +GAPID3D9::~GAPID3D9() {} + +// Initializes a D3D interface and device, and sets basic states. +bool GAPID3D9::Initialize() { + if (!FindDirect3DFunctions()) { + Destroy(); + return false; + } + + d3d_ = Direct3DCreate(D3D_SDK_VERSION); + if (NULL == d3d_) { + LOG(ERROR) << "Failed to create the initial D3D9 Interface"; + Destroy(); + return false; + } + d3d_device_ = NULL; + + D3DDISPLAYMODE d3ddm; + d3d_->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm); + // NOTE: make sure the backbuffer matches this format, as it is + // currently currently assumed to be 32-bit 8X8R8G8B + + D3DPRESENT_PARAMETERS d3dpp; + ZeroMemory(&d3dpp, sizeof(d3dpp)); + d3dpp.Windowed = TRUE; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp.BackBufferFormat = d3ddm.Format; + d3dpp.EnableAutoDepthStencil = TRUE; + d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; // wait for vsync + // Note: SwapEffect=DISCARD is req. for multisample to function + // Note: AutoDepthStencilFormat is 16-bit (not the usual 8-bit) + + // query multisampling + const int kNumTypesToCheck = 4; + D3DMULTISAMPLE_TYPE multisample_types[] = { D3DMULTISAMPLE_5_SAMPLES, + D3DMULTISAMPLE_4_SAMPLES, + D3DMULTISAMPLE_2_SAMPLES, + D3DMULTISAMPLE_NONE }; + DWORD multisample_quality = 0; + for (int i = 0; i < kNumTypesToCheck; ++i) { + // check back-buffer for multisampling at level "i"; + // back buffer = 32-bit XRGB (i.e. no alpha) + if (SUCCEEDED(d3d_->CheckDeviceMultiSampleType( + D3DADAPTER_DEFAULT, + D3DDEVTYPE_HAL, + D3DFMT_X8R8G8B8, + true, // result is windowed + multisample_types[i], + &multisample_quality))) { + // back buffer succeeded, now check depth-buffer + // depth buffer = 24-bit, stencil = 8-bit + // NOTE: 8-bit not 16-bit like the D3DPRESENT_PARAMETERS + if (SUCCEEDED(d3d_->CheckDeviceMultiSampleType( + D3DADAPTER_DEFAULT, + D3DDEVTYPE_HAL, + D3DFMT_D24S8, + true, // result is windowed + multisample_types[i], + &multisample_quality))) { + d3dpp.MultiSampleType = multisample_types[i]; + d3dpp.MultiSampleQuality = multisample_quality - 1; + break; + } + } + } + // D3DCREATE_FPU_PRESERVE is there because Firefox 3 relies on specific FPU + // flags for its UI rendering. Apparently Firefox 2 does not, though we don't + // currently propagate that info. + // TODO: check if FPU_PRESERVE has a significant perf hit, in which + // case find out if we can disable it for Firefox 2/other browsers, and/or if + // it makes sense to switch FPU flags before/after every DX call. + DWORD flags = D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE; + if (!SUCCEEDED(d3d_->CreateDevice(D3DADAPTER_DEFAULT, + D3DDEVTYPE_HAL, + hwnd_, + flags, + &d3dpp, + &d3d_device_))) { + LOG(ERROR) << "Failed to create the D3D Device"; + Destroy(); + return false; + } + // initialise the d3d graphics state. + HR(d3d_device_->SetRenderState(D3DRS_LIGHTING, FALSE)); + HR(d3d_device_->SetRenderState(D3DRS_ZENABLE, TRUE)); + HR(d3d_device_->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE)); + return true; +} + +// Deletes the D3D9 Device and releases the D3D interface. +void GAPID3D9::Destroy() { + vertex_buffers_.DestroyAllResources(); + index_buffers_.DestroyAllResources(); + vertex_structs_.DestroyAllResources(); + effects_.DestroyAllResources(); + effect_params_.DestroyAllResources(); + textures_.DestroyAllResources(); + samplers_.DestroyAllResources(); + render_surfaces_.DestroyAllResources(); + depth_surfaces_.DestroyAllResources(); + if (d3d_device_) { + d3d_device_->Release(); + d3d_device_ = NULL; + } + if (d3d_) { + d3d_->Release(); + d3d_ = NULL; + } + if (d3dx_module_) { + FreeLibrary(d3dx_module_); + d3dx_module_ = NULL; + get_shader_constant_table_ = NULL; + create_effect_ = NULL; + get_shader_input_semantics_ = NULL; + } + if (d3d_module_) { + FreeLibrary(d3d_module_); + d3d_module_ = NULL; + direct3d_create9_ = NULL; + } +} + +// Begins the frame. +void GAPID3D9::BeginFrame() { + HR(d3d_device_->GetRenderTarget(0, &back_buffer_surface_)); + HR(d3d_device_->GetDepthStencilSurface(&back_buffer_depth_surface_)); + HR(d3d_device_->BeginScene()); +} + +// Ends the frame, presenting the back buffer. +void GAPID3D9::EndFrame() { + DirtyEffect(); + HR(d3d_device_->EndScene()); + HR(d3d_device_->Present(NULL, NULL, NULL, NULL)); + + // Release the back-buffer references. + back_buffer_surface_ = NULL; + back_buffer_depth_surface_ = NULL; +} + +// Clears the selected buffers. +void GAPID3D9::Clear(unsigned int buffers, + const RGBA &color, + float depth, + unsigned int stencil) { + DWORD flags = (buffers & kColor ? D3DCLEAR_TARGET : 0) | + (buffers & kDepth ? D3DCLEAR_ZBUFFER : 0) | + (buffers & kStencil ? D3DCLEAR_STENCIL : 0); + HR(d3d_device_->Clear(0, + NULL, + flags, + D3DCOLOR_COLORVALUE(color.red, + color.green, + color.blue, + color.alpha), + depth, + stencil)); +} + +// Sets the viewport. +void GAPID3D9::SetViewport(unsigned int x, + unsigned int y, + unsigned int width, + unsigned int height, + float z_min, + float z_max) { + D3DVIEWPORT9 viewport = {x, y, width, height, z_min, z_max}; + HR(d3d_device_->SetViewport(&viewport)); +} + +// Converts an unsigned int RGBA color into an unsigned int ARGB (DirectX) +// color. +static unsigned int RGBAToARGB(unsigned int rgba) { + return (rgba >> 8) | (rgba << 24); +} + +// Sets the current VertexStruct. Just keep track of the ID. +parse_error::ParseError GAPID3D9::SetVertexStruct(ResourceId id) { + current_vertex_struct_ = id; + validate_streams_ = true; + return parse_error::kParseNoError; +} + +bool GAPID3D9::FindDirect3DFunctions() { + d3d_module_ = LoadLibrary(TEXT("d3d9.dll")); + if (NULL == d3d_module_) { + LOG(ERROR) << "Failed to load d3d9.dll"; + return false; + } + + direct3d_create9_ = reinterpret_cast( + GetProcAddress(d3d_module_, "Direct3DCreate9")); + if (NULL == direct3d_create9_) { + LOG(ERROR) << "Failed to find Direct3DCreate9 in d3d9.dll"; + Destroy(); + return false; + } + + d3dx_module_ = LoadLibrary(TEXT("d3dx9_36.dll")); + if (NULL == d3d_module_) { + LOG(ERROR) << "Failed to load d3dx9_36.dll"; + return false; + } + + get_shader_constant_table_ = reinterpret_cast( + GetProcAddress(d3dx_module_, "D3DXGetShaderConstantTable")); + if (NULL == get_shader_constant_table_) { + LOG(ERROR) << "Failed to find D3DXGetShaderConstantTable in d3dx9_36.dll"; + Destroy(); + return false; + } + + create_effect_ = reinterpret_cast( + GetProcAddress(d3dx_module_, "D3DXCreateEffect")); + if (NULL == create_effect_) { + LOG(ERROR) << "Failed to find D3DXCreateEffect in d3dx9_36.dll"; + Destroy(); + return false; + } + + get_shader_input_semantics_ = + reinterpret_cast( + GetProcAddress(d3dx_module_, "D3DXGetShaderInputSemantics")); + if (NULL == get_shader_input_semantics_) { + LOG(ERROR) << "Failed to find D3DXGetShaderInputSemantics in d3dx9_36.dll"; + Destroy(); + return false; + } + + return true; +} + +// Sets in D3D the input streams of the current vertex struct. +bool GAPID3D9::ValidateStreams() { + DCHECK(validate_streams_); + VertexStructD3D9 *vertex_struct = vertex_structs_.Get(current_vertex_struct_); + if (!vertex_struct) { + LOG(ERROR) << "Drawing with invalid streams."; + return false; + } + max_vertices_ = vertex_struct->SetStreams(this); + validate_streams_ = false; + return max_vertices_ > 0; +} + +// Converts a GAPID3D9::PrimitiveType to a D3DPRIMITIVETYPE. +static D3DPRIMITIVETYPE D3DPrimitive( + PrimitiveType primitive_type) { + switch (primitive_type) { + case kPoints: + return D3DPT_POINTLIST; + case kLines: + return D3DPT_LINELIST; + case kLineStrips: + return D3DPT_LINESTRIP; + case kTriangles: + return D3DPT_TRIANGLELIST; + case kTriangleStrips: + return D3DPT_TRIANGLESTRIP; + case kTriangleFans: + return D3DPT_TRIANGLEFAN; + default: + LOG(FATAL) << "Invalid primitive type"; + return D3DPT_POINTLIST; + } +} + +// Draws with the current vertex struct. +parse_error::ParseError GAPID3D9::Draw( + PrimitiveType primitive_type, + unsigned int first, + unsigned int count) { + if (validate_streams_ && !ValidateStreams()) { + // TODO: add proper error management + return parse_error::kParseInvalidArguments; + } + if (validate_effect_ && !ValidateEffect()) { + // TODO: add proper error management + return parse_error::kParseInvalidArguments; + } + DCHECK(current_effect_); + if (!current_effect_->CommitParameters()) { + return parse_error::kParseInvalidArguments; + } + if (first + count > max_vertices_) { + // TODO: add proper error management + return parse_error::kParseInvalidArguments; + } + HR(d3d_device_->DrawPrimitive(D3DPrimitive(primitive_type), first, count)); + return parse_error::kParseNoError; +} + +// Draws with the current vertex struct. +parse_error::ParseError GAPID3D9::DrawIndexed( + PrimitiveType primitive_type, + ResourceId index_buffer_id, + unsigned int first, + unsigned int count, + unsigned int min_index, + unsigned int max_index) { + IndexBufferD3D9 *index_buffer = index_buffers_.Get(index_buffer_id); + if (!index_buffer) return parse_error::kParseInvalidArguments; + if (validate_streams_ && !ValidateStreams()) { + // TODO: add proper error management + return parse_error::kParseInvalidArguments; + } + if (validate_effect_ && !ValidateEffect()) { + // TODO: add proper error management + return parse_error::kParseInvalidArguments; + } + DCHECK(current_effect_); + if (!current_effect_->CommitParameters()) { + return parse_error::kParseInvalidArguments; + } + if ((min_index >= max_vertices_) || (max_index > max_vertices_)) { + // TODO: add proper error management + return parse_error::kParseInvalidArguments; + } + + HR(d3d_device_->SetIndices(index_buffer->d3d_index_buffer())); + HR(d3d_device_->DrawIndexedPrimitive(D3DPrimitive(primitive_type), 0, + min_index, max_index - min_index + 1, + first, count)); + return parse_error::kParseNoError; +} + +} // namespace o3d +} // namespace command_buffer diff --git a/o3d/command_buffer/service/gapi_d3d9.h b/o3d/command_buffer/service/gapi_d3d9.h new file mode 100644 index 0000000..bac33a8 --- /dev/null +++ b/o3d/command_buffer/service/gapi_d3d9.h @@ -0,0 +1,508 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the GAPID3D9 class, implementing the GAPI interface for +// D3D9. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_WIN_D3D9_GAPI_D3D9_H_ +#define GPU_COMMAND_BUFFER_SERVICE_WIN_D3D9_GAPI_D3D9_H_ + +#include "command_buffer/common/gapi_interface.h" +#include "command_buffer/service/d3d9_utils.h" +#include "command_buffer/service/geometry_d3d9.h" +#include "command_buffer/service/effect_d3d9.h" +#include "command_buffer/service/texture_d3d9.h" +#include "command_buffer/service/sampler_d3d9.h" +#include "command_buffer/service/render_surface_d3d9.h" + +namespace command_buffer { +namespace o3d { + +// This class implements the GAPI interface for D3D9. +class GAPID3D9 : public GAPIInterface { + public: + GAPID3D9(); + virtual ~GAPID3D9(); + + void set_hwnd(HWND hwnd) { hwnd_ = hwnd; } + HWND hwnd() const { return hwnd_; } + + // Initializes the graphics context, bound to a window. + // Returns: + // true if successful. + virtual bool Initialize(); + + // Destroys the graphics context. + virtual void Destroy(); + + // Implements the BeginFrame function for D3D9. + virtual void BeginFrame(); + + // Implements the EndFrame function for D3D9. + virtual void EndFrame(); + + // Implements the Clear function for D3D9. + virtual void Clear(unsigned int buffers, + const RGBA &color, + float depth, + unsigned int stencil); + + // Implements the SetViewport function for D3D9. + virtual void SetViewport(unsigned int x, + unsigned int y, + unsigned int width, + unsigned int height, + float z_min, + float z_max); + + // Implements the CreateVertexBuffer function for D3D9. + virtual ParseError CreateVertexBuffer(ResourceId id, + unsigned int size, + unsigned int flags); + + // Implements the DestroyVertexBuffer function for D3D9. + virtual ParseError DestroyVertexBuffer(ResourceId id); + + // Implements the SetVertexBufferData function for D3D9. + virtual ParseError SetVertexBufferData(ResourceId id, + unsigned int offset, + unsigned int size, + const void *data); + + // Implements the GetVertexBufferData function for D3D9. + virtual ParseError GetVertexBufferData(ResourceId id, + unsigned int offset, + unsigned int size, + void *data); + + // Implements the CreateIndexBuffer function for D3D9. + virtual ParseError CreateIndexBuffer(ResourceId id, + unsigned int size, + unsigned int flags); + + // Implements the DestroyIndexBuffer function for D3D9. + virtual ParseError DestroyIndexBuffer(ResourceId id); + + // Implements the SetIndexBufferData function for D3D9. + virtual ParseError SetIndexBufferData(ResourceId id, + unsigned int offset, + unsigned int size, + const void *data); + + // Implements the GetIndexBufferData function for D3D9. + virtual ParseError GetIndexBufferData(ResourceId id, + unsigned int offset, + unsigned int size, + void *data); + + // Implements the CreateVertexStruct function for D3D9. + virtual ParseError CreateVertexStruct(ResourceId id, + unsigned int input_count); + + // Implements the DestroyVertexStruct function for D3D9. + virtual ParseError DestroyVertexStruct(ResourceId id); + + // Implements the SetVertexInput function for D3D9. + virtual ParseError SetVertexInput(ResourceId vertex_struct_id, + unsigned int input_index, + ResourceId vertex_buffer_id, + unsigned int offset, + unsigned int stride, + vertex_struct::Type type, + vertex_struct::Semantic semantic, + unsigned int semantic_index); + + // Implements the SetVertexStruct function for D3D9. + virtual ParseError SetVertexStruct(ResourceId id); + + // Implements the Draw function for D3D9. + virtual ParseError Draw(PrimitiveType primitive_type, + unsigned int first, + unsigned int count); + + // Implements the DrawIndexed function for D3D9. + virtual ParseError DrawIndexed(PrimitiveType primitive_type, + ResourceId index_buffer_id, + unsigned int first, + unsigned int count, + unsigned int min_index, + unsigned int max_index); + + // Implements the CreateEffect function for D3D9. + virtual ParseError CreateEffect(ResourceId id, + unsigned int size, + const void *data); + + // Implements the DestroyEffect function for D3D9. + virtual ParseError DestroyEffect(ResourceId id); + + // Implements the SetEffect function for D3D9. + virtual ParseError SetEffect(ResourceId id); + + // Implements the GetParamCount function for D3D9. + virtual ParseError GetParamCount(ResourceId id, + unsigned int size, + void *data); + + // Implements the CreateParam function for D3D9. + virtual ParseError CreateParam(ResourceId param_id, + ResourceId effect_id, + unsigned int index); + + // Implements the CreateParamByName function for D3D9. + virtual ParseError CreateParamByName(ResourceId param_id, + ResourceId effect_id, + unsigned int size, + const void *name); + + // Implements the DestroyParam function for D3D9. + virtual ParseError DestroyParam(ResourceId id); + + // Implements the SetParamData function for D3D9. + virtual ParseError SetParamData(ResourceId id, + unsigned int size, + const void *data); + + // Implements the GetParamDesc function for D3D9. + virtual ParseError GetParamDesc(ResourceId id, + unsigned int size, + void *data); + + // Implements the GetStreamCount function for D3D9. + virtual ParseError GetStreamCount(ResourceId id, + unsigned int size, + void *data); + + // Implements the GetStreamDesc function for D3D9. + virtual ParseError GetStreamDesc(ResourceId id, + unsigned int index, + unsigned int size, + void *data); + + // Implements the CreateTexture2D function for D3D9. + virtual ParseError CreateTexture2D(ResourceId id, + unsigned int width, + unsigned int height, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces); + + // Implements the CreateTexture3D function for D3D9. + virtual ParseError CreateTexture3D(ResourceId id, + unsigned int width, + unsigned int height, + unsigned int depth, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces); + + // Implements the CreateTextureCube function for D3D9. + virtual ParseError CreateTextureCube(ResourceId id, + unsigned int side, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces); + + // Implements the SetTextureData function for D3D9. + virtual ParseError SetTextureData(ResourceId id, + unsigned int x, + unsigned int y, + unsigned int z, + unsigned int width, + unsigned int height, + unsigned int depth, + unsigned int level, + texture::Face face, + unsigned int pitch, + unsigned int slice_pitch, + unsigned int size, + const void *data); + + // Implements the GetTextureData function for D3D9. + virtual ParseError GetTextureData(ResourceId id, + unsigned int x, + unsigned int y, + unsigned int z, + unsigned int width, + unsigned int height, + unsigned int depth, + unsigned int level, + texture::Face face, + unsigned int pitch, + unsigned int slice_pitch, + unsigned int size, + void *data); + + // Implements the DestroyTexture function for D3D9. + virtual ParseError DestroyTexture(ResourceId id); + + // Implements the CreateSampler function for D3D9. + virtual ParseError CreateSampler(ResourceId id); + + // Implements the DestroySampler function for D3D9. + virtual ParseError DestroySampler(ResourceId id); + + // Implements the SetSamplerStates function for D3D9. + virtual ParseError SetSamplerStates(ResourceId id, + sampler::AddressingMode addressing_u, + sampler::AddressingMode addressing_v, + sampler::AddressingMode addressing_w, + sampler::FilteringMode mag_filter, + sampler::FilteringMode min_filter, + sampler::FilteringMode mip_filter, + unsigned int max_anisotropy); + + // Implements the SetSamplerBorderColor function for D3D9. + virtual ParseError SetSamplerBorderColor(ResourceId id, const RGBA &color); + + // Implements the SetSamplerTexture function for D3D9. + virtual ParseError SetSamplerTexture(ResourceId id, ResourceId texture_id); + + // Implements the SetScissor function for D3D9. + virtual void SetScissor(bool enable, + unsigned int x, + unsigned int y, + unsigned int width, + unsigned int height); + + // Implements the SetPointLineRaster function for D3D9. + virtual void SetPointLineRaster(bool line_smooth, + bool point_sprite, + float point_size); + + // Implements the SetPolygonOffset function for D3D9. + virtual void SetPolygonOffset(float slope_factor, float units); + + // Implements the SetPolygonRaster function for D3D9. + virtual void SetPolygonRaster(PolygonMode fill_mode, + FaceCullMode cull_mode); + + // Implements the SetAlphaTest function for D3D9. + virtual void SetAlphaTest(bool enable, + float reference, + Comparison comp); + + // Implements the SetDepthTest function for D3D9. + virtual void SetDepthTest(bool enable, + bool write_enable, + Comparison comp); + + // Implements the SetStencilTest function for D3D9. + virtual void SetStencilTest(bool enable, + bool separate_ccw, + unsigned int write_mask, + unsigned int compare_mask, + unsigned int ref, + Uint32 func_ops); + + // Implements the SetColorWritefunction for D3D9. + virtual void SetColorWrite(bool red, + bool green, + bool blue, + bool alpha, + bool dither); + + // Implements the SetBlending function for D3D9. + virtual void SetBlending(bool enable, + bool separate_alpha, + BlendEq color_eq, + BlendFunc color_src_func, + BlendFunc color_dst_func, + BlendEq alpha_eq, + BlendFunc alpha_src_func, + BlendFunc alpha_dst_func); + + // Implements the SetBlendingColor function for D3D9. + virtual void SetBlendingColor(const RGBA &color); + + // Implements the CreateRenderSurface function for D3D9. + virtual ParseError CreateRenderSurface(ResourceId id, + unsigned int width, + unsigned int height, + unsigned int mip_level, + unsigned int side, + ResourceId texture_id); + + // Implements the DestroyRenderSurface function for D3D9. + virtual ParseError DestroyRenderSurface(ResourceId id); + + // Implements the CreateDepthSurface function for D3D9. + virtual ParseError CreateDepthSurface(ResourceId id, + unsigned int width, + unsigned int height); + + // Implements teh DestroyDepthSurface function for D3D9. + virtual ParseError DestroyDepthSurface(ResourceId id); + + // Implements the SetRenderSurface function for D3D9. + virtual ParseError SetRenderSurface(ResourceId render_surface_id, + ResourceId depth_stencil_id); + + // Implements the SetBackSurfaces function for D3D9. + virtual void SetBackSurfaces(); + + // Gets the D3D9 device. + IDirect3DDevice9 *d3d_device() const { return d3d_device_; } + + // Gets a vertex buffer by resource ID. + VertexBufferD3D9 *GetVertexBuffer(ResourceId id) { + return vertex_buffers_.Get(id); + } + + // Gets a texture by resource ID. + TextureD3D9 *GetTexture(ResourceId id) { + return textures_.Get(id); + } + + // Gets a sampler by resource ID. + SamplerD3D9 *GetSampler(ResourceId id) { + return samplers_.Get(id); + } + + EffectD3D9 *current_effect() { return current_effect_; } + + // Direct3D functions cannot be called directly because the DLLs are loaded + // dynamically via LoadLibrary. If you need to add another Direct3D function + // add another function here, a typedef matching the signature and a member + // variable of that type below. Then add code to FindDirect3DFunctions to + // get the address of that function out of the DLL and assign it to the + // member variable. Be careful to initialize the value of the variable to + // NULL in the constructor and to set it to again NULL in Destroy. + + IDirect3D9* Direct3DCreate(UINT version) { + DCHECK(direct3d_create9_); + return direct3d_create9_(version); + } + + HRESULT D3DXGetShaderConstantTable(const DWORD* function, + LPD3DXCONSTANTTABLE* table) { + DCHECK(get_shader_constant_table_); + return get_shader_constant_table_(function, table); + } + + HRESULT D3DXCreateEffect(LPDIRECT3DDEVICE9 device, + LPCVOID src_data, + UINT src_data_len, + CONST D3DXMACRO * defines, + LPD3DXINCLUDE include, + DWORD flags, + LPD3DXEFFECTPOOL pool, + LPD3DXEFFECT * effect, + LPD3DXBUFFER * compilation_errors) { + DCHECK(create_effect_); + return create_effect_(device, src_data, src_data_len, defines, include, + flags, pool, effect, compilation_errors); + } + + HRESULT D3DXGetShaderInputSemantics(const DWORD* function, + D3DXSEMANTIC* semantics, + UINT* count) { + DCHECK(get_shader_input_semantics_); + return get_shader_input_semantics_(function, semantics, count); + } + + private: + bool FindDirect3DFunctions(); + + // Validates the current vertex struct to D3D, setting the streams. + bool ValidateStreams(); + // Validates the current effect to D3D. This sends the effect states to D3D. + bool ValidateEffect(); + // "Dirty" the current effect. This resets the effect states to D3D, and + // requires ValidateEffect() to be called before further draws occur. + void DirtyEffect(); + + // Module handle for d3d9.dll. + HMODULE d3d_module_; + + // Module handle for d3dx9_n.dll + HMODULE d3dx_module_; + + LPDIRECT3D9 d3d_; + LPDIRECT3DDEVICE9 d3d_device_; + HWND hwnd_; + ResourceId current_vertex_struct_; + bool validate_streams_; + unsigned int max_vertices_; + ResourceId current_effect_id_; + bool validate_effect_; + EffectD3D9 *current_effect_; + IDirect3DSurface9* back_buffer_surface_; + IDirect3DSurface9* back_buffer_depth_surface_; + ResourceId current_surface_id_; + ResourceId current_depth_surface_id_; + + ResourceMap vertex_buffers_; + ResourceMap index_buffers_; + ResourceMap vertex_structs_; + ResourceMap effects_; + ResourceMap effect_params_; + ResourceMap textures_; + ResourceMap samplers_; + ResourceMap render_surfaces_; + ResourceMap depth_surfaces_; + + typedef IDirect3D9* (WINAPI *Direct3DCreate9Proc)(UINT version); + Direct3DCreate9Proc direct3d_create9_; + + typedef HRESULT (WINAPI *D3DXGetShaderConstantTableProc)( + const DWORD* function, + LPD3DXCONSTANTTABLE* table); + D3DXGetShaderConstantTableProc get_shader_constant_table_; + + typedef HRESULT (WINAPI *D3DXCreateEffectProc)( + LPDIRECT3DDEVICE9 device, + LPCVOID src_data, + UINT src_data_len, + CONST D3DXMACRO * defines, + LPD3DXINCLUDE include, + DWORD flags, + LPD3DXEFFECTPOOL pool, + LPD3DXEFFECT * effect, + LPD3DXBUFFER * compilation_errors); + D3DXCreateEffectProc create_effect_; + + typedef HRESULT (WINAPI *D3DXGetShaderInputSemanticsProc)( + const DWORD* function, + D3DXSEMANTIC* semantics, + UINT* count); + D3DXGetShaderInputSemanticsProc get_shader_input_semantics_; +}; + +} // namespace o3d +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_WIN_D3D9_GAPI_D3D9_H_ + diff --git a/o3d/command_buffer/service/gapi_decoder.cc b/o3d/command_buffer/service/gapi_decoder.cc new file mode 100644 index 0000000..ec079f9 --- /dev/null +++ b/o3d/command_buffer/service/gapi_decoder.cc @@ -0,0 +1,938 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This class contains the implementation of the GAPI decoder class, decoding +// GAPI commands into calls to a GAPIInterface class. + +#include "base/cross/bits.h" +#include "command_buffer/common/gapi_interface.h" +#include "command_buffer/service/gapi_decoder.h" + +namespace command_buffer { +namespace o3d { + +namespace { + +// Returns the address of the first byte after a struct. +template +const void* AddressAfterStruct(const T& pod) { + return reinterpret_cast(&pod) + sizeof(pod); +} + +// Returns the size in bytes of the data of an Immediate command, a command with +// its data inline in the command buffer. +template +unsigned int ImmediateDataSize(uint32 arg_count, const T& pod) { + return static_cast( + (arg_count + 1 - ComputeNumEntries(sizeof(pod))) * + sizeof(CommandBufferEntry)); // NOLINT +} + +// A struct to hold info about each command. +struct CommandInfo { + int arg_flags; // How to handle the arguments for this command + int arg_count; // How many arguments are expected for this command. +}; + +// A table of CommandInfo for all the commands. +const CommandInfo g_command_info[] = { + #define O3D_COMMAND_BUFFER_CMD_OP(name) { \ + name::kArgFlags, \ + sizeof(name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ \ + + O3D_COMMAND_BUFFER_CMDS(O3D_COMMAND_BUFFER_CMD_OP) + + #undef O3D_COMMAND_BUFFER_CMD_OP +}; + +} // anonymous namespace. + +// Decode command with its arguments, and call the corresponding method. +// Note: args is a pointer to the command buffer. As such, it could be changed +// by a (malicious) client at any time, so if validation has to happen, it +// should operate on a copy of them. +parse_error::ParseError GAPIDecoder::DoCommand( + unsigned int command, + unsigned int arg_count, + const void* cmd_data) { + unsigned int command_index = command - kStartPoint - 1; + if (command_index < arraysize(g_command_info)) { + const CommandInfo& info = g_command_info[command_index]; + unsigned int info_arg_count = static_cast(info.arg_count); + if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) || + (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) { + switch (command) { + #define O3D_COMMAND_BUFFER_CMD_OP(name) \ + case name::kCmdId: \ + return Handle ## name( \ + arg_count, \ + *static_cast(cmd_data)); \ + + O3D_COMMAND_BUFFER_CMDS(O3D_COMMAND_BUFFER_CMD_OP) + + #undef O3D_COMMAND_BUFFER_CMD_OP + } + } else { + return parse_error::kParseInvalidArguments; + } + } + return DoCommonCommand(command, arg_count, cmd_data); + return parse_error::kParseUnknownCommand; +} + + // Overridden from AsyncAPIInterface. +const char* GAPIDecoder::GetCommandName(unsigned int command_id) const { + if (command_id > kStartPoint && command_id < kNumCommands) { + return o3d::GetCommandName(static_cast(command_id)); + } + return GetCommonCommandName(static_cast(command_id)); +} + +parse_error::ParseError GAPIDecoder::HandleBeginFrame( + uint32 arg_count, + const BeginFrame& args) { + gapi_->BeginFrame(); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIDecoder::HandleEndFrame( + uint32 arg_count, + const EndFrame& args) { + gapi_->EndFrame(); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIDecoder::HandleClear( + uint32 arg_count, + const Clear& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 buffers = args.buffers; + if (buffers & ~kAllBuffers) + return parse_error::kParseInvalidArguments; + RGBA rgba; + rgba.red = args.red; + rgba.green = args.green; + rgba.blue = args.blue; + rgba.alpha = args.alpha; + gapi_->Clear(buffers, rgba, args.depth, args.stencil); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIDecoder::HandleSetViewport( + uint32 arg_count, + const SetViewport& args) { + gapi_->SetViewport(args.left, + args.top, + args.width, + args.height, + args.z_min, + args.z_max); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIDecoder::HandleCreateVertexBuffer( + uint32 arg_count, + const CreateVertexBuffer& args) { + return gapi_->CreateVertexBuffer( + args.vertex_buffer_id, args.size, args.flags); +} + +parse_error::ParseError GAPIDecoder::HandleDestroyVertexBuffer( + uint32 arg_count, + const DestroyVertexBuffer& args) { + return gapi_->DestroyVertexBuffer(args.vertex_buffer_id); +} + +parse_error::ParseError GAPIDecoder::HandleSetVertexBufferDataImmediate( + uint32 arg_count, + const SetVertexBufferDataImmediate& args) { + uint32 size = ImmediateDataSize(arg_count, args); + if (size == 0) { + return parse_error::kParseNoError; + } + return gapi_->SetVertexBufferData(args.vertex_buffer_id, args.offset, + size, + AddressAfterStruct(args)); +} + +parse_error::ParseError GAPIDecoder::HandleSetVertexBufferData( + uint32 arg_count, + const SetVertexBufferData& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return parse_error::kParseInvalidArguments; + return gapi_->SetVertexBufferData( + args.vertex_buffer_id, args.offset, size, data); +} + +parse_error::ParseError GAPIDecoder::HandleGetVertexBufferData( + uint32 arg_count, + const GetVertexBufferData& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return parse_error::kParseInvalidArguments; + return gapi_->GetVertexBufferData( + args.vertex_buffer_id, args.offset, size, data); +} + +parse_error::ParseError GAPIDecoder::HandleCreateIndexBuffer( + uint32 arg_count, + const CreateIndexBuffer& args) { + return gapi_->CreateIndexBuffer(args.index_buffer_id, args.size, args.flags); +} + +parse_error::ParseError GAPIDecoder::HandleDestroyIndexBuffer( + uint32 arg_count, + const DestroyIndexBuffer& args) { + return gapi_->DestroyIndexBuffer(args.index_buffer_id); +} + +parse_error::ParseError GAPIDecoder::HandleSetIndexBufferDataImmediate( + uint32 arg_count, + const SetIndexBufferDataImmediate& args) { + uint32 size = ImmediateDataSize(arg_count, args); + if (size == 0) { + return parse_error::kParseNoError; + } + return gapi_->SetIndexBufferData(args.index_buffer_id, args.offset, size, + AddressAfterStruct(args)); +} + +parse_error::ParseError GAPIDecoder::HandleSetIndexBufferData( + uint32 arg_count, + const SetIndexBufferData& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return parse_error::kParseInvalidArguments; + return gapi_->SetIndexBufferData( + args.index_buffer_id, args.offset, size, data); +} + +parse_error::ParseError GAPIDecoder::HandleGetIndexBufferData( + uint32 arg_count, + const GetIndexBufferData& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return parse_error::kParseInvalidArguments; + return gapi_->GetIndexBufferData( + args.index_buffer_id, args.offset, size, data); +} + +parse_error::ParseError GAPIDecoder::HandleCreateVertexStruct( + uint32 arg_count, + const CreateVertexStruct& args) { + return gapi_->CreateVertexStruct(args.vertex_struct_id, args.input_count); +} + +parse_error::ParseError GAPIDecoder::HandleDestroyVertexStruct( + uint32 arg_count, + const DestroyVertexStruct& args) { + return gapi_->DestroyVertexStruct(args.vertex_struct_id); +} + +parse_error::ParseError GAPIDecoder::HandleSetVertexInput( + uint32 arg_count, + const SetVertexInput& args) { + unsigned int type_stride_semantic = args.type_stride_semantic; + unsigned int semantic_index = + SetVertexInput::SemanticIndex::Get(type_stride_semantic); + unsigned int semantic = + SetVertexInput::Semantic::Get(type_stride_semantic); + unsigned int type = + SetVertexInput::Type::Get(type_stride_semantic); + unsigned int stride = + SetVertexInput::Stride::Get(type_stride_semantic); + if (semantic >= vertex_struct::kNumSemantics || + type >= vertex_struct::kNumTypes || stride == 0) + return parse_error::kParseInvalidArguments; + return gapi_->SetVertexInput( + args.vertex_struct_id, args.input_index, args.vertex_buffer_id, + args.offset, stride, + static_cast(type), + static_cast(semantic), + semantic_index); +} + +parse_error::ParseError GAPIDecoder::HandleSetVertexStruct( + uint32 arg_count, + const SetVertexStruct& args) { + return gapi_->SetVertexStruct(args.vertex_struct_id); +} + +parse_error::ParseError GAPIDecoder::HandleDraw( + uint32 arg_count, + const Draw& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 primitive_type = args.primitive_type; + if (primitive_type >= kMaxPrimitiveType) + return parse_error::kParseInvalidArguments; + return gapi_->Draw( + static_cast(primitive_type), + args.first, args.count); +} + +parse_error::ParseError GAPIDecoder::HandleDrawIndexed( + uint32 arg_count, + const DrawIndexed& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 primitive_type = args.primitive_type; + if (primitive_type >= kMaxPrimitiveType) + return parse_error::kParseInvalidArguments; + return gapi_->DrawIndexed( + static_cast(primitive_type), + args.index_buffer_id, + args.first, args.count, args.min_index, args.max_index); +} + +parse_error::ParseError GAPIDecoder::HandleCreateEffect( + uint32 arg_count, + const CreateEffect& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return parse_error::kParseInvalidArguments; + return gapi_->CreateEffect(args.effect_id, size, data); +} + +parse_error::ParseError GAPIDecoder::HandleCreateEffectImmediate( + uint32 arg_count, + const CreateEffectImmediate& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + uint32 data_size = ImmediateDataSize(arg_count, args); + if (size > data_size) { + return parse_error::kParseInvalidArguments; + } + if (data_size == 0) { + return parse_error::kParseNoError; + } + return gapi_->CreateEffect(args.effect_id, size, AddressAfterStruct(args)); +} + +parse_error::ParseError GAPIDecoder::HandleDestroyEffect( + uint32 arg_count, + const DestroyEffect& args) { + return gapi_->DestroyEffect(args.effect_id); +} + +parse_error::ParseError GAPIDecoder::HandleSetEffect( + uint32 arg_count, + const SetEffect& args) { + return gapi_->SetEffect(args.effect_id); +} + +parse_error::ParseError GAPIDecoder::HandleGetParamCount( + uint32 arg_count, + const GetParamCount& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return parse_error::kParseInvalidArguments; + return gapi_->GetParamCount(args.effect_id, size, data); +} + +parse_error::ParseError GAPIDecoder::HandleCreateParam( + uint32 arg_count, + const CreateParam& args) { + return gapi_->CreateParam(args.param_id, args.effect_id, args.index); +} + +parse_error::ParseError GAPIDecoder::HandleCreateParamByName( + uint32 arg_count, + const CreateParamByName& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return parse_error::kParseInvalidArguments; + return gapi_->CreateParamByName(args.param_id, args.effect_id, size, + data); +} + +parse_error::ParseError GAPIDecoder::HandleCreateParamByNameImmediate( + uint32 arg_count, + const CreateParamByNameImmediate& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + uint32 data_size = ImmediateDataSize(arg_count, args); + if (size > data_size) + return parse_error::kParseInvalidArguments; + if (data_size == 0) { + return parse_error::kParseNoError; + } + return gapi_->CreateParamByName(args.param_id, args.effect_id, size, + AddressAfterStruct(args)); +} + +parse_error::ParseError GAPIDecoder::HandleDestroyParam( + uint32 arg_count, + const DestroyParam& args) { + return gapi_->DestroyParam(args.param_id); +} + +parse_error::ParseError GAPIDecoder::HandleSetParamData( + uint32 arg_count, + const SetParamData& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return parse_error::kParseInvalidArguments; + return gapi_->SetParamData(args.param_id, size, data); +} + +parse_error::ParseError GAPIDecoder::HandleSetParamDataImmediate( + uint32 arg_count, + const SetParamDataImmediate& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + uint32 data_size = ImmediateDataSize(arg_count, args); + if (size > data_size) { + return parse_error::kParseInvalidArguments; + } + if (data_size == 0) { + return parse_error::kParseNoError; + } + return gapi_->SetParamData(args.param_id, size, AddressAfterStruct(args)); +} + +parse_error::ParseError GAPIDecoder::HandleGetParamDesc( + uint32 arg_count, + const GetParamDesc& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return parse_error::kParseInvalidArguments; + return gapi_->GetParamDesc(args.param_id, size, data); +} + +parse_error::ParseError GAPIDecoder::HandleGetStreamCount( + uint32 arg_count, + const GetStreamCount& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return parse_error::kParseInvalidArguments; + return gapi_->GetStreamCount(args.effect_id, size, data); +} + +parse_error::ParseError GAPIDecoder::HandleGetStreamDesc( + uint32 arg_count, + const GetStreamDesc& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return parse_error::kParseInvalidArguments; + return gapi_->GetStreamDesc(args.effect_id, args.index, size, data); +} + +parse_error::ParseError GAPIDecoder::HandleDestroyTexture( + uint32 arg_count, + const DestroyTexture& args) { + return gapi_->DestroyTexture(args.texture_id); +} + +parse_error::ParseError GAPIDecoder::HandleCreateTexture2d( + uint32 arg_count, + const CreateTexture2d& args) { + unsigned int width_height = args.width_height; + unsigned int levels_format_flags = args.levels_format_flags; + unsigned int width = CreateTexture2d::Width::Get(width_height); + unsigned int height = CreateTexture2d::Height::Get(width_height); + unsigned int levels = CreateTexture2d::Levels::Get(levels_format_flags); + unsigned int unused = CreateTexture2d::Unused::Get(levels_format_flags); + unsigned int format = CreateTexture2d::Format::Get(levels_format_flags); + unsigned int flags = CreateTexture2d::Flags::Get(levels_format_flags); + unsigned int max_levels = + 1 + ::o3d::base::bits::Log2Ceiling(std::max(width, height)); + if ((width == 0) || (height == 0) || (levels > max_levels) || + (unused != 0) || (format == texture::kUnknown) || (levels == 0)) + return parse_error::kParseInvalidArguments; + bool enable_render_surfaces = !!flags; + return gapi_->CreateTexture2D(args.texture_id, width, height, levels, + static_cast(format), flags, + enable_render_surfaces); +} + +parse_error::ParseError GAPIDecoder::HandleCreateTexture3d( + uint32 arg_count, + const CreateTexture3d& args) { + unsigned int width_height = args.width_height; + unsigned int depth_unused = args.depth_unused; + unsigned int levels_format_flags = args.levels_format_flags; + unsigned int width = CreateTexture3d::Width::Get(width_height); + unsigned int height = CreateTexture3d::Height::Get(width_height); + unsigned int depth = CreateTexture3d::Depth::Get(depth_unused); + unsigned int unused1 = CreateTexture3d::Unused1::Get(depth_unused); + unsigned int levels = CreateTexture3d::Levels::Get(levels_format_flags); + unsigned int unused2 = CreateTexture3d::Unused2::Get(levels_format_flags); + unsigned int format = CreateTexture3d::Format::Get(levels_format_flags); + unsigned int flags = CreateTexture3d::Flags::Get(levels_format_flags); + unsigned int max_levels = + 1 + ::o3d::base::bits::Log2Ceiling(std::max(depth, std::max(width, height))); + if ((width == 0) || (height == 0) || (depth == 0) || + (levels > max_levels) || (unused1 != 0) || (unused2 != 0) || + (format == texture::kUnknown) || (levels == 0)) + return parse_error::kParseInvalidArguments; + bool enable_render_surfaces = !!flags; + return gapi_->CreateTexture3D(args.texture_id, width, height, depth, levels, + static_cast(format), flags, + enable_render_surfaces); +} + +parse_error::ParseError GAPIDecoder::HandleCreateTextureCube( + uint32 arg_count, + const CreateTextureCube& args) { + unsigned int side_unused = args.edge_length; + unsigned int levels_format_flags = args.levels_format_flags; + unsigned int side = CreateTextureCube::Side::Get(side_unused); + unsigned int unused1 = CreateTextureCube::Unused1::Get(side_unused); + unsigned int levels = CreateTextureCube::Levels::Get(levels_format_flags); + unsigned int unused2 = CreateTextureCube::Unused2::Get(levels_format_flags); + unsigned int format = CreateTextureCube::Format::Get(levels_format_flags); + unsigned int flags = CreateTextureCube::Flags::Get(levels_format_flags); + unsigned int max_levels = 1 + ::o3d::base::bits::Log2Ceiling(side); + if ((side == 0) || (levels > max_levels) || (unused1 != 0) || + (unused2 != 0) || (format == texture::kUnknown) || (levels == 0)) + return parse_error::kParseInvalidArguments; + bool enable_render_surfaces = !!flags; + return gapi_->CreateTextureCube(args.texture_id, side, levels, + static_cast(format), + flags, enable_render_surfaces); +} + +parse_error::ParseError GAPIDecoder::HandleSetTextureData( + uint32 arg_count, + const SetTextureData& args) { + unsigned int x_y = args.x_y; + unsigned int width_height = args.width_height; + unsigned int z_depth = args.z_depth; + unsigned int level_face = args.level_face; + unsigned int size = args.size; + unsigned int x = SetTextureData::X::Get(x_y); + unsigned int y = SetTextureData::Y::Get(x_y); + unsigned int width = SetTextureData::Width::Get(width_height); + unsigned int height = SetTextureData::Height::Get(width_height); + unsigned int z = SetTextureData::Z::Get(z_depth); + unsigned int depth = SetTextureData::Depth::Get(z_depth); + unsigned int level = SetTextureData::Level::Get(level_face); + unsigned int face = SetTextureData::Face::Get(level_face); + unsigned int unused = SetTextureData::Unused::Get(level_face); + const void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, size); + if (face >= 6 || unused != 0 || !data) + return parse_error::kParseInvalidArguments; + return gapi_->SetTextureData( + args.texture_id, x, y, z, width, height, depth, level, + static_cast(face), args.row_pitch, + args.slice_pitch, size, data); +} + +parse_error::ParseError GAPIDecoder::HandleSetTextureDataImmediate( + uint32 arg_count, + const SetTextureDataImmediate& args) { + unsigned int x_y = args.x_y; + unsigned int width_height = args.width_height; + unsigned int z_depth = args.z_depth; + unsigned int level_face = args.level_face; + unsigned int size = args.size; + unsigned int x = SetTextureDataImmediate::X::Get(x_y); + unsigned int y = SetTextureDataImmediate::Y::Get(x_y); + unsigned int width = SetTextureDataImmediate::Width::Get(width_height); + unsigned int height = SetTextureDataImmediate::Height::Get(width_height); + unsigned int z = SetTextureDataImmediate::Z::Get(z_depth); + unsigned int depth = SetTextureDataImmediate::Depth::Get(z_depth); + unsigned int level = SetTextureDataImmediate::Level::Get(level_face); + unsigned int face = SetTextureDataImmediate::Face::Get(level_face); + unsigned int unused = SetTextureDataImmediate::Unused::Get(level_face); + uint32 data_size = ImmediateDataSize(arg_count, args); + if (face >= 6 || unused != 0 || + size > data_size) + return parse_error::kParseInvalidArguments; + if (data_size == 0) { + return parse_error::kParseNoError; + } + return gapi_->SetTextureData( + args.texture_id, x, y, z, width, height, depth, level, + static_cast(face), args.row_pitch, + args.slice_pitch, size, AddressAfterStruct(args)); +} + +parse_error::ParseError GAPIDecoder::HandleGetTextureData( + uint32 arg_count, + const GetTextureData& args) { + unsigned int x_y = args.x_y; + unsigned int width_height = args.width_height; + unsigned int z_depth = args.z_depth; + unsigned int level_face = args.level_face; + unsigned int size = args.size; + unsigned int x = GetTextureData::X::Get(x_y); + unsigned int y = GetTextureData::Y::Get(x_y); + unsigned int width = GetTextureData::Width::Get(width_height); + unsigned int height = GetTextureData::Height::Get(width_height); + unsigned int z = GetTextureData::Z::Get(z_depth); + unsigned int depth = GetTextureData::Depth::Get(z_depth); + unsigned int level = GetTextureData::Level::Get(level_face); + unsigned int face = GetTextureData::Face::Get(level_face); + unsigned int unused = GetTextureData::Unused::Get(level_face); + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, size); + if (face >= 6 || unused != 0 || !data) + return parse_error::kParseInvalidArguments; + return gapi_->GetTextureData( + args.texture_id, x, y, z, width, height, depth, level, + static_cast(face), args.row_pitch, + args.slice_pitch, size, data); +} + +parse_error::ParseError GAPIDecoder::HandleCreateSampler( + uint32 arg_count, + const CreateSampler& args) { + return gapi_->CreateSampler(args.sampler_id); +} + +parse_error::ParseError GAPIDecoder::HandleDestroySampler( + uint32 arg_count, + const DestroySampler& args) { + return gapi_->DestroySampler(args.sampler_id); +} + +parse_error::ParseError GAPIDecoder::HandleSetSamplerStates( + uint32 arg_count, + const SetSamplerStates& args) { + Uint32 arg = args.sampler_states; + if (SetSamplerStates::Unused::Get(arg) != 0) + return parse_error::kParseInvalidArguments; + unsigned int address_u_value = SetSamplerStates::AddressingU::Get(arg); + unsigned int address_v_value = SetSamplerStates::AddressingV::Get(arg); + unsigned int address_w_value = SetSamplerStates::AddressingW::Get(arg); + unsigned int mag_filter_value = SetSamplerStates::MagFilter::Get(arg); + unsigned int min_filter_value = SetSamplerStates::MinFilter::Get(arg); + unsigned int mip_filter_value = SetSamplerStates::MipFilter::Get(arg); + unsigned int max_anisotropy = SetSamplerStates::MaxAnisotropy::Get(arg); + if (address_u_value >= sampler::kNumAddressingMode || + address_v_value >= sampler::kNumAddressingMode || + address_w_value >= sampler::kNumAddressingMode || + mag_filter_value >= sampler::kNumFilteringMode || + min_filter_value >= sampler::kNumFilteringMode || + mip_filter_value >= sampler::kNumFilteringMode || + mag_filter_value == sampler::kNone || + min_filter_value == sampler::kNone || + max_anisotropy == 0) { + return parse_error::kParseInvalidArguments; + } + gapi_->SetSamplerStates( + args.sampler_id, + static_cast(address_u_value), + static_cast(address_v_value), + static_cast(address_w_value), + static_cast(mag_filter_value), + static_cast(min_filter_value), + static_cast(mip_filter_value), + max_anisotropy); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIDecoder::HandleSetSamplerBorderColor( + uint32 arg_count, + const SetSamplerBorderColor& args) { + RGBA rgba; + rgba.red = args.red; + rgba.green = args.green; + rgba.blue = args.blue; + rgba.alpha = args.alpha; + return gapi_->SetSamplerBorderColor(args.sampler_id, rgba); +} + +parse_error::ParseError GAPIDecoder::HandleSetSamplerTexture( + uint32 arg_count, + const SetSamplerTexture& args) { + return gapi_->SetSamplerTexture(args.sampler_id, args.texture_id); +} + +parse_error::ParseError GAPIDecoder::HandleSetScissor( + uint32 arg_count, + const SetScissor& args) { + Uint32 x_y_enable = args.x_y_enable; + if (SetScissor::Unused::Get(x_y_enable) != 0) + return parse_error::kParseInvalidArguments; + unsigned int x = SetScissor::X::Get(x_y_enable); + unsigned int y = SetScissor::Y::Get(x_y_enable); + bool enable = SetScissor::Enable::Get(x_y_enable) != 0; + Uint32 width_height = args.width_height; + unsigned int width = SetScissor::Width::Get(width_height); + unsigned int height = SetScissor::Height::Get(width_height); + gapi_->SetScissor(enable, x, y, width, height); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIDecoder::HandleSetPolygonOffset( + uint32 arg_count, + const SetPolygonOffset& args) { + gapi_->SetPolygonOffset(args.slope_factor, args.units); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIDecoder::HandleSetPointLineRaster( + uint32 arg_count, + const SetPointLineRaster& args) { + Uint32 enables = args.enables; + if (SetPointLineRaster::Unused::Get(enables) != 0) + return parse_error::kParseInvalidArguments; + bool line_smooth = !!SetPointLineRaster::LineSmoothEnable::Get(enables); + bool point_sprite = !!SetPointLineRaster::PointSpriteEnable::Get(enables); + gapi_->SetPointLineRaster(line_smooth, point_sprite, args.point_size); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIDecoder::HandleSetPolygonRaster( + uint32 arg_count, + const SetPolygonRaster& args) { + Uint32 fill_cull = args.fill_cull; + unsigned int fill_value = SetPolygonRaster::FillMode::Get(fill_cull); + unsigned int cull_value = SetPolygonRaster::CullMode::Get(fill_cull); + if (SetPolygonRaster::Unused::Get(fill_cull) != 0 || + fill_value >= kNumPolygonMode || + cull_value >= kNumFaceCullMode) + return parse_error::kParseInvalidArguments; + gapi_->SetPolygonRaster( + static_cast(fill_value), + static_cast(cull_value)); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIDecoder::HandleSetAlphaTest( + uint32 arg_count, + const SetAlphaTest& args) { + Uint32 func_enable = args.func_enable; + if (SetAlphaTest::Unused::Get(func_enable) != 0) + return parse_error::kParseInvalidArguments; + // Check that the bitmask get cannot generate values outside of the + // allowed range. + COMPILE_ASSERT(SetAlphaTest::Func::kMask < + kNumComparison, + set_alpha_test_Func_may_produce_invalid_values); + Comparison comp = static_cast( + SetAlphaTest::Func::Get(func_enable)); + bool enable = SetAlphaTest::Enable::Get(func_enable) != 0; + gapi_->SetAlphaTest(enable, args.value, comp); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIDecoder::HandleSetDepthTest( + uint32 arg_count, + const SetDepthTest& args) { + Uint32 func_enable = args.func_enable; + if (SetDepthTest::Unused::Get(func_enable) != 0) + return parse_error::kParseInvalidArguments; + // Check that the bitmask get cannot generate values outside of the + // allowed range. + COMPILE_ASSERT(SetDepthTest::Func::kMask < + kNumComparison, + set_alpha_test_Func_may_produce_invalid_values); + Comparison comp = static_cast( + SetDepthTest::Func::Get(func_enable)); + bool write_enable = SetDepthTest::WriteEnable::Get(func_enable) != 0; + bool enable = SetDepthTest::Enable::Get(func_enable) != 0; + gapi_->SetDepthTest(enable, write_enable, comp); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIDecoder::HandleSetStencilTest( + uint32 arg_count, + const SetStencilTest& args) { + Uint32 arg0 = args.stencil_args0; + Uint32 arg1 = args.stencil_args1; + if (SetStencilTest::Unused0::Get(arg0) != 0 || + SetStencilTest::Unused1::Get(arg1) != 0 || + SetStencilTest::Unused2::Get(arg1) != 0) + return parse_error::kParseInvalidArguments; + unsigned int write_mask = SetStencilTest::WriteMask::Get(arg0); + unsigned int compare_mask = SetStencilTest::CompareMask::Get(arg0); + unsigned int ref = SetStencilTest::ReferenceValue::Get(arg0); + bool enable = SetStencilTest::Enable::Get(arg0) != 0; + bool separate_ccw = SetStencilTest::SeparateCCW::Get(arg0) != 0; + gapi_->SetStencilTest(enable, separate_ccw, write_mask, compare_mask, ref, + arg1); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIDecoder::HandleSetColorWrite( + uint32 arg_count, + const SetColorWrite& args) { + Uint32 enables = args.flags; + if (SetColorWrite::Unused::Get(enables) != 0) + return parse_error::kParseInvalidArguments; + bool red = SetColorWrite::RedMask::Get(enables) != 0; + bool green = SetColorWrite::GreenMask::Get(enables) != 0; + bool blue = SetColorWrite::BlueMask::Get(enables) != 0; + bool alpha = SetColorWrite::AlphaMask::Get(enables) != 0; + bool dither = SetColorWrite::DitherEnable::Get(enables) != 0; + gapi_->SetColorWrite(red, green, blue, alpha, dither); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIDecoder::HandleSetBlending( + uint32 arg_count, + const SetBlending& args) { + Uint32 arg = args.blend_settings; + bool enable = SetBlending::Enable::Get(arg) != 0; + bool separate_alpha = SetBlending::SeparateAlpha::Get(arg) != 0; + unsigned int color_eq = SetBlending::ColorEq::Get(arg); + unsigned int color_src = SetBlending::ColorSrcFunc::Get(arg); + unsigned int color_dst = SetBlending::ColorDstFunc::Get(arg); + unsigned int alpha_eq = SetBlending::AlphaEq::Get(arg); + unsigned int alpha_src = SetBlending::AlphaSrcFunc::Get(arg); + unsigned int alpha_dst = SetBlending::AlphaDstFunc::Get(arg); + if (SetBlending::Unused0::Get(arg) != 0 || + SetBlending::Unused1::Get(arg) != 0 || + color_eq >= kNumBlendEq || + color_src >= kNumBlendFunc || + color_dst >= kNumBlendFunc || + alpha_eq >= kNumBlendEq || + alpha_src >= kNumBlendFunc || + alpha_dst >= kNumBlendFunc) + return parse_error::kParseInvalidArguments; + gapi_->SetBlending(enable, + separate_alpha, + static_cast(color_eq), + static_cast(color_src), + static_cast(color_dst), + static_cast(alpha_eq), + static_cast(alpha_src), + static_cast(alpha_dst)); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIDecoder::HandleSetBlendingColor( + uint32 arg_count, + const SetBlendingColor& args) { + RGBA rgba; + rgba.red = args.red; + rgba.green = args.green; + rgba.blue = args.blue; + rgba.alpha = args.alpha; + gapi_->SetBlendingColor(rgba); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIDecoder::HandleCreateRenderSurface( + uint32 arg_count, + const CreateRenderSurface& args) { + unsigned int width_height = args.width_height; + unsigned int width = CreateRenderSurface::Width::Get(width_height); + unsigned int height = CreateRenderSurface::Height::Get(width_height); + unsigned int levels_side = args.levels_side; + unsigned int mip_level = CreateRenderSurface::Levels::Get(levels_side); + unsigned int side = CreateRenderSurface::Side::Get(levels_side); + return gapi_->CreateRenderSurface(args.render_surface_id, + width, height, mip_level, + side, args.texture_id); +} + +parse_error::ParseError GAPIDecoder::HandleDestroyRenderSurface( + uint32 arg_count, + const DestroyRenderSurface& args) { + return gapi_->DestroyRenderSurface(args.render_surface_id); +} + +parse_error::ParseError GAPIDecoder::HandleCreateDepthSurface( + uint32 arg_count, + const CreateDepthSurface& args) { + unsigned int width_height = args.width_height; + unsigned int width = CreateDepthSurface::Width::Get(width_height); + unsigned int height = CreateDepthSurface::Height::Get(width_height); + return gapi_->CreateDepthSurface(args.depth_surface_id, width, height); +} + +parse_error::ParseError GAPIDecoder::HandleDestroyDepthSurface( + uint32 arg_count, + const DestroyDepthSurface& args) { + return gapi_->DestroyDepthSurface(args.depth_surface_id); +} + +parse_error::ParseError GAPIDecoder::HandleSetRenderSurface( + uint32 arg_count, + const SetRenderSurface& args) { + return gapi_->SetRenderSurface(args.render_surface_id, args.depth_surface_id); +} + +parse_error::ParseError GAPIDecoder::HandleSetBackSurfaces( + uint32 arg_count, + const SetBackSurfaces& args) { + gapi_->SetBackSurfaces(); + return parse_error::kParseNoError; +} + +} // namespace o3d +} // namespace command_buffer diff --git a/o3d/command_buffer/service/gapi_decoder.h b/o3d/command_buffer/service/gapi_decoder.h new file mode 100644 index 0000000..5641311 --- /dev/null +++ b/o3d/command_buffer/service/gapi_decoder.h @@ -0,0 +1,81 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the GAPI decoder class. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_GAPI_DECODER_H_ +#define GPU_COMMAND_BUFFER_SERVICE_CROSS_GAPI_DECODER_H_ + +#include "command_buffer/service/common_decoder.h" +#include "command_buffer/common/o3d_cmd_format.h" + +namespace command_buffer { +namespace o3d { + +class GAPIInterface; + +// This class implements the AsyncAPIInterface interface, decoding GAPI +// commands and sending them to a GAPI interface. +class GAPIDecoder : public CommonDecoder { + public: + typedef parse_error::ParseError ParseError; + + explicit GAPIDecoder(GAPIInterface *gapi) : gapi_(gapi) {} + virtual ~GAPIDecoder() {} + + // Overridden from AsyncAPIInterface. + virtual ParseError DoCommand(unsigned int command, + unsigned int arg_count, + const void* args); + + // Overridden from AsyncAPIInterface. + virtual const char* GetCommandName(unsigned int command_id) const; + + private: + // Generate a member function prototype for each command in an automated and + // typesafe way. + #define GPU_COMMAND_BUFFER_CMD_OP(name) \ + ParseError Handle ## name( \ + unsigned int arg_count, \ + const o3d::name& args); \ + + O3D_COMMAND_BUFFER_CMDS(GPU_COMMAND_BUFFER_CMD_OP) + + #undef GPU_COMMAND_BUFFER_CMD_OP + + GAPIInterface *gapi_; +}; + +} // namespace o3d +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_GAPI_DECODER_H_ diff --git a/o3d/command_buffer/service/gapi_gl.cc b/o3d/command_buffer/service/gapi_gl.cc new file mode 100644 index 0000000..5bc587d --- /dev/null +++ b/o3d/command_buffer/service/gapi_gl.cc @@ -0,0 +1,417 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file implements the GAPIGL class. + +#include +#include "command_buffer/service/gapi_gl.h" + +#ifdef OS_LINUX +#include "command_buffer/service/linux/x_utils.h" +#endif // OS_LINUX + +namespace command_buffer { +namespace o3d { + +GAPIGL::GAPIGL() + : cg_context_(NULL), +#ifdef OS_LINUX + window_(NULL), +#endif +#ifdef OS_WIN + hwnd_(NULL), + device_context_(NULL), + gl_context_(NULL), +#endif + anti_aliased_(false), + current_vertex_struct_(kInvalidResource), + validate_streams_(true), + max_vertices_(0), + current_effect_id_(kInvalidResource), + validate_effect_(true), + current_effect_(NULL) { +} + +GAPIGL::~GAPIGL() { +} + +bool GAPIGL::Initialize() { + if (!InitPlatformSpecific()) + return false; + if (!InitCommon()) + return false; + CHECK_GL_ERROR(); + return true; +} + +#if defined(OS_WIN) +static const PIXELFORMATDESCRIPTOR kPixelFormatDescriptor = { + sizeof(kPixelFormatDescriptor), // Size of structure. + 1, // Default version. + PFD_DRAW_TO_WINDOW | // Window drawing support. + PFD_SUPPORT_OPENGL | // OpenGL support. + PFD_DOUBLEBUFFER, // Double buffering support (not stereo). + PFD_TYPE_RGBA, // RGBA color mode (not indexed). + 24, // 24 bit color mode. + 0, 0, 0, 0, 0, 0, // Don't set RGB bits & shifts. + 8, 0, // 8 bit alpha + 0, // No accumulation buffer. + 0, 0, 0, 0, // Ignore accumulation bits. + 24, // 24 bit z-buffer size. + 8, // 8-bit stencil buffer. + 0, // No aux buffer. + PFD_MAIN_PLANE, // Main drawing plane (not overlay). + 0, // Reserved. + 0, 0, 0, // Layer masks ignored. +}; + +LRESULT CALLBACK IntermediateWindowProc(HWND window, + UINT message, + WPARAM w_param, + LPARAM l_param) { + return ::DefWindowProc(window, message, w_param, l_param); +} + +// Helper routine that returns the highest quality pixel format supported on +// the current platform. Returns true upon success. +static bool GetWindowsPixelFormat(HWND window, + bool anti_aliased, + int* pixel_format) { + // We must initialize a GL context before we can determine the multi-sampling + // supported on the current hardware, so we create an intermediate window + // and context here. + HINSTANCE module_handle; + if (!::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + reinterpret_cast(IntermediateWindowProc), + &module_handle)) { + return false; + } + + WNDCLASS intermediate_class; + intermediate_class.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + intermediate_class.lpfnWndProc = IntermediateWindowProc; + intermediate_class.cbClsExtra = 0; + intermediate_class.cbWndExtra = 0; + intermediate_class.hInstance = module_handle; + intermediate_class.hIcon = LoadIcon(NULL, IDI_APPLICATION); + intermediate_class.hCursor = LoadCursor(NULL, IDC_ARROW); + intermediate_class.hbrBackground = NULL; + intermediate_class.lpszMenuName = NULL; + intermediate_class.lpszClassName = L"Intermediate GL Window"; + + ATOM class_registration = ::RegisterClass(&intermediate_class); + if (!class_registration) { + return false; + } + + HWND intermediate_window = ::CreateWindow( + reinterpret_cast(class_registration), + L"", + WS_OVERLAPPEDWINDOW, + 0, 0, + CW_USEDEFAULT, CW_USEDEFAULT, + NULL, + NULL, + NULL, + NULL); + + if (!intermediate_window) { + ::UnregisterClass(reinterpret_cast(class_registration), + module_handle); + return false; + } + + HDC intermediate_dc = ::GetDC(intermediate_window); + int format_index = ::ChoosePixelFormat(intermediate_dc, + &kPixelFormatDescriptor); + if (format_index == 0) { + DLOG(ERROR) << "Unable to get the pixel format for GL context."; + ::ReleaseDC(intermediate_window, intermediate_dc); + ::DestroyWindow(intermediate_window); + ::UnregisterClass(reinterpret_cast(class_registration), + module_handle); + return false; + } + if (!::SetPixelFormat(intermediate_dc, format_index, + &kPixelFormatDescriptor)) { + DLOG(ERROR) << "Unable to set the pixel format for GL context."; + ::ReleaseDC(intermediate_window, intermediate_dc); + ::DestroyWindow(intermediate_window); + ::UnregisterClass(reinterpret_cast(class_registration), + module_handle); + return false; + } + + // Store the pixel format without multisampling. + *pixel_format = format_index; + HGLRC gl_context = ::wglCreateContext(intermediate_dc); + if (::wglMakeCurrent(intermediate_dc, gl_context)) { + // GL context was successfully created and applied to the window's DC. + // Startup GLEW, the GL extensions wrangler. + GLenum glew_error = ::glewInit(); + if (glew_error == GLEW_OK) { + DLOG(INFO) << "Initialized GLEW " << ::glewGetString(GLEW_VERSION); + } else { + DLOG(ERROR) << "Unable to initialise GLEW : " + << ::glewGetErrorString(glew_error); + ::wglMakeCurrent(intermediate_dc, NULL); + ::wglDeleteContext(gl_context); + ::ReleaseDC(intermediate_window, intermediate_dc); + ::DestroyWindow(intermediate_window); + ::UnregisterClass(reinterpret_cast(class_registration), + module_handle); + return false; + } + + // If the multi-sample extensions are present, query the api to determine + // the pixel format. + if (anti_aliased && WGLEW_ARB_pixel_format && WGLEW_ARB_multisample) { + int pixel_attributes[] = { + WGL_SAMPLES_ARB, 4, + WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, + WGL_SUPPORT_OPENGL_ARB, GL_TRUE, + WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, + WGL_COLOR_BITS_ARB, 24, + WGL_ALPHA_BITS_ARB, 8, + WGL_DEPTH_BITS_ARB, 24, + WGL_STENCIL_BITS_ARB, 8, + WGL_DOUBLE_BUFFER_ARB, GL_TRUE, + WGL_SAMPLE_BUFFERS_ARB, GL_TRUE, + 0, 0}; + + float pixel_attributes_f[] = {0, 0}; + int msaa_pixel_format; + unsigned int num_formats; + + // Query for the highest sampling rate supported, starting at 4x. + static const int kSampleCount[] = {4, 2}; + static const int kNumSamples = 2; + for (int sample = 0; sample < kNumSamples; ++sample) { + pixel_attributes[1] = kSampleCount[sample]; + if (GL_TRUE == ::wglChoosePixelFormatARB(intermediate_dc, + pixel_attributes, + pixel_attributes_f, + 1, + &msaa_pixel_format, + &num_formats)) { + *pixel_format = msaa_pixel_format; + break; + } + } + } + } + + ::wglMakeCurrent(intermediate_dc, NULL); + ::wglDeleteContext(gl_context); + ::ReleaseDC(intermediate_window, intermediate_dc); + ::DestroyWindow(intermediate_window); + ::UnregisterClass(reinterpret_cast(class_registration), + module_handle); + return true; +} +#endif + +bool GAPIGL::InitPlatformSpecific() { +#if defined(OS_WIN) + device_context_ = ::GetDC(hwnd_); + + int pixel_format; + + if (!GetWindowsPixelFormat(hwnd_, + anti_aliased(), + &pixel_format)) { + DLOG(ERROR) << "Unable to determine optimal pixel format for GL context."; + return false; + } + + if (!::SetPixelFormat(device_context_, pixel_format, + &kPixelFormatDescriptor)) { + DLOG(ERROR) << "Unable to set the pixel format for GL context."; + return false; + } + + gl_context_ = ::wglCreateContext(device_context_); + if (!gl_context_) { + DLOG(ERROR) << "Failed to create GL context."; + return false; + } + + if (!::wglMakeCurrent(device_context_, gl_context_)) { + DLOG(ERROR) << "Unable to make gl context current."; + return false; + } +#elif defined(OS_LINUX) + DCHECK(window_); + if (!window_->Initialize()) + return false; + if (!window_->MakeCurrent()) + return false; +#endif + + return true; +} + +bool GAPIGL::InitCommon() { + if (!InitGlew()) + return false; + InitCG(); + + // Initialize global GL settings. + // Tell GL that texture buffers can be single-byte aligned. + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); + // Get the initial viewport (set to the window size) to set up the helper + // constant. + GLint viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); + SetViewport(viewport[0], viewport[1], viewport[2], viewport[3], 0.f, 1.f); + CHECK_GL_ERROR(); + + ::glGenFramebuffersEXT(1, &render_surface_framebuffer_); + CHECK_GL_ERROR(); + return true; +} + +void GAPIGL::InitCG() { + cg_context_ = cgCreateContext(); + // Set up all Cg State Assignments for OpenGL. + cgGLRegisterStates(cg_context_); + cgGLSetDebugMode(CG_FALSE); + // Enable the profiles we use. + cgGLEnableProfile(CG_PROFILE_ARBVP1); + cgGLEnableProfile(CG_PROFILE_ARBFP1); +} + +bool GAPIGL::InitGlew() { + DLOG(INFO) << "Initializing GL and GLEW for GAPI."; + + GLenum glew_error = glewInit(); + if (glew_error != GLEW_OK) { + DLOG(ERROR) << "Unable to initialise GLEW : " + << ::glewGetErrorString(glew_error); + return false; + } + + // Check to see that we can use the OpenGL vertex attribute APIs + // TODO(petersont): Return false if this check fails, but because some + // Intel hardware does not support OpenGL 2.0, yet does support all of the + // extensions we require, we only log an error. A future CL should change + // this check to ensure that all of the extension strings we require are + // present. + if (!GLEW_VERSION_2_0) { + DLOG(ERROR) << "GL drivers do not have OpenGL 2.0 functionality."; + } + + bool extensions_found = true; + if (!GLEW_ARB_vertex_buffer_object) { + // NOTE: Linux NVidia drivers claim to support OpenGL 2.0 when using + // indirect rendering (e.g. remote X), but it is actually lying. The + // ARB_vertex_buffer_object functions silently no-op (!) when using + // indirect rendering, leading to crashes. Fortunately, in that case, the + // driver claims to not support ARB_vertex_buffer_object, so fail in that + // case. + DLOG(ERROR) << "GL drivers do not support vertex buffer objects."; + extensions_found = false; + } + if (!GLEW_EXT_framebuffer_object) { + DLOG(ERROR) << "GL drivers do not support framebuffer objects."; + extensions_found = false; + } + // Check for necessary extensions + if (!GLEW_VERSION_2_0 && !GLEW_EXT_stencil_two_side) { + DLOG(ERROR) << "Two sided stencil extension missing."; + extensions_found = false; + } + if (!GLEW_VERSION_1_4 && !GLEW_EXT_blend_func_separate) { + DLOG(ERROR) <<"Separate blend func extension missing."; + extensions_found = false; + } + if (!GLEW_VERSION_2_0 && !GLEW_EXT_blend_equation_separate) { + DLOG(ERROR) << "Separate blend function extension missing."; + extensions_found = false; + } + if (!extensions_found) + return false; + + return true; +} + +void GAPIGL::Destroy() { + vertex_buffers_.DestroyAllResources(); + index_buffers_.DestroyAllResources(); + vertex_structs_.DestroyAllResources(); + effects_.DestroyAllResources(); + effect_params_.DestroyAllResources(); + // textures_.DestroyAllResources(); + // samplers_.DestroyAllResources(); + cgDestroyContext(cg_context_); + cg_context_ = NULL; +#ifdef OS_LINUX + DCHECK(window_); + window_->Destroy(); +#endif +} + +void GAPIGL::BeginFrame() { +} + +void GAPIGL::EndFrame() { +#ifdef OS_WIN + ::SwapBuffers(device_context_); +#endif + +#ifdef OS_LINUX + DCHECK(window_); + window_->SwapBuffers(); +#endif + + CHECK_GL_ERROR(); +} + +void GAPIGL::Clear(unsigned int buffers, + const RGBA &color, + float depth, + unsigned int stencil) { + glClearColor(color.red, color.green, color.blue, color.alpha); + glClearDepth(depth); + glClearStencil(stencil); + glClear((buffers & kColor ? GL_COLOR_BUFFER_BIT : 0) | + (buffers & kDepth ? GL_DEPTH_BUFFER_BIT : 0) | + (buffers & kStencil ? GL_STENCIL_BUFFER_BIT : 0)); + CHECK_GL_ERROR(); +} + +} // namespace o3d +} // namespace command_buffer diff --git a/o3d/command_buffer/service/gapi_gl.h b/o3d/command_buffer/service/gapi_gl.h new file mode 100644 index 0000000..e46bd7f --- /dev/null +++ b/o3d/command_buffer/service/gapi_gl.h @@ -0,0 +1,465 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the GAPIGL class, implementing the GAPI interface for +// GL. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_GL_GAPI_GL_H_ +#define GPU_COMMAND_BUFFER_SERVICE_CROSS_GL_GAPI_GL_H_ + +#include +#include +#include +#include +#include "command_buffer/common/gapi_interface.h" +#include "command_buffer/service/gl_utils.h" +#include "command_buffer/service/effect_gl.h" +#include "command_buffer/service/geometry_gl.h" +#include "command_buffer/service/render_surface_gl.h" +#include "command_buffer/service/sampler_gl.h" +#include "command_buffer/service/texture_gl.h" + +namespace command_buffer { +namespace o3d { +#if defined(OS_LINUX) +class XWindowWrapper; +#endif // defined(OS_LINUX) + +// This class implements the GAPI interface for GL. +class GAPIGL : public GAPIInterface { + public: + GAPIGL(); + virtual ~GAPIGL(); + +#if defined(OS_LINUX) + void set_window_wrapper(XWindowWrapper *window) { window_ = window; } +#elif defined(OS_WIN) + void set_hwnd(HWND hwnd) { hwnd_ = hwnd; } + + HWND hwnd() const { + return hwnd_; + } +#endif + + // Initializes the graphics context, bound to a window. + // Returns: + // true if successful. + virtual bool Initialize(); + + // Initailizes Cg. + void InitCG(); + + // Helper function for Initailize that inits just glew. + bool InitGlew(); + + // Destroys the graphics context. + virtual void Destroy(); + + // Implements the BeginFrame function for GL. + virtual void BeginFrame(); + + // Implements the EndFrame function for GL. + virtual void EndFrame(); + + // Implements the Clear function for GL. + virtual void Clear(unsigned int buffers, + const RGBA &color, + float depth, + unsigned int stencil); + + // Implements the SetViewport function for GL. + virtual void SetViewport(unsigned int x, + unsigned int y, + unsigned int width, + unsigned int height, + float z_min, + float z_max); + + // Implements the CreateVertexBuffer function for GL. + virtual ParseError CreateVertexBuffer(ResourceId id, + unsigned int size, + unsigned int flags); + + // Implements the DestroyVertexBuffer function for GL. + virtual ParseError DestroyVertexBuffer(ResourceId id); + + // Implements the SetVertexBufferData function for GL. + virtual ParseError SetVertexBufferData(ResourceId id, + unsigned int offset, + unsigned int size, + const void *data); + + // Implements the GetVertexBufferData function for GL. + virtual ParseError GetVertexBufferData(ResourceId id, + unsigned int offset, + unsigned int size, + void *data); + + // Implements the CreateIndexBuffer function for GL. + virtual ParseError CreateIndexBuffer(ResourceId id, + unsigned int size, + unsigned int flags); + + // Implements the DestroyIndexBuffer function for GL. + virtual ParseError DestroyIndexBuffer(ResourceId id); + + // Implements the SetIndexBufferData function for GL. + virtual ParseError SetIndexBufferData(ResourceId id, + unsigned int offset, + unsigned int size, + const void *data); + + // Implements the GetIndexBufferData function for GL. + virtual ParseError GetIndexBufferData(ResourceId id, + unsigned int offset, + unsigned int size, + void *data); + + // Implements the CreateVertexStruct function for GL. + virtual ParseError CreateVertexStruct(ResourceId id, + unsigned int input_count); + + // Implements the DestroyVertexStruct function for GL. + virtual ParseError DestroyVertexStruct(ResourceId id); + + // Implements the SetVertexInput function for GL. + virtual ParseError SetVertexInput(ResourceId vertex_struct_id, + unsigned int input_index, + ResourceId vertex_buffer_id, + unsigned int offset, + unsigned int stride, + vertex_struct::Type type, + vertex_struct::Semantic semantic, + unsigned int semantic_index); + + // Implements the SetVertexStruct function for GL. + virtual ParseError SetVertexStruct(ResourceId id); + + // Implements the Draw function for GL. + virtual ParseError Draw(PrimitiveType primitive_type, + unsigned int first, + unsigned int count); + + // Implements the DrawIndexed function for GL. + virtual ParseError DrawIndexed(PrimitiveType primitive_type, + ResourceId index_buffer_id, + unsigned int first, + unsigned int count, + unsigned int min_index, + unsigned int max_index); + + // Implements the CreateEffect function for GL. + virtual ParseError CreateEffect(ResourceId id, + unsigned int size, + const void *data); + + // Implements the DestroyEffect function for GL. + virtual ParseError DestroyEffect(ResourceId id); + + // Implements the SetEffect function for GL. + virtual ParseError SetEffect(ResourceId id); + + // Implements the GetParamCount function for GL. + virtual ParseError GetParamCount(ResourceId id, + unsigned int size, + void *data); + + // Implements the CreateParam function for GL. + virtual ParseError CreateParam(ResourceId param_id, + ResourceId effect_id, + unsigned int index); + + // Implements the CreateParamByName function for GL. + virtual ParseError CreateParamByName(ResourceId param_id, + ResourceId effect_id, + unsigned int size, + const void *name); + + // Implements the DestroyParam function for GL. + virtual ParseError DestroyParam(ResourceId id); + + // Implements the SetParamData function for GL. + virtual ParseError SetParamData(ResourceId id, + unsigned int size, + const void *data); + + // Implements the GetParamDesc function for GL. + virtual ParseError GetParamDesc(ResourceId id, + unsigned int size, + void *data); + + // Implements the GetStreamCount function for GL. + virtual ParseError GetStreamCount(ResourceId id, + unsigned int size, + void *data); + + // Implements the GetStreamDesc function for GL. + virtual ParseError GetStreamDesc(ResourceId id, + unsigned int index, + unsigned int size, + void *data); + + // Implements the CreateTexture2D function for GL. + virtual ParseError CreateTexture2D(ResourceId id, + unsigned int width, + unsigned int height, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces); + + // Implements the CreateTexture3D function for GL. + virtual ParseError CreateTexture3D(ResourceId id, + unsigned int width, + unsigned int height, + unsigned int depth, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces); + + // Implements the CreateTextureCube function for GL. + virtual ParseError CreateTextureCube(ResourceId id, + unsigned int side, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces); + + // Implements the SetTextureData function for GL. + virtual ParseError SetTextureData(ResourceId id, + unsigned int x, + unsigned int y, + unsigned int z, + unsigned int width, + unsigned int height, + unsigned int depth, + unsigned int level, + texture::Face face, + unsigned int pitch, + unsigned int slice_pitch, + unsigned int size, + const void *data); + + // Implements the GetTextureData function for GL. + virtual ParseError GetTextureData(ResourceId id, + unsigned int x, + unsigned int y, + unsigned int z, + unsigned int width, + unsigned int height, + unsigned int depth, + unsigned int level, + texture::Face face, + unsigned int pitch, + unsigned int slice_pitch, + unsigned int size, + void *data); + + // Implements the DestroyTexture function for GL. + virtual ParseError DestroyTexture(ResourceId id); + + // Implements the CreateSampler function for GL. + virtual ParseError CreateSampler(ResourceId id); + + // Implements the DestroySampler function for GL. + virtual ParseError DestroySampler(ResourceId id); + + // Implements the SetSamplerStates function for GL. + virtual ParseError SetSamplerStates(ResourceId id, + sampler::AddressingMode addressing_u, + sampler::AddressingMode addressing_v, + sampler::AddressingMode addressing_w, + sampler::FilteringMode mag_filter, + sampler::FilteringMode min_filter, + sampler::FilteringMode mip_filter, + unsigned int max_anisotropy); + + // Implements the SetSamplerBorderColor function for GL. + virtual ParseError SetSamplerBorderColor(ResourceId id, const RGBA &color); + + // Implements the SetSamplerTexture function for GL. + virtual ParseError SetSamplerTexture(ResourceId id, ResourceId texture_id); + + // Implements the SetScissor function for GL. + virtual void SetScissor(bool enable, + unsigned int x, + unsigned int y, + unsigned int width, + unsigned int height); + + // Implements the SetPointLineRaster function for GL. + virtual void SetPointLineRaster(bool line_smooth, + bool point_sprite, + float point_size); + + // Implements the SetPolygonOffset function for GL. + virtual void SetPolygonOffset(float slope_factor, float units); + + // Implements the SetPolygonRaster function for GL. + virtual void SetPolygonRaster(PolygonMode fill_mode, + FaceCullMode cull_mode); + + // Implements the SetAlphaTest function for GL. + virtual void SetAlphaTest(bool enable, + float reference, + Comparison comp); + + // Implements the SetDepthTest function for GL. + virtual void SetDepthTest(bool enable, + bool write_enable, + Comparison comp); + + // Implements the SetStencilTest function for GL. + virtual void SetStencilTest(bool enable, + bool separate_ccw, + unsigned int write_mask, + unsigned int compare_mask, + unsigned int ref, + Uint32 func_ops); + + // Implements the SetColorWritefunction for GL. + virtual void SetColorWrite(bool red, + bool green, + bool blue, + bool alpha, + bool dither); + + // Implements the SetBlending function for GL. + virtual void SetBlending(bool enable, + bool separate_alpha, + BlendEq color_eq, + BlendFunc color_src_func, + BlendFunc color_dst_func, + BlendEq alpha_eq, + BlendFunc alpha_src_func, + BlendFunc alpha_dst_func); + + // Implements the SetBlendingColor function for GL. + virtual void SetBlendingColor(const RGBA &color); + + // Implements the CreateRenderSurface function for GL. + virtual ParseError CreateRenderSurface(ResourceId id, + unsigned int width, + unsigned int height, + unsigned int mip_level, + unsigned int side, + ResourceId texture_id); + + // Implements the DestroyRenderSurface function for GL. + virtual ParseError DestroyRenderSurface(ResourceId id); + + // Implements the CreateDepthSurface function for GL. + virtual ParseError CreateDepthSurface(ResourceId id, + unsigned int width, + unsigned int height); + + // Implements the DestroyDepthSurface function for GL. + virtual ParseError DestroyDepthSurface(ResourceId id); + + // Implements the SetRenderSurface function for GL. + virtual ParseError SetRenderSurface(ResourceId render_surface_id, + ResourceId depth_stencil_id); + + // Implements the SetBackSurfaces function for GL. + virtual void SetBackSurfaces(); + + // Gets a vertex buffer by resource ID. + VertexBufferGL *GetVertexBuffer(ResourceId id) { + return vertex_buffers_.Get(id); + } + + // Gets a texture by resource ID. + TextureGL *GetTexture(ResourceId id) { + return textures_.Get(id); + } + + // Gets a sampler by resource ID. + SamplerGL *GetSampler(ResourceId id) { + return samplers_.Get(id); + } + void set_anti_aliased(bool anti_aliased) { anti_aliased_ = anti_aliased; } + + bool anti_aliased() const { return anti_aliased_; } + + CGcontext cg_context() const { return cg_context_; } + + EffectGL *current_effect() const { return current_effect_; } + // "Dirty" the current effect. This resets the vertex and fragment program, + // and requires ValidateEffect() to be called before further draws occur. + void DirtyEffect(); + private: + bool InitPlatformSpecific(); + bool InitCommon(); + // Validates the current vertex struct to GL, setting the vertex attributes. + bool ValidateStreams(); + // Validates the current effect to GL. This sets the vertex and fragment + // programs, and updates parameters if needed. + bool ValidateEffect(); + + CGcontext cg_context_; + +#if defined(OS_LINUX) + XWindowWrapper *window_; +#elif defined(OS_WIN) + // Handle to the GL device. + HWND hwnd_; + HDC device_context_; + HGLRC gl_context_; +#endif + + bool anti_aliased_; + ResourceId current_vertex_struct_; + bool validate_streams_; + unsigned int max_vertices_; + ResourceId current_effect_id_; + bool validate_effect_; + EffectGL *current_effect_; + ResourceId current_surface_id_; + ResourceId current_depth_surface_id_; + GLuint render_surface_framebuffer_; + + ResourceMap vertex_buffers_; + ResourceMap index_buffers_; + ResourceMap vertex_structs_; + ResourceMap effects_; + ResourceMap effect_params_; + ResourceMap textures_; + ResourceMap samplers_; + ResourceMap render_surfaces_; + ResourceMap depth_surfaces_; +}; + +} // namespace o3d +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_GL_GAPI_GL_H_ diff --git a/o3d/command_buffer/service/geometry_d3d9.cc b/o3d/command_buffer/service/geometry_d3d9.cc new file mode 100644 index 0000000..8fb3f35 --- /dev/null +++ b/o3d/command_buffer/service/geometry_d3d9.cc @@ -0,0 +1,436 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the implementation of the D3D9 versions of the +// VertexBuffer, IndexBuffer and VertexStruct resources. +// This file also contains the related GAPID3D9 function implementations. + +#include +#include "command_buffer/service/d3d9_utils.h" +#include "command_buffer/service/geometry_d3d9.h" +#include "command_buffer/service/gapi_d3d9.h" + +namespace command_buffer { +namespace o3d { + +// Destroys the D3D9 vertex buffer. +VertexBufferD3D9::~VertexBufferD3D9() { + DCHECK(d3d_vertex_buffer_ != NULL); + if (d3d_vertex_buffer_) { + d3d_vertex_buffer_->Release(); + d3d_vertex_buffer_ = NULL; + } +} + +// Creates a D3D9 vertex buffer. +void VertexBufferD3D9::Create(GAPID3D9 *gapi) { + DCHECK(d3d_vertex_buffer_ == NULL); + + DWORD d3d_usage = (flags() & vertex_buffer::kDynamic) ? D3DUSAGE_DYNAMIC : 0; + D3DPOOL d3d_pool = D3DPOOL_MANAGED; + HR(gapi->d3d_device()->CreateVertexBuffer(size(), d3d_usage, 0, d3d_pool, + &d3d_vertex_buffer_, NULL)); +} + +// Sets the data into the D3D9 vertex buffer, using Lock() and memcpy. +bool VertexBufferD3D9::SetData(unsigned int offset, + unsigned int size, + const void *data) { + if (!d3d_vertex_buffer_) { + LOG(ERROR) << "Calling SetData on a non-initialized VertexBufferD3D9."; + return false; + } + if ((offset >= this->size()) || (offset + size > this->size())) { + LOG(ERROR) << "Invalid size or offset on VertexBufferD3D9::SetData."; + return false; + } + void *ptr = NULL; + DWORD lock_flags = 0; + // If we are setting the full buffer, discard the old data. That's only + // possible to do for a dynamic d3d vertex buffer. + if ((offset == 0) && (size == this->size()) && + (flags() & vertex_buffer::kDynamic)) + lock_flags = D3DLOCK_DISCARD; + HR(d3d_vertex_buffer_->Lock(offset, size, &ptr, lock_flags)); + memcpy(ptr, data, size); + HR(d3d_vertex_buffer_->Unlock()); + return true; +} + +// Gets the data from the D3D9 vertex buffer, using Lock() and memcpy. +bool VertexBufferD3D9::GetData(unsigned int offset, + unsigned int size, + void *data) { + if (!d3d_vertex_buffer_) { + LOG(ERROR) << "Calling SetData on a non-initialized VertexBufferD3D9."; + return false; + } + if ((offset >= this->size()) || (offset + size > this->size())) { + LOG(ERROR) << "Invalid size or offset on VertexBufferD3D9::SetData."; + return false; + } + void *ptr = NULL; + DWORD lock_flags = D3DLOCK_READONLY; + HR(d3d_vertex_buffer_->Lock(offset, size, &ptr, lock_flags)); + memcpy(data, ptr, size); + HR(d3d_vertex_buffer_->Unlock()); + return true; +} + +// Destroys the D3D9 index buffer. +IndexBufferD3D9::~IndexBufferD3D9() { + DCHECK(d3d_index_buffer_ != NULL); + if (d3d_index_buffer_) { + d3d_index_buffer_->Release(); + d3d_index_buffer_ = NULL; + } +} + +// Creates a D3D9 index buffer. +void IndexBufferD3D9::Create(GAPID3D9 *gapi) { + DCHECK(d3d_index_buffer_ == NULL); + + DWORD d3d_usage = (flags() & index_buffer::kDynamic) ? D3DUSAGE_DYNAMIC : 0; + D3DFORMAT d3d_format = + (flags() & index_buffer::kIndex32Bit) ? D3DFMT_INDEX32 : D3DFMT_INDEX16; + D3DPOOL d3d_pool = D3DPOOL_MANAGED; + HR(gapi->d3d_device()->CreateIndexBuffer(size(), d3d_usage, d3d_format, + d3d_pool, &d3d_index_buffer_, + NULL)); +} + +// Sets the data into the D3D9 index buffer, using Lock() and memcpy. +bool IndexBufferD3D9::SetData(unsigned int offset, + unsigned int size, + const void *data) { + if (!d3d_index_buffer_) { + LOG(ERROR) << "Calling SetData on a non-initialized IndexBufferD3D9."; + return false; + } + if ((offset >= this->size()) || (offset + size > this->size())) { + LOG(ERROR) << "Invalid size or offset on IndexBufferD3D9::SetData."; + return false; + } + void *ptr = NULL; + DWORD lock_flags = 0; + // If we are setting the full buffer, discard the old data. That's only + // possible to do for a dynamic d3d index buffer. + if ((offset == 0) && (size == this->size()) && + (flags() & index_buffer::kDynamic)) + lock_flags = D3DLOCK_DISCARD; + HR(d3d_index_buffer_->Lock(offset, size, &ptr, lock_flags)); + memcpy(ptr, data, size); + HR(d3d_index_buffer_->Unlock()); + return true; +} + +// Gets the data from the D3D9 index buffer, using Lock() and memcpy. +bool IndexBufferD3D9::GetData(unsigned int offset, + unsigned int size, + void *data) { + if (!d3d_index_buffer_) { + LOG(ERROR) << "Calling SetData on a non-initialized IndexBufferD3D9."; + return false; + } + if ((offset >= this->size()) || (offset + size > this->size())) { + LOG(ERROR) << "Invalid size or offset on IndexBufferD3D9::SetData."; + return false; + } + void *ptr = NULL; + DWORD lock_flags = D3DLOCK_READONLY; + HR(d3d_index_buffer_->Lock(offset, size, &ptr, lock_flags)); + memcpy(data, ptr, size); + HR(d3d_index_buffer_->Unlock()); + return true; +} + +// Sets the input element in the VertexStruct resource. +void VertexStructD3D9::SetInput(unsigned int input_index, + ResourceId vertex_buffer_id, + unsigned int offset, + unsigned int stride, + vertex_struct::Type type, + vertex_struct::Semantic semantic, + unsigned int semantic_index) { + Element &element = GetElement(input_index); + element.vertex_buffer = vertex_buffer_id; + element.offset = offset; + element.stride = stride; + element.type = type; + element.semantic = semantic; + element.semantic_index = semantic_index; + dirty_ = true; +} + +// Sets the vdecl and stream sources in D3D9. Compiles them if needed. +unsigned int VertexStructD3D9::SetStreams(GAPID3D9 *gapi) { + IDirect3DDevice9 *d3d_device = gapi->d3d_device(); + if (dirty_) Compile(d3d_device); + HR(d3d_device->SetVertexDeclaration(d3d_vertex_decl_)); + unsigned int max_vertices = UINT_MAX; + for (unsigned int i = 0; i < streams_.size(); ++i) { + const StreamPair &pair = streams_[i]; + VertexBufferD3D9 *vertex_buffer = gapi->GetVertexBuffer(pair.first); + if (!vertex_buffer) { + max_vertices = 0; + continue; + } + HR(d3d_device->SetStreamSource(i, vertex_buffer->d3d_vertex_buffer(), 0, + pair.second)); + + // TODO(apatrick): A zero size stride is valid. It means the first element + // in the vertex buffer will be used for every vertex. There doesn't seem + // to be enough information here to determine whether a zero stride + // vertex buffer is big enough to contain a single element. + if (pair.second != 0) { + max_vertices = std::min(max_vertices, + vertex_buffer->size() / pair.second); + } + } + return max_vertices; +} + +// Converts a vertex_struct::Type to a D3DDECLTYPE. +static D3DDECLTYPE D3DType(vertex_struct::Type type) { + switch (type) { + case vertex_struct::kFloat1: + return D3DDECLTYPE_FLOAT1; + case vertex_struct::kFloat2: + return D3DDECLTYPE_FLOAT2; + case vertex_struct::kFloat3: + return D3DDECLTYPE_FLOAT3; + case vertex_struct::kFloat4: + return D3DDECLTYPE_FLOAT4; + case vertex_struct::kUChar4N: + return D3DDECLTYPE_UBYTE4N; + case vertex_struct::kNumTypes: + break; + } + LOG(FATAL) << "Invalid type"; + return D3DDECLTYPE_FLOAT1; +} + +// Converts a vertex_struct::Semantic to a D3DDECLUSAGE. +static D3DDECLUSAGE D3DUsage(vertex_struct::Semantic semantic) { + switch (semantic) { + case vertex_struct::kPosition: + return D3DDECLUSAGE_POSITION; + case vertex_struct::kNormal: + return D3DDECLUSAGE_NORMAL; + case vertex_struct::kColor: + return D3DDECLUSAGE_COLOR; + case vertex_struct::kTexCoord: + return D3DDECLUSAGE_TEXCOORD; + case vertex_struct::kNumSemantics: + break; + } + LOG(FATAL) << "Invalid type"; + return D3DDECLUSAGE_POSITION; +} + +// Destroys the d3d vertex declaration. +VertexStructD3D9::~VertexStructD3D9() { + Destroy(); +} + +void VertexStructD3D9::Destroy() { + if (d3d_vertex_decl_) { + d3d_vertex_decl_->Release(); + d3d_vertex_decl_ = NULL; + } + streams_.clear(); +} + +// Compiles a stream map and a d3d vertex declaration from the list of inputs. +// 2 inputs that use the same vertex buffer and stride will use the same +// d3d stream. +void VertexStructD3D9::Compile(IDirect3DDevice9 *d3d_device) { + DCHECK(dirty_); + Destroy(); + streams_.reserve(count_); + scoped_array d3d_elements( + new D3DVERTEXELEMENT9[count_ + 1]); + memset(d3d_elements.get(), 0, sizeof(D3DVERTEXELEMENT9) * (count_ + 1)); + // build streams_ like a set, but the order matters. + for (unsigned int i = 0; i < count_ ; ++i) { + Element &element = GetElement(i); + D3DVERTEXELEMENT9 &d3d_element = d3d_elements[i]; + StreamPair pair(element.vertex_buffer, element.stride); + std::vector::iterator it = + std::find(streams_.begin(), streams_.end(), pair); + unsigned int stream_index = 0; + if (it == streams_.end()) { + streams_.push_back(pair); + stream_index = static_cast(streams_.size() - 1); + } else { + stream_index = it - streams_.begin(); + } + d3d_element.Stream = stream_index; + d3d_element.Offset = element.offset; + d3d_element.Type = D3DType(element.type); + d3d_element.Usage = D3DUsage(element.semantic); + d3d_element.UsageIndex = element.semantic_index; + } + D3DVERTEXELEMENT9 &end = d3d_elements[count_]; + end.Stream = 0xFF; + end.Type = D3DDECLTYPE_UNUSED; + HR(d3d_device->CreateVertexDeclaration(d3d_elements.get(), + &d3d_vertex_decl_)); + dirty_ = false; +} + +// Creates and assigns a VertexBufferD3D9 resource. +parse_error::ParseError GAPID3D9::CreateVertexBuffer( + ResourceId id, + unsigned int size, + unsigned int flags) { + VertexBufferD3D9 *vertex_buffer = new VertexBufferD3D9(size, flags); + vertex_buffer->Create(this); + vertex_buffers_.Assign(id, vertex_buffer); + return parse_error::kParseNoError; +} + +// Destroys a VertexBufferD3D9 resource. +parse_error::ParseError GAPID3D9::DestroyVertexBuffer(ResourceId id) { + return vertex_buffers_.Destroy(id) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +// Copies the data into the VertexBufferD3D9 resource. +parse_error::ParseError GAPID3D9::SetVertexBufferData( + ResourceId id, + unsigned int offset, + unsigned int size, + const void *data) { + VertexBufferD3D9 *vertex_buffer = vertex_buffers_.Get(id); + if (!vertex_buffer) return parse_error::kParseInvalidArguments; + return vertex_buffer->SetData(offset, size, data) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +// Copies the data from the VertexBufferD3D9 resource. +parse_error::ParseError GAPID3D9::GetVertexBufferData( + ResourceId id, + unsigned int offset, + unsigned int size, + void *data) { + VertexBufferD3D9 *vertex_buffer = vertex_buffers_.Get(id); + if (!vertex_buffer) return parse_error::kParseInvalidArguments; + return vertex_buffer->GetData(offset, size, data) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +// Creates and assigns an IndexBufferD3D9 resource. +parse_error::ParseError GAPID3D9::CreateIndexBuffer( + ResourceId id, + unsigned int size, + unsigned int flags) { + IndexBufferD3D9 *index_buffer = new IndexBufferD3D9(size, flags); + index_buffer->Create(this); + index_buffers_.Assign(id, index_buffer); + return parse_error::kParseNoError; +} + +// Destroys an IndexBufferD3D9 resource. +parse_error::ParseError GAPID3D9::DestroyIndexBuffer(ResourceId id) { + return index_buffers_.Destroy(id) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +// Copies the data into the IndexBufferD3D9 resource. +parse_error::ParseError GAPID3D9::SetIndexBufferData( + ResourceId id, + unsigned int offset, + unsigned int size, + const void *data) { + IndexBufferD3D9 *index_buffer = index_buffers_.Get(id); + if (!index_buffer) return parse_error::kParseInvalidArguments; + return index_buffer->SetData(offset, size, data) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +// Copies the data from the IndexBufferD3D9 resource. +parse_error::ParseError GAPID3D9::GetIndexBufferData( + ResourceId id, + unsigned int offset, + unsigned int size, + void *data) { + IndexBufferD3D9 *index_buffer = index_buffers_.Get(id); + if (!index_buffer) return parse_error::kParseInvalidArguments; + return index_buffer->GetData(offset, size, data) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +// Creates and assigns a VertexStructD3D9 resource. +parse_error::ParseError GAPID3D9::CreateVertexStruct( + ResourceId id, unsigned int input_count) { + if (id == current_vertex_struct_) validate_streams_ = true; + VertexStructD3D9 *vertex_struct = new VertexStructD3D9(input_count); + vertex_structs_.Assign(id, vertex_struct); + return parse_error::kParseNoError; +} + +// Destroys a VertexStructD3D9 resource. +parse_error::ParseError GAPID3D9::DestroyVertexStruct(ResourceId id) { + if (id == current_vertex_struct_) validate_streams_ = true; + return vertex_structs_.Destroy(id) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +// Sets an input into a VertexStructD3D9 resource. +parse_error::ParseError GAPID3D9::SetVertexInput( + ResourceId vertex_struct_id, + unsigned int input_index, + ResourceId vertex_buffer_id, + unsigned int offset, + unsigned int stride, + vertex_struct::Type type, + vertex_struct::Semantic semantic, + unsigned int semantic_index) { + if (vertex_buffer_id == current_vertex_struct_) validate_streams_ = true; + VertexStructD3D9 *vertex_struct = vertex_structs_.Get(vertex_struct_id); + if (!vertex_struct || input_index >= vertex_struct->count()) + return parse_error::kParseInvalidArguments; + vertex_struct->SetInput(input_index, vertex_buffer_id, offset, stride, type, + semantic, semantic_index); + return parse_error::kParseNoError; +} + +} // namespace o3d +} // namespace command_buffer diff --git a/o3d/command_buffer/service/geometry_d3d9.h b/o3d/command_buffer/service/geometry_d3d9.h new file mode 100644 index 0000000..201a69e --- /dev/null +++ b/o3d/command_buffer/service/geometry_d3d9.h @@ -0,0 +1,126 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the definition of the D3D9 versions of geometry-related +// resource classes. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_WIN_D3D9_GEOMETRY_D3D9_H_ +#define GPU_COMMAND_BUFFER_SERVICE_WIN_D3D9_GEOMETRY_D3D9_H_ + +#include +#include +#include "command_buffer/common/gapi_interface.h" +#include "command_buffer/service/d3d9_utils.h" +#include "command_buffer/service/resource.h" + +namespace command_buffer { +namespace o3d { + +class GAPID3D9; + +// D3D9 version of VertexBuffer. +class VertexBufferD3D9 : public VertexBuffer { + public: + VertexBufferD3D9(unsigned int size, unsigned int flags) + : VertexBuffer(size, flags), + d3d_vertex_buffer_(NULL) {} + virtual ~VertexBufferD3D9(); + // Creates the D3D vertex buffer. + void Create(GAPID3D9 *gapi); + // Sets the data into the D3D vertex buffer. + bool SetData(unsigned int offset, unsigned int size, const void *data); + // Gets the data from the D3D vertex buffer. + bool GetData(unsigned int offset, unsigned int size, void *data); + + // Gets the D3D vertex buffer. + IDirect3DVertexBuffer9 * d3d_vertex_buffer() { return d3d_vertex_buffer_; } + private: + IDirect3DVertexBuffer9 *d3d_vertex_buffer_; + DISALLOW_COPY_AND_ASSIGN(VertexBufferD3D9); +}; + +// D3D9 version of IndexBuffer. +class IndexBufferD3D9 : public IndexBuffer { + public: + IndexBufferD3D9(unsigned int size, unsigned int flags) + : IndexBuffer(size, flags), + d3d_index_buffer_(NULL) {} + virtual ~IndexBufferD3D9(); + // Creates the D3D index buffer. + void Create(GAPID3D9 *gapi); + // Sets the data into the D3D index buffer. + bool SetData(unsigned int offset, unsigned int size, const void *data); + // Gets the data from the D3D index buffer. + bool GetData(unsigned int offset, unsigned int size, void *data); + + // Gets the D3D index buffer. + IDirect3DIndexBuffer9 *d3d_index_buffer() const { return d3d_index_buffer_; } + private: + IDirect3DIndexBuffer9 *d3d_index_buffer_; + DISALLOW_COPY_AND_ASSIGN(IndexBufferD3D9); +}; + +// D3D9 version of VertexStruct. +class VertexStructD3D9 : public VertexStruct { + public: + explicit VertexStructD3D9(unsigned int count) + : VertexStruct(count), + dirty_(true), + d3d_vertex_decl_(NULL) {} + virtual ~VertexStructD3D9(); + // Adds an input to the vertex struct. + void SetInput(unsigned int input_index, + ResourceId vertex_buffer_id, + unsigned int offset, + unsigned int stride, + vertex_struct::Type type, + vertex_struct::Semantic semantic, + unsigned int semantic_index); + // Sets the input streams to D3D. + unsigned int SetStreams(GAPID3D9 *gapi); + private: + // Destroys the vertex declaration and stream map. + void Destroy(); + // Compiles the vertex declaration and stream map. + void Compile(IDirect3DDevice9 *d3d_device); + + bool dirty_; + typedef std::pair StreamPair; + std::vector streams_; + IDirect3DVertexDeclaration9 *d3d_vertex_decl_; + DISALLOW_COPY_AND_ASSIGN(VertexStructD3D9); +}; + +} // namespace o3d +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_WIN_D3D9_GEOMETRY_D3D9_H_ diff --git a/o3d/command_buffer/service/geometry_gl.cc b/o3d/command_buffer/service/geometry_gl.cc new file mode 100644 index 0000000..f6194a2 --- /dev/null +++ b/o3d/command_buffer/service/geometry_gl.cc @@ -0,0 +1,553 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the implementation of the VertexBufferGL, IndexBufferGL +// and VertexStructGL classes, as well as the geometry-related GAPI functions. + +#include "command_buffer/service/gapi_gl.h" +#include "command_buffer/service/geometry_gl.h" + +namespace command_buffer { +namespace o3d { + +VertexBufferGL::~VertexBufferGL() { + glDeleteBuffers(1, &gl_buffer_); + CHECK_GL_ERROR(); +} + +// Creates the GL buffer object. +void VertexBufferGL::Create() { + glGenBuffers(1, &gl_buffer_); + glBindBuffer(GL_ARRAY_BUFFER, gl_buffer_); + GLenum usage = + (flags() & vertex_buffer::kDynamic) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW; + glBufferData(GL_ARRAY_BUFFER, size(), NULL, usage); + CHECK_GL_ERROR(); +} + +// Sets the data into the GL buffer object. +bool VertexBufferGL::SetData(unsigned int offset, + unsigned int size, + const void *data) { + if (!gl_buffer_) { + LOG(ERROR) << "Calling SetData on a non-initialized VertexBufferGL."; + return false; + } + if ((offset >= this->size()) || (offset + size > this->size())) { + LOG(ERROR) << "Invalid size or offset on VertexBufferGL::SetData."; + return false; + } + glBindBuffer(GL_ARRAY_BUFFER, gl_buffer_); + glBufferSubData(GL_ARRAY_BUFFER, offset, size, data); + CHECK_GL_ERROR(); + return true; +} + +// Gets the data from the GL buffer object. +bool VertexBufferGL::GetData(unsigned int offset, + unsigned int size, + void *data) { + if (!gl_buffer_) { + LOG(ERROR) << "Calling GetData on a non-initialized VertexBufferGL."; + return false; + } + if ((offset >= this->size()) || (offset + size > this->size())) { + LOG(ERROR) << "Invalid size or offset on VertexBufferGL::GetData."; + return false; + } + glBindBuffer(GL_ARRAY_BUFFER, gl_buffer_); + glGetBufferSubData(GL_ARRAY_BUFFER, offset, size, data); + CHECK_GL_ERROR(); + return true; +} + +IndexBufferGL::~IndexBufferGL() { + glDeleteBuffers(1, &gl_buffer_); +} + +// Creates the GL buffer object. +void IndexBufferGL::Create() { + glGenBuffers(1, &gl_buffer_); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl_buffer_); + GLenum usage = + (flags() & vertex_buffer::kDynamic) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW; + glBufferData(GL_ELEMENT_ARRAY_BUFFER, size(), NULL, usage); + CHECK_GL_ERROR(); +} + +// Sets the data into the GL buffer object. +bool IndexBufferGL::SetData(unsigned int offset, + unsigned int size, + const void *data) { + if (!gl_buffer_) { + LOG(ERROR) << "Calling SetData on a non-initialized IndexBufferGL."; + return false; + } + if ((offset >= this->size()) || (offset + size > this->size())) { + LOG(ERROR) << "Invalid size or offset on IndexBufferGL::SetData."; + return false; + } + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl_buffer_); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, size, data); + CHECK_GL_ERROR(); + return true; +} + +// Gets the data from the GL buffer object. +bool IndexBufferGL::GetData(unsigned int offset, + unsigned int size, + void *data) { + if (!gl_buffer_) { + LOG(ERROR) << "Calling GetData on a non-initialized IndexBufferGL."; + return false; + } + if ((offset >= this->size()) || (offset + size > this->size())) { + LOG(ERROR) << "Invalid size or offset on IndexBufferGL::GetData."; + return false; + } + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl_buffer_); + glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, size, data); + CHECK_GL_ERROR(); + return true; +} + +// Sets the input element in the VertexStruct resource. +void VertexStructGL::SetInput(unsigned int input_index, + ResourceId vertex_buffer_id, + unsigned int offset, + unsigned int stride, + vertex_struct::Type type, + vertex_struct::Semantic semantic, + unsigned int semantic_index) { + Element &element = GetElement(input_index); + element.vertex_buffer = vertex_buffer_id; + element.offset = offset; + element.stride = stride; + element.type = type; + element.semantic = semantic; + element.semantic_index = semantic_index; + dirty_ = true; +} + +namespace { + +inline ptrdiff_t OffsetToPtrDiff(unsigned int offset) { + return static_cast(offset); +} + +inline void* OffsetToPtr(ptrdiff_t offset) { + return reinterpret_cast(offset); +} + +} // anonymous namespace + +unsigned int VertexStructGL::SetStreams(GAPIGL *gapi) { + if (dirty_) Compile(); + unsigned int max_vertices = UINT_MAX; + for (unsigned int i = 0; i < kMaxAttribs; ++i) { + const AttribDesc &attrib = attribs_[i]; + if (attrib.vertex_buffer_id == kInvalidResource) { + if (i == 0) { + glDisableClientState(GL_VERTEX_ARRAY); + } else { + glDisableVertexAttribArray(i); + } + } else { + glEnableVertexAttribArray(i); + VertexBufferGL *vertex_buffer = + gapi->GetVertexBuffer(attrib.vertex_buffer_id); + if (!vertex_buffer) { + glDisableVertexAttribArray(i); + max_vertices = 0; + continue; + } + DCHECK_NE(vertex_buffer->gl_buffer(), 0); + glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer->gl_buffer()); + glVertexAttribPointer(i, attrib.size, attrib.type, attrib.normalized, + attrib.stride, + OffsetToPtr(attrib.offset)); + max_vertices = std::min(max_vertices, + vertex_buffer->size() / attrib.stride); + } + } + CHECK_GL_ERROR(); + return max_vertices; +} + +namespace { + +// from the ARB_vertex_program extension, at +// http://www.opengl.org/registry/specs/ARB/vertex_program.txt +// +// Generic +// Attribute Conventional Attribute Conventional Attribute Command +// --------- ------------------------ ------------------------------ +// 0 vertex position Vertex +// 1 vertex weights 0-3 WeightARB, VertexWeightEXT +// 2 normal Normal +// 3 primary color Color +// 4 secondary color SecondaryColorEXT +// 5 fog coordinate FogCoordEXT +// 6 - - +// 7 - - +// 8 texture coordinate set 0 MultiTexCoord(TEXTURE0, ...) +// 9 texture coordinate set 1 MultiTexCoord(TEXTURE1, ...) +// 10 texture coordinate set 2 MultiTexCoord(TEXTURE2, ...) +// 11 texture coordinate set 3 MultiTexCoord(TEXTURE3, ...) +// 12 texture coordinate set 4 MultiTexCoord(TEXTURE4, ...) +// 13 texture coordinate set 5 MultiTexCoord(TEXTURE5, ...) +// 14 texture coordinate set 6 MultiTexCoord(TEXTURE6, ...) +// 15 texture coordinate set 7 MultiTexCoord(TEXTURE7, ...) +// 8+n texture coordinate set n MultiTexCoord(TEXTURE0+n, ...) +// +// Note: we only accept at most 8 texture coordinates for maximum compatibility +// with DirectX. + +inline unsigned int GetAttribIndex(vertex_struct::Semantic semantic, + unsigned int semantic_index) { + switch (semantic) { + case vertex_struct::kPosition: + DCHECK_EQ(semantic_index, 0); + return 0; + case vertex_struct::kNormal: + DCHECK_EQ(semantic_index, 0); + return 2; + case vertex_struct::kColor: + DCHECK_LT(semantic_index, 2U); + return 3 + semantic_index; + case vertex_struct::kTexCoord: + DCHECK_LT(semantic_index, 8U); + return 8 + semantic_index; + default: + DLOG(FATAL) << "Not reached."; + return 0; + } +} + +inline void ExtractSizeTypeNormalized(vertex_struct::Type type, + GLint *size, + GLenum *gl_type, + GLboolean *normalized) { + switch (type) { + case vertex_struct::kFloat1: + case vertex_struct::kFloat2: + case vertex_struct::kFloat3: + case vertex_struct::kFloat4: + *size = type - vertex_struct::kFloat1 + 1; + *gl_type = GL_FLOAT; + *normalized = false; + break; + case vertex_struct::kUChar4N: + *size = 4; + *gl_type = GL_UNSIGNED_BYTE; + *normalized = true; + break; + default: + DLOG(FATAL) << "Not reached."; + break; + } +} + +} // anonymous namespace + +#ifndef COMPILER_MSVC +// Although required by the spec, this causes problems on MSVC. It is needed by +// GCC. +const unsigned int VertexStructGL::kMaxAttribs; +#endif + +void VertexStructGL::Compile() { + DCHECK(dirty_); + for (unsigned int i = 0; i < kMaxAttribs; ++i) { + attribs_[i].vertex_buffer_id = kInvalidResource; + } + for (unsigned int i = 0; i < count_ ; ++i) { + const Element &element = GetElement(i); + unsigned int index = GetAttribIndex(element.semantic, + element.semantic_index); + DCHECK_LT(index, kMaxAttribs); + AttribDesc &attrib = attribs_[index]; + attrib.vertex_buffer_id = element.vertex_buffer; + ExtractSizeTypeNormalized(element.type, &attrib.size, &attrib.type, + &attrib.normalized); + attrib.stride = element.stride; + attrib.offset = OffsetToPtrDiff(element.offset); + } + dirty_ = false; +} + +parse_error::ParseError GAPIGL::CreateVertexBuffer(ResourceId id, + unsigned int size, + unsigned int flags) { + VertexBufferGL *vertex_buffer = new VertexBufferGL(size, flags); + vertex_buffer->Create(); + vertex_buffers_.Assign(id, vertex_buffer); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIGL::DestroyVertexBuffer(ResourceId id) { + return vertex_buffers_.Destroy(id) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +parse_error::ParseError GAPIGL::SetVertexBufferData(ResourceId id, + unsigned int offset, + unsigned int size, + const void *data) { + VertexBufferGL *vertex_buffer = vertex_buffers_.Get(id); + if (!vertex_buffer) return parse_error::kParseInvalidArguments; + return vertex_buffer->SetData(offset, size, data) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +parse_error::ParseError GAPIGL::GetVertexBufferData(ResourceId id, + unsigned int offset, + unsigned int size, + void *data) { + VertexBufferGL *vertex_buffer = vertex_buffers_.Get(id); + if (!vertex_buffer) return parse_error::kParseInvalidArguments; + return vertex_buffer->GetData(offset, size, data) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +parse_error::ParseError GAPIGL::CreateIndexBuffer(ResourceId id, + unsigned int size, + unsigned int flags) { + IndexBufferGL *index_buffer = new IndexBufferGL(size, flags); + index_buffer->Create(); + index_buffers_.Assign(id, index_buffer); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIGL::DestroyIndexBuffer(ResourceId id) { + return index_buffers_.Destroy(id) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +parse_error::ParseError GAPIGL::SetIndexBufferData(ResourceId id, + unsigned int offset, + unsigned int size, + const void *data) { + IndexBufferGL *index_buffer = index_buffers_.Get(id); + if (!index_buffer) return parse_error::kParseInvalidArguments; + return index_buffer->SetData(offset, size, data) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +parse_error::ParseError GAPIGL::GetIndexBufferData(ResourceId id, + unsigned int offset, + unsigned int size, + void *data) { + IndexBufferGL *index_buffer = index_buffers_.Get(id); + if (!index_buffer) return parse_error::kParseInvalidArguments; + return index_buffer->GetData(offset, size, data) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +parse_error::ParseError GAPIGL::CreateVertexStruct( + ResourceId id, + unsigned int input_count) { + if (id == current_vertex_struct_) validate_streams_ = true; + VertexStructGL *vertex_struct = new VertexStructGL(input_count); + vertex_structs_.Assign(id, vertex_struct); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIGL::DestroyVertexStruct(ResourceId id) { + if (id == current_vertex_struct_) validate_streams_ = true; + return vertex_structs_.Destroy(id) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +parse_error::ParseError GAPIGL::SetVertexInput( + ResourceId vertex_struct_id, + unsigned int input_index, + ResourceId vertex_buffer_id, + unsigned int offset, + unsigned int stride, + vertex_struct::Type type, + vertex_struct::Semantic semantic, + unsigned int semantic_index) { + switch (semantic) { + case vertex_struct::kPosition: + if (semantic_index != 0) { + return parse_error::kParseInvalidArguments; + } + break; + case vertex_struct::kNormal: + if (semantic_index != 0) { + return parse_error::kParseInvalidArguments; + } + break; + case vertex_struct::kColor: + if (semantic_index >= 2) { + return parse_error::kParseInvalidArguments; + } + break; + case vertex_struct::kTexCoord: + if (semantic_index >= 8) { + return parse_error::kParseInvalidArguments; + } + break; + default: + DLOG(FATAL) << "Not reached."; + break; + } + if (vertex_buffer_id == current_vertex_struct_) validate_streams_ = true; + VertexStructGL *vertex_struct = vertex_structs_.Get(vertex_struct_id); + if (!vertex_struct || input_index >= vertex_struct->count()) + return parse_error::kParseInvalidArguments; + vertex_struct->SetInput(input_index, vertex_buffer_id, offset, stride, type, + semantic, semantic_index); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIGL::SetVertexStruct(ResourceId id) { + current_vertex_struct_ = id; + validate_streams_ = true; + return parse_error::kParseNoError; +} + +bool GAPIGL::ValidateStreams() { + DCHECK(validate_streams_); + VertexStructGL *vertex_struct = vertex_structs_.Get(current_vertex_struct_); + if (!vertex_struct) { + LOG(ERROR) << "Drawing with invalid streams."; + return false; + } + max_vertices_ = vertex_struct->SetStreams(this); + validate_streams_ = false; + return max_vertices_ > 0; +} + +namespace { + +void PrimitiveTypeToGL(o3d::PrimitiveType primitive_type, + GLenum *gl_mode, + unsigned int *count) { + switch (primitive_type) { + case o3d::kPoints: + *gl_mode = GL_POINTS; + break; + case o3d::kLines: + *gl_mode = GL_LINES; + *count *= 2; + break; + case o3d::kLineStrips: + *gl_mode = GL_LINE_STRIP; + ++*count; + break; + case o3d::kTriangles: + *gl_mode = GL_TRIANGLES; + *count *= 3; + break; + case o3d::kTriangleStrips: + *gl_mode = GL_TRIANGLE_STRIP; + *count += 2; + break; + case o3d::kTriangleFans: + *gl_mode = GL_TRIANGLE_FAN; + *count += 2; + break; + default: + LOG(FATAL) << "Invalid primitive type"; + break; + } +} + +} // anonymous namespace + +parse_error::ParseError GAPIGL::Draw(o3d::PrimitiveType primitive_type, + unsigned int first, + unsigned int count) { + if (validate_effect_ && !ValidateEffect()) { + return parse_error::kParseInvalidArguments; + } + DCHECK(current_effect_); + if (validate_streams_ && !ValidateStreams()) { + return parse_error::kParseInvalidArguments; + } + GLenum gl_mode = GL_POINTS; + PrimitiveTypeToGL(primitive_type, &gl_mode, &count); + if (first + count > max_vertices_) { + return parse_error::kParseInvalidArguments; + } + glDrawArrays(gl_mode, first, count); + CHECK_GL_ERROR(); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIGL::DrawIndexed( + o3d::PrimitiveType primitive_type, + ResourceId index_buffer_id, + unsigned int first, + unsigned int count, + unsigned int min_index, + unsigned int max_index) { + IndexBufferGL *index_buffer = index_buffers_.Get(index_buffer_id); + if (!index_buffer) return parse_error::kParseInvalidArguments; + if (validate_effect_ && !ValidateEffect()) { + return parse_error::kParseInvalidArguments; + } + DCHECK(current_effect_); + if (validate_streams_ && !ValidateStreams()) { + return parse_error::kParseInvalidArguments; + } + if ((min_index >= max_vertices_) || (max_index > max_vertices_)) { + return parse_error::kParseInvalidArguments; + } + GLenum gl_mode = GL_POINTS; + PrimitiveTypeToGL(primitive_type, &gl_mode, &count); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer->gl_buffer()); + GLenum index_type = (index_buffer->flags() & index_buffer::kIndex32Bit) ? + GL_UNSIGNED_INT : GL_UNSIGNED_SHORT; + GLuint index_size = (index_buffer->flags() & index_buffer::kIndex32Bit) ? + sizeof(GLuint) : sizeof(GLushort); // NOLINT + GLuint offset = first * index_size; + if (offset + count * index_size > index_buffer->size()) { + return parse_error::kParseInvalidArguments; + } + glDrawRangeElements(gl_mode, min_index, max_index, count, index_type, + OffsetToPtr(offset)); + CHECK_GL_ERROR(); + return parse_error::kParseNoError; +} + +} // namespace o3d +} // namespace command_buffer diff --git a/o3d/command_buffer/service/geometry_gl.h b/o3d/command_buffer/service/geometry_gl.h new file mode 100644 index 0000000..4849330 --- /dev/null +++ b/o3d/command_buffer/service/geometry_gl.h @@ -0,0 +1,144 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file declares the VertexBufferGL, IndexBufferGL and VertexStructGL +// classes. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_GL_GEOMETRY_GL_H_ +#define GPU_COMMAND_BUFFER_SERVICE_CROSS_GL_GEOMETRY_GL_H_ + +#include "command_buffer/common/gapi_interface.h" +#include "command_buffer/service/resource.h" +#include "command_buffer/service/gl_utils.h" + +namespace command_buffer { +namespace o3d { + +class GAPIGL; + +// GL version of VertexBuffer. +class VertexBufferGL : public VertexBuffer { + public: + VertexBufferGL(unsigned int size, unsigned int flags) + : VertexBuffer(size, flags), + gl_buffer_(0) {} + virtual ~VertexBufferGL(); + + // Creates the GL vertex buffer. + void Create(); + + // Sets the data into the GL vertex buffer. + bool SetData(unsigned int offset, unsigned int size, const void *data); + + // Gets the data from the GL vertex buffer. + bool GetData(unsigned int offset, unsigned int size, void *data); + + // Gets the GL vertex buffer. + GLuint gl_buffer() const { return gl_buffer_; } + + private: + GLuint gl_buffer_; + DISALLOW_COPY_AND_ASSIGN(VertexBufferGL); +}; + +// GL version of IndexBuffer. +class IndexBufferGL : public IndexBuffer { + public: + IndexBufferGL(unsigned int size, unsigned int flags) + : IndexBuffer(size, flags), + gl_buffer_(0) {} + virtual ~IndexBufferGL(); + + // Creates the GL index buffer. + void Create(); + + // Sets the data into the GL index buffer. + bool SetData(unsigned int offset, unsigned int size, const void *data); + + // Gets the data from the GL index buffer. + bool GetData(unsigned int offset, unsigned int size, void *data); + + // Gets the GL index buffer. + GLuint gl_buffer() const { return gl_buffer_; } + + private: + GLuint gl_buffer_; + DISALLOW_COPY_AND_ASSIGN(IndexBufferGL); +}; + +// GL version of VertexStruct. +class VertexStructGL : public VertexStruct { + public: + explicit VertexStructGL(unsigned int count) + : VertexStruct(count), + dirty_(true) {} + virtual ~VertexStructGL() {} + + // Adds an input to the vertex struct. + void SetInput(unsigned int input_index, + ResourceId vertex_buffer_id, + unsigned int offset, + unsigned int stride, + vertex_struct::Type type, + vertex_struct::Semantic semantic, + unsigned int semantic_index); + + // Sets the input streams to GL. + unsigned int SetStreams(GAPIGL *gapi); + + private: + static const unsigned int kMaxAttribs = 16; + + // This struct describes the parameters that are passed to + // glVertexAttribPointer. + struct AttribDesc { + ResourceId vertex_buffer_id; + GLint size; + GLenum type; + GLboolean normalized; + GLsizei stride; + ptrdiff_t offset; + }; + + // Compiles the vertex declaration into the attribute array. + void Compile(); + + bool dirty_; + AttribDesc attribs_[kMaxAttribs]; + DISALLOW_COPY_AND_ASSIGN(VertexStructGL); +}; + + +} // namespace o3d +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_GL_GEOMETRY_GL_H_ diff --git a/o3d/command_buffer/service/gl_utils.h b/o3d/command_buffer/service/gl_utils.h new file mode 100644 index 0000000..2034260 --- /dev/null +++ b/o3d/command_buffer/service/gl_utils.h @@ -0,0 +1,60 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file includes all the necessary GL/Cg headers and implements some useful +// utilities. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_GL_GL_UTILS_H_ +#define GPU_COMMAND_BUFFER_SERVICE_CROSS_GL_GL_UTILS_H_ + +#include +#if defined(OS_WIN) +#include +#endif +#include +#include +#include + +#define GL_GLEXT_PROTOTYPES + +// Define this for extra GL error debugging (slower). +// #define GL_ERROR_DEBUGGING +#ifdef GL_ERROR_DEBUGGING +#define CHECK_GL_ERROR() do { \ + GLenum gl_error = glGetError(); \ + LOG_IF(ERROR, gl_error != GL_NO_ERROR) << "GL Error :" << gl_error; \ + } while (0) +#else // GL_ERROR_DEBUGGING +#define CHECK_GL_ERROR() void(0) +#endif // GL_ERROR_DEBUGGING + +#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_GL_GL_UTILS_H_ diff --git a/o3d/command_buffer/service/mocks.h b/o3d/command_buffer/service/mocks.h new file mode 100644 index 0000000..9cbfe67 --- /dev/null +++ b/o3d/command_buffer/service/mocks.h @@ -0,0 +1,108 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains definitions for mock objects, used for testing. + +// TODO: This file "manually" defines some mock objects. Using gMock +// would be definitely preferable, unfortunately it doesn't work on Windows +// yet. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_MOCKS_H_ +#define GPU_COMMAND_BUFFER_SERVICE_CROSS_MOCKS_H_ + +#include +#include "gmock/gmock.h" +#include "command_buffer/service/cmd_parser.h" +#include "command_buffer/service/cmd_buffer_engine.h" + +namespace command_buffer { + +// Mocks an AsyncAPIInterface, using GMock. +class AsyncAPIMock : public AsyncAPIInterface { + public: + AsyncAPIMock() { + testing::DefaultValue::Set( + parse_error::kParseNoError); + } + + // Predicate that matches args passed to DoCommand, by looking at the values. + class IsArgs { + public: + IsArgs(unsigned int arg_count, const void* args) + : arg_count_(arg_count), + args_(static_cast(const_cast(args))) { + } + + bool operator() (const void* _args) const { + const CommandBufferEntry* args = + static_cast(_args) + 1; + for (unsigned int i = 0; i < arg_count_; ++i) { + if (args[i].value_uint32 != args_[i].value_uint32) return false; + } + return true; + } + + private: + unsigned int arg_count_; + CommandBufferEntry *args_; + }; + + MOCK_METHOD3(DoCommand, parse_error::ParseError( + unsigned int command, + unsigned int arg_count, + const void* cmd_data)); + + const char* GetCommandName(unsigned int command_id) const { + return ""; + }; + + // Sets the engine, to forward SetToken commands to it. + void set_engine(CommandBufferEngine *engine) { engine_ = engine; } + + // Forwards the SetToken commands to the engine. + void SetToken(unsigned int command, + unsigned int arg_count, + const void* _args) { + DCHECK(engine_); + DCHECK_EQ(1u, command); + DCHECK_EQ(1u, arg_count); + const CommandBufferEntry* args = + static_cast(_args); + engine_->set_token(args[0].value_uint32); + } + private: + CommandBufferEngine *engine_; +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_MOCKS_H_ diff --git a/o3d/command_buffer/service/precompile.cc b/o3d/command_buffer/service/precompile.cc new file mode 100644 index 0000000..62eb0f4 --- /dev/null +++ b/o3d/command_buffer/service/precompile.cc @@ -0,0 +1,33 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "command_buffer/service/precompile.h" diff --git a/o3d/command_buffer/service/precompile.h b/o3d/command_buffer/service/precompile.h new file mode 100644 index 0000000..55d2b21 --- /dev/null +++ b/o3d/command_buffer/service/precompile.h @@ -0,0 +1,50 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains includes for common headers used by command buffer server +// files. It is used for pre-compiled header support. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_PRECOMPILE_H_ +#define GPU_COMMAND_BUFFER_SERVICE_CROSS_PRECOMPILE_H_ + +#include + +#if defined(OS_WIN) +#include +#endif + +#include +#include +#include +#include + +#endif // O3D_CORE_CROSS_PRECOMPILE_H_ diff --git a/o3d/command_buffer/service/render_surface_d3d9.cc b/o3d/command_buffer/service/render_surface_d3d9.cc new file mode 100644 index 0000000..daa5ee2 --- /dev/null +++ b/o3d/command_buffer/service/render_surface_d3d9.cc @@ -0,0 +1,229 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file implements the D3D9 versions of the render surface resources, +// as well as the related GAPID3D9 function implementations. + +#include "command_buffer/service/render_surface_d3d9.h" +#include "command_buffer/service/gapi_d3d9.h" +#include "command_buffer/service/texture_d3d9.h" + + +namespace command_buffer { +namespace o3d { + +RenderSurfaceD3D9::RenderSurfaceD3D9(int width, + int height, + int mip_level, + int side, + TextureD3D9 *texture, + IDirect3DSurface9 *direct3d_surface) + : width_(width), + height_(height), + mip_level_(mip_level), + texture_(texture), + direct3d_surface_(direct3d_surface) { + DCHECK_GT(width, 0); + DCHECK_GT(height, 0); + DCHECK_GT(mip_level, -1); + DCHECK(texture); +} + +RenderSurfaceD3D9* RenderSurfaceD3D9::Create(GAPID3D9 *gapi, + int width, + int height, + int mip_level, + int side, + TextureD3D9 *texture) { + DCHECK(gapi); + DCHECK_GT(width, 0); + DCHECK_GT(height, 0); + DCHECK_GT(mip_level, -1); + DCHECK(texture); + CComPtr direct3d_surface_handle; + bool success = + texture->CreateRenderSurface(width, height, mip_level, side, + &direct3d_surface_handle); + if (!success || direct3d_surface_handle == NULL) { + // If the surface was not created properly, delete and return nothing. + return NULL; + } + RenderSurfaceD3D9 *render_surface = + new RenderSurfaceD3D9(width, + height, + mip_level, + side, + texture, + direct3d_surface_handle); + return render_surface; +} + +RenderDepthStencilSurfaceD3D9::RenderDepthStencilSurfaceD3D9( + int width, + int height, + IDirect3DSurface9 *direct3d_surface) + : width_(width), + height_(height), + direct3d_surface_(direct3d_surface) { + DCHECK_GT(width, 0); + DCHECK_GT(height, 0); +} + +RenderDepthStencilSurfaceD3D9* RenderDepthStencilSurfaceD3D9::Create( + GAPID3D9 *gapi, + int width, + int height) { + DCHECK(gapi); + DCHECK_GT(width, 0); + DCHECK_GT(height, 0); + + CComPtr direct3d_surface; + gapi->d3d_device()->CreateDepthStencilSurface( + width, + height, + D3DFMT_D24S8, // d3d format + D3DMULTISAMPLE_NONE, // multisampling type + 0, // multisample quality level + FALSE, // z-buffer discarding disabled + &direct3d_surface, + NULL); // This parameter is required to be NULL. + if (direct3d_surface == NULL) { + return NULL; + } + RenderDepthStencilSurfaceD3D9 *depth_stencil = + new RenderDepthStencilSurfaceD3D9(width, height, direct3d_surface); + return depth_stencil; +} + +// GAPI Interface functions --------------------------------------------------- + +// Copies the data from a texture resource. +parse_error::ParseError GAPID3D9::CreateRenderSurface( + ResourceId id, + unsigned int width, + unsigned int height, + unsigned int mip_level, + unsigned int side, + ResourceId texture_id) { + if (id == current_surface_id_) { + // This will delete the current surface which would be bad. + return parse_error::kParseInvalidArguments; + } + TextureD3D9 *texture = textures_.Get(texture_id); + if (!texture->render_surfaces_enabled()) { + return parse_error::kParseInvalidArguments; + } else { + RenderSurfaceD3D9 *render_surface = RenderSurfaceD3D9::Create(this, + width, + height, + mip_level, + side, + texture); + if (render_surface == NULL) { + return parse_error::kParseInvalidArguments; + } + render_surfaces_.Assign(id, render_surface); + } + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPID3D9::DestroyRenderSurface(ResourceId id) { + if (id == current_surface_id_) { + return parse_error::kParseInvalidArguments; + } + return render_surfaces_.Destroy(id) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +parse_error::ParseError GAPID3D9::CreateDepthSurface( + ResourceId id, + unsigned int width, + unsigned int height) { + if (id == current_depth_surface_id_) { + // This will delete the current surface which would be bad. + return parse_error::kParseInvalidArguments; + } + RenderDepthStencilSurfaceD3D9 *depth_surface = + RenderDepthStencilSurfaceD3D9::Create(this, width, height); + if (depth_surface == NULL) { + return parse_error::kParseInvalidArguments; + } + depth_surfaces_.Assign(id, depth_surface); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPID3D9::DestroyDepthSurface(ResourceId id) { + if (id == current_depth_surface_id_) { + return parse_error::kParseInvalidArguments; + } + return depth_surfaces_.Destroy(id) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +parse_error::ParseError GAPID3D9::SetRenderSurface( + ResourceId render_surface_id, + ResourceId depth_stencil_id) { + RenderSurfaceD3D9 *d3d_render_surface = + render_surfaces_.Get(render_surface_id); + RenderDepthStencilSurfaceD3D9 *d3d_render_depth_surface = + depth_surfaces_.Get(depth_stencil_id); + + if (d3d_render_surface == NULL && d3d_render_depth_surface == NULL) { + return parse_error::kParseInvalidArguments; + } + + IDirect3DSurface9 *d3d_surface = + d3d_render_surface ? d3d_render_surface->direct3d_surface() : NULL; + IDirect3DSurface9 *d3d_depth_surface = d3d_render_depth_surface ? + d3d_render_depth_surface->direct3d_surface() : NULL; + + // Get the device and set the render target and the depth stencil surface. + IDirect3DDevice9 *device = this->d3d_device(); + + HR(device->SetRenderTarget(0, d3d_surface)); + HR(device->SetDepthStencilSurface(d3d_depth_surface)); + current_surface_id_ = render_surface_id; + current_depth_surface_id_ = depth_stencil_id; + return parse_error::kParseNoError; +} + +void GAPID3D9::SetBackSurfaces() { + // Get the device and set the render target and the depth stencil surface. + IDirect3DDevice9 *device = this->d3d_device(); + HR(d3d_device()->SetRenderTarget(0, back_buffer_surface_)); + HR(d3d_device()->SetDepthStencilSurface(back_buffer_depth_surface_)); +} + +} // namespace o3d +} // namespace command_buffer diff --git a/o3d/command_buffer/service/render_surface_d3d9.h b/o3d/command_buffer/service/render_surface_d3d9.h new file mode 100644 index 0000000..1094a5b --- /dev/null +++ b/o3d/command_buffer/service/render_surface_d3d9.h @@ -0,0 +1,161 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef GPU_COMMAND_BUFFER_SERVICE_WIN_D3D9_RENDER_SURFACE_D3D9_H_ +#define GPU_COMMAND_BUFFER_SERVICE_WIN_D3D9_RENDER_SURFACE_D3D9_H_ + +// This file contains the definition of the D3D9 versions of +// render surface-related resource classes. + +#include +#include "base/scoped_ptr.h" +#include "command_buffer/common/gapi_interface.h" +#include "command_buffer/service/resource.h" +#include "command_buffer/service/d3d9_utils.h" +#include "command_buffer/service/texture_d3d9.h" + +namespace command_buffer { +namespace o3d { + +class GAPID3D9; + +// The RenderSurfaceD3D class represents a render surface resource in the d3d +// backend of the command buffer server. +class RenderSurfaceD3D9 : public RenderSurface { + public: + + // Creates a render surface resource based on D3D. + // Parameters: + // width - width of the surface to be created. Must match width of texture + // at mip_level. + // height - height of the surface to be created. Must match width of + // texture at mip_level. + // mip_level - mip level of the texture to which the render surface maps. + // side - side of a cube if texture is a cube texture. Does not apply to + // texture 2d's. + // texture - the texture to which this render surface maps. Not owned by + // the RenderSurfaceD3D9. + // direct3d_surface - a surface to be used as this render surface's + // rendering surface. The new RenderSurfaceD3D9 will own the + // direct3d_surface. + RenderSurfaceD3D9(int width, + int height, + int mip_level, + int side, + TextureD3D9 *texture, + IDirect3DSurface9 *direct3d_surface); + + // Destructor for the render surface. + virtual ~RenderSurfaceD3D9() {} + + // Performs the setup necessary to create a render surface resource based on + // D3D and returns a new one if possibe. + // Parameters: + // gapi - the gapi interface to D3D. + // width - width of the surface to be created. Must match width of texture + // at mip_level. + // height - height of the surface to be created. Must match width of + // texture at mip_level. + // mip_level - mip level of the texture to which the render surface maps. + // side - side of a cube if texture is a cube texture. Does not apply to + // texture 2d's. + // texture - the texture to which this render surface maps. + // Returns: + // a new RenderSurfaceD3D9 or NULL on failure + static RenderSurfaceD3D9* Create(GAPID3D9 *gapi, + int width, + int height, + int mip_level, + int side, + TextureD3D9 *texture); + + // Returns a reference to the actual direct3d surface that is rendered to. + IDirect3DSurface9* direct3d_surface() const { + return direct3d_surface_; + } + private: + CComPtr direct3d_surface_; + int width_; + int height_; + int mip_level_; + TextureD3D9 *texture_; + DISALLOW_COPY_AND_ASSIGN(RenderSurfaceD3D9); +}; + +// The RenderDepthStencilSurfaceD3D class represents a depth stencil surface +// resource in the d3d backend of the command buffer server. +class RenderDepthStencilSurfaceD3D9 : public RenderDepthStencilSurface { + public: + + // Creates a depth stencil surface resource based on D3D. + // Parameters: + // width - width of the surface to be created. + // height - height of the surface to be created. + // direct3d_surface - a surface to be used as this depth stencil surface's + // rendering rendering surface. The new RenderDepthStencilSurfaceD3D9 + // will own the direct3d_surface. + RenderDepthStencilSurfaceD3D9(int width, + int height, + IDirect3DSurface9 *direct3d_surface); + + // Destructor for the depth stencil surface. + virtual ~RenderDepthStencilSurfaceD3D9() {} + + + // Performs the setup necessary to create a depth stencil surface resource + // based on D3D and returns a new one if possibe. + // Parameters: + // gapi - the gapi interface to D3D. + // width - width of the surface to be created. + // height - height of the surface to be created. + // Returns: + // a new RenderDepthStencilSurfaceD3D9 or NULL on failure. + static RenderDepthStencilSurfaceD3D9* Create(GAPID3D9 *gapi, + int width, + int height); + + // Returns a reference to the actual direct3d surface that is rendered to. + IDirect3DSurface9* direct3d_surface() const { + return direct3d_surface_; + } + private: + CComPtr direct3d_surface_; + int width_; + int height_; + DISALLOW_COPY_AND_ASSIGN(RenderDepthStencilSurfaceD3D9); +}; + +} // namespace o3d +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_WIN_D3D9_RENDER_SURFACE_D3D9_H_ + diff --git a/o3d/command_buffer/service/render_surface_gl.cc b/o3d/command_buffer/service/render_surface_gl.cc new file mode 100644 index 0000000..1c06131 --- /dev/null +++ b/o3d/command_buffer/service/render_surface_gl.cc @@ -0,0 +1,261 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file implements the OpenGL versions of the render surface resources, +// as well as the related GAPIGL function implementations. + +#include "command_buffer/service/gapi_gl.h" +#include "command_buffer/service/render_surface_gl.h" + + +namespace command_buffer { +namespace o3d { + +RenderSurfaceGL::RenderSurfaceGL(int width, + int height, + int mip_level, + int side, + TextureGL *texture) + : width_(width), height_(height), mip_level_(mip_level), texture_(texture) { +} + +RenderSurfaceGL* RenderSurfaceGL::Create(int width, + int height, + int mip_level, + int side, + TextureGL *texture) { + DCHECK_GT(width, 0); + DCHECK_GT(height, 0); + DCHECK_GE(mip_level, 0); + DCHECK(texture); + + RenderSurfaceGL* render_surface = + new RenderSurfaceGL(width, height, mip_level, side, texture); + return render_surface; +} + +RenderDepthStencilSurfaceGL::RenderDepthStencilSurfaceGL( + int width, + int height) + : width_(width), height_(height) { + DCHECK_GT(width, 0); + DCHECK_GT(height, 0); + + // If packed depth stencil is supported, create only one buffer for both + // depth and stencil. + if (GLEW_EXT_packed_depth_stencil) { + glGenRenderbuffersEXT(1, render_buffers_); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, render_buffers_[0]); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, + GL_DEPTH24_STENCIL8_EXT, + width, + height); + CHECK_GL_ERROR(); + render_buffers_[1] = render_buffers_[0]; + } else { + glGenRenderbuffersEXT(2, render_buffers_); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, render_buffers_[0]); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, + GL_DEPTH_COMPONENT24, + width, + height); + CHECK_GL_ERROR(); + + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, render_buffers_[1]); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, + GL_STENCIL_INDEX8_EXT, + width, + height); + CHECK_GL_ERROR(); + } +} + +RenderDepthStencilSurfaceGL* RenderDepthStencilSurfaceGL::Create( + int width, + int height) { + DCHECK_GT(width, 0); + DCHECK_GT(height, 0); + + return new RenderDepthStencilSurfaceGL(height, width); +} + +// Copies the data from a texture resource. +parse_error::ParseError GAPIGL::CreateRenderSurface( + ResourceId id, + unsigned int width, + unsigned int height, + unsigned int mip_level, + unsigned int side, + ResourceId texture_id) { + if (id == current_surface_id_) { + // This will delete the current surface which would be bad. + return parse_error::kParseInvalidArguments; + } + TextureGL *texture = textures_.Get(texture_id); + if (!texture->render_surfaces_enabled()) { + return parse_error::kParseInvalidArguments; + } else { + RenderSurfaceGL* render_surface = RenderSurfaceGL::Create(width, + height, + mip_level, + side, + texture); + if (render_surface == NULL) { + return parse_error::kParseInvalidArguments; + } + render_surfaces_.Assign(id, render_surface); + } + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIGL::DestroyRenderSurface(ResourceId id) { + if (id == current_surface_id_) { + return parse_error::kParseInvalidArguments; + } + return render_surfaces_.Destroy(id) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +parse_error::ParseError GAPIGL::CreateDepthSurface( + ResourceId id, + unsigned int width, + unsigned int height) { + if (id == current_depth_surface_id_) { + // This will delete the current surface which would be bad. + return parse_error::kParseInvalidArguments; + } + RenderDepthStencilSurfaceGL* depth_surface = + RenderDepthStencilSurfaceGL::Create(width, height); + if (depth_surface == NULL) { + return parse_error::kParseInvalidArguments; + } + depth_surfaces_.Assign(id, depth_surface); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIGL::DestroyDepthSurface(ResourceId id) { + if (id == current_depth_surface_id_) { + return parse_error::kParseInvalidArguments; + } + return depth_surfaces_.Destroy(id) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +void ResetBoundAttachments() { +#ifdef _DEBUG + GLint bound_framebuffer; + ::glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &bound_framebuffer); + DCHECK(bound_framebuffer != 0); +#endif + + // Reset the bound attachments to the current framebuffer object. + ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, + GL_RENDERBUFFER_EXT, + 0); + + ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, + GL_DEPTH_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, + 0); + + ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, + GL_STENCIL_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, + 0); + + CHECK_GL_ERROR(); +} + +bool BindDepthStencilBuffer(const RenderDepthStencilSurfaceGL* gl_surface) { + // Bind both the depth and stencil attachments. + ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, + GL_DEPTH_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, + gl_surface->depth_buffer()); + ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, + GL_STENCIL_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, + gl_surface->stencil_buffer()); + + // Check for errors. + GLenum framebuffer_status = ::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + if (GL_FRAMEBUFFER_COMPLETE_EXT != framebuffer_status) { + return false; + } + + CHECK_GL_ERROR(); + return true; +} + +parse_error::ParseError GAPIGL::SetRenderSurface( + ResourceId render_surface_id, + ResourceId depth_stencil_id) { + if (render_surfaces_.Get(render_surface_id) == NULL && + depth_surfaces_.Get(depth_stencil_id) == NULL) { + return parse_error::kParseInvalidArguments; + } + + ::glBindFramebufferEXT(GL_FRAMEBUFFER, render_surface_framebuffer_); + ResetBoundAttachments(); + + RenderSurfaceGL* render_surface = render_surfaces_.Get(render_surface_id); + RenderDepthStencilSurfaceGL* depth_surface = + depth_surfaces_.Get(render_surface_id); + + if (!render_surface->texture()-> + InstallFrameBufferObjects(render_surface) || + !BindDepthStencilBuffer(depth_surface)) { + return parse_error::kParseInvalidArguments; + } + + // RenderSurface rendering is performed with an inverted Y, so the front + // face winding must be changed to clock-wise. See comments for + // UpdateHelperConstant. + glFrontFace(GL_CW); + + current_surface_id_ = render_surface_id; + current_depth_surface_id_ = depth_stencil_id; + return parse_error::kParseNoError; +} + +void GAPIGL::SetBackSurfaces() { + // Bind the default context, and restore the default front-face winding. + ::glBindFramebufferEXT(GL_FRAMEBUFFER, 0); + glFrontFace(GL_CCW); +} + +} // namespace o3d +} // namespace command_buffer + diff --git a/o3d/command_buffer/service/render_surface_gl.h b/o3d/command_buffer/service/render_surface_gl.h new file mode 100644 index 0000000..db6860d --- /dev/null +++ b/o3d/command_buffer/service/render_surface_gl.h @@ -0,0 +1,117 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_GL_RENDER_SURFACE_GL_H__ +#define GPU_COMMAND_BUFFER_SERVICE_CROSS_GL_RENDER_SURFACE_GL_H__ + +// This file contains the definition of the OpenGL versions of +// render surface-related resource classes. + +#include "command_buffer/service/texture_gl.h" +#include "command_buffer/service/resource.h" + +namespace command_buffer { +namespace o3d { + +class RenderSurfaceGL : public RenderSurface { + public: + RenderSurfaceGL(int width, + int height, + int mip_level, + int side, + TextureGL *texture); + virtual ~RenderSurfaceGL() {} + + static RenderSurfaceGL* Create(int width, + int height, + int mip_level, + int side, + TextureGL *texture); + TextureGL* texture() { + return texture_; + } + + int width() { + return width_; + } + + int height() { + return height_; + } + + int mip_level() { + return mip_level_; + } + + int side() { + return side_; + } + private: + unsigned int width_; + unsigned int height_; + unsigned int mip_level_; + unsigned int side_; + TextureGL* texture_; + DISALLOW_COPY_AND_ASSIGN(RenderSurfaceGL); +}; + +class RenderDepthStencilSurfaceGL : public RenderDepthStencilSurface { + public: + RenderDepthStencilSurfaceGL(int width, + int height); + virtual ~RenderDepthStencilSurfaceGL() {} + + static RenderDepthStencilSurfaceGL* Create( + int width, + int height); + + GLuint depth_buffer() const { + return render_buffers_[0]; + } + + GLuint stencil_buffer() const { + return render_buffers_[1]; + } + + private: + // Handles to the depth and stencil render-buffers, respectively. + GLuint render_buffers_[2]; + unsigned int width_; + unsigned int height_; + DISALLOW_COPY_AND_ASSIGN(RenderDepthStencilSurfaceGL); +}; + +} // namespace o3d +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_WIN_GL_RENDER_SURFACE_GL_H__ + diff --git a/o3d/command_buffer/service/resource.cc b/o3d/command_buffer/service/resource.cc new file mode 100644 index 0000000..c09b450 --- /dev/null +++ b/o3d/command_buffer/service/resource.cc @@ -0,0 +1,100 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the implementation of ResourceMapBase. + +#include "command_buffer/service/resource.h" + +namespace command_buffer { + +// Assigns a resource to a resource ID, by setting it at the right location +// into the list, resizing the list if necessary, and destroying an existing +// resource if one existed already. +void ResourceMapBase::Assign(ResourceId id, Resource *resource) { + if (id >= resources_.size()) { + resources_.resize(id + 1, NULL); + } else { + Resource *&entry = resources_[id]; + if (entry) { + delete entry; + entry = NULL; + } + } + DCHECK(resources_[id] == NULL); + resources_[id] = resource; +} + +// Destroys a resource contained in the map, setting its entry to NULL. If +// necessary, this will trim the list. +bool ResourceMapBase::Destroy(ResourceId id) { + if (id >= resources_.size()) { + return false; + } + Resource *&entry = resources_[id]; + if (entry) { + delete entry; + entry = NULL; + + // Removing the last element, we can trim the list. + // TODO: this may not be optimal to do every time. Investigate if it + // becomes an issue, and add a threshold before we resize. + if (id == resources_.size() - 1) { + size_t last_valid = resources_.max_size(); + for (unsigned int i = id; i < resources_.size(); --i) { + if (resources_[i]) { + last_valid = i; + break; + } + } + if (last_valid == resources_.max_size()) { + resources_.clear(); + } else { + resources_.resize(last_valid + 1); + } + } + return true; + } + return false; +} + +// Goes over all non-NULL entries in the list, destroying them, then clears the +// list. +void ResourceMapBase::DestroyAllResources() { + for (Container::iterator i = resources_.begin(); i != resources_.end(); ++i) { + if (*i) { + delete *i; + } + } + resources_.clear(); +} + +} // namespace command_buffer diff --git a/o3d/command_buffer/service/resource.h b/o3d/command_buffer/service/resource.h new file mode 100644 index 0000000..6a2c2e2 --- /dev/null +++ b/o3d/command_buffer/service/resource.h @@ -0,0 +1,268 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the definition for resource classes and the resource map. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_RESOURCE_H_ +#define GPU_COMMAND_BUFFER_SERVICE_CROSS_RESOURCE_H_ + +#include +#include "base/scoped_ptr.h" +#include "command_buffer/common/resource.h" + +namespace command_buffer { + +// Base class for resources, just providing a common Destroy function. +class Resource { + public: + Resource() {} + virtual ~Resource() {} + private: + DISALLOW_COPY_AND_ASSIGN(Resource); +}; + +// VertexBuffer class, representing a vertex buffer resource. +class VertexBuffer: public Resource { + public: + VertexBuffer(unsigned int size, unsigned int flags) + : size_(size), + flags_(flags) {} + virtual ~VertexBuffer() {} + + // Returns the vertex buffer flags. + unsigned int flags() const { return flags_; } + // Sets the vertex buffer flags. + void set_flags(unsigned int flags) { flags_ = flags; } + // Returns the vertex buffer size. + unsigned int size() const { return size_; } + // Sets the vertex buffer size. + void set_size(unsigned int size) { size_ = size; } + protected: + unsigned int size_; + unsigned int flags_; + private: + DISALLOW_COPY_AND_ASSIGN(VertexBuffer); +}; + +// IndexBuffer class, representing an index buffer resource. +class IndexBuffer: public Resource { + public: + IndexBuffer(unsigned int size, unsigned int flags) + : size_(size), + flags_(flags) {} + virtual ~IndexBuffer() {} + + // Returns the index buffer flags. + unsigned int flags() const { return flags_; } + // Sets the index buffer flags. + void set_flags(unsigned int flags) { flags_ = flags; } + // Returns the index buffer size. + unsigned int size() const { return size_; } + // Sets the index buffer size. + void set_size(unsigned int size) { size_ = size; } + protected: + unsigned int size_; + unsigned int flags_; + private: + DISALLOW_COPY_AND_ASSIGN(IndexBuffer); +}; + +// VertexStruct class, representing a vertex struct resource. +class VertexStruct: public Resource { + public: + // The representation of an input data stream. + struct Element { + ResourceId vertex_buffer; + unsigned int offset; + unsigned int stride; + vertex_struct::Type type; + vertex_struct::Semantic semantic; + unsigned int semantic_index; + }; + + explicit VertexStruct(unsigned int count) + : count_(count), + elements_(new Element[count]) { + memset(elements_.get(), 0, count * sizeof(Element)); // NOLINT + } + + // Returns the number of inputs in this struct. + unsigned int count() const { return count_; } + // Returns an element by index. + Element &GetElement(unsigned int i) { + DCHECK_GT(count_, i); + return elements_[i]; + } + protected: + unsigned int count_; + scoped_array elements_; + private: + DISALLOW_COPY_AND_ASSIGN(VertexStruct); +}; + +// Effect class, representing an effect. +class Effect: public Resource { + public: + Effect() {} + private: + DISALLOW_COPY_AND_ASSIGN(Effect); +}; + +// EffectParam class, representing an effect parameter. +class EffectParam: public Resource { + public: + explicit EffectParam(effect_param::DataType data_type) + : data_type_(data_type) { + } + + // Gets the data type of this parameter. + effect_param::DataType data_type() const { return data_type_; } + private: + effect_param::DataType data_type_; + DISALLOW_COPY_AND_ASSIGN(EffectParam); +}; + +// Texture class, representing a texture resource. +class Texture: public Resource { + public: + Texture(texture::Type type, + unsigned int levels, + texture::Format format, + bool enable_render_surfaces, + unsigned int flags) + : type_(type), + levels_(levels), + format_(format), + render_surfaces_enabled_(enable_render_surfaces), + flags_(flags) {} + virtual ~Texture() {} + + // Returns the type of the texture. + texture::Type type() const { return type_; } + // Returns the texture flags. + unsigned int flags() const { return flags_; } + // Returns the texture format. + texture::Format format() const { return format_; } + // Returns whether the texture supports render surfaces + bool render_surfaces_enabled() const { return render_surfaces_enabled_; } + // Returns the number of mipmap levels in the texture. + unsigned int levels() const { return levels_; } + private: + texture::Type type_; + unsigned int levels_; + texture::Format format_; + bool render_surfaces_enabled_; + unsigned int flags_; + DISALLOW_COPY_AND_ASSIGN(Texture); +}; + +// RenderSurface class, representing a render surface/target +class RenderSurface: public Resource { + public: + RenderSurface() {} + private: + DISALLOW_COPY_AND_ASSIGN(RenderSurface); +}; + +// RenderSurface class, representing a render surface/target +class RenderDepthStencilSurface: public Resource { + public: + RenderDepthStencilSurface() {} + private: + DISALLOW_COPY_AND_ASSIGN(RenderDepthStencilSurface); +}; + + +// Texture class, representing a sampler resource. +class Sampler: public Resource { + public: + Sampler() {} + private: + DISALLOW_COPY_AND_ASSIGN(Sampler); +}; + +// Base of ResourceMap. Contains most of the implementation of ResourceMap, to +// avoid template bloat. +class ResourceMapBase { + public: + ResourceMapBase() : resources_() {} + ~ResourceMapBase() {} + + // Assigns a resource to a resource ID. Assigning a resource to an ID that + // already has an existing resource will destroy that existing resource. The + // map takes ownership of the resource. + void Assign(ResourceId id, Resource* resource); + // Destroys a resource. + bool Destroy(ResourceId id); + // Destroy all resources. + void DestroyAllResources(); + // Gets a resource by ID. + Resource *Get(ResourceId id) { + return (id < resources_.size()) ? resources_[id] : NULL; + } + private: + typedef std::vector Container; + Container resources_; +}; + +// Resource Map class, allowing resource ID <-> Resource association. This is a +// dense map, optimized for retrieval (O(1)). +template class ResourceMap { + public: + ResourceMap() : container_() {} + ~ResourceMap() {} + + // Assigns a resource to a resource ID. Assigning a resource to an ID that + // already has an existing resource will destroy that existing resource. The + // map takes ownership of the resource. + void Assign(ResourceId id, T* resource) { + container_.Assign(id, resource); + } + // Destroys a resource. + bool Destroy(ResourceId id) { + return container_.Destroy(id); + } + // Destroy all resources. + void DestroyAllResources() { + return container_.DestroyAllResources(); + } + // Gets a resource by ID. + T *Get(ResourceId id) { + return static_cast(container_.Get(id)); + } + private: + ResourceMapBase container_; +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_RESOURCE_H_ diff --git a/o3d/command_buffer/service/resource_test.cc b/o3d/command_buffer/service/resource_test.cc new file mode 100644 index 0000000..ed6154a --- /dev/null +++ b/o3d/command_buffer/service/resource_test.cc @@ -0,0 +1,126 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// Tests for the ResourceMap. + +#include "tests/common/win/testing_common.h" +#include "command_buffer/service/resource.h" + +namespace command_buffer { + +// Mock resource implementation that checks for leaks. +class ResourceMock : public Resource { + public: + ResourceMock() : Resource() { + ++instance_count_; + } + virtual ~ResourceMock() { + --instance_count_; + } + + // Returns the instance count. The instance count is increased in the + // constructor and decreased in the destructor, to track leaks. The reason is + // that we can't mock the destructor, though we want to make sure the mock is + // destroyed. + static int instance_count() { return instance_count_; } + private: + static int instance_count_; + DISALLOW_COPY_AND_ASSIGN(ResourceMock); +}; +int ResourceMock::instance_count_ = 0; + +// Test fixture for ResourceMap test. Creates a ResourceMap using a mock +// Resource, and checks for ResourceMock leaks. +class ResourceMapTest : public testing::Test { + protected: + typedef ResourceMap Map; + virtual void SetUp() { + instance_count_ = ResourceMock::instance_count(); + map_.reset(new Map()); + } + virtual void TearDown() { + CheckLeaks(); + } + + // Makes sure we didn't leak any ResourceMock object. + void CheckLeaks() { + EXPECT_EQ(instance_count_, ResourceMock::instance_count()); + } + + Map *map() const { return map_.get(); } + private: + int instance_count_; + scoped_ptr map_; +}; + +TEST_F(ResourceMapTest, TestMap) { + // check that initial mapping is empty. + EXPECT_EQ(NULL, map()->Get(0)); + EXPECT_EQ(NULL, map()->Get(1)); + EXPECT_EQ(NULL, map()->Get(392)); + + // create a new resource, assign it to an ID. + ResourceMock *resource = new ResourceMock(); + map()->Assign(123, resource); + EXPECT_EQ(resource, map()->Get(123)); + + // Destroy the resource, making sure the object is deleted. + EXPECT_EQ(true, map()->Destroy(123)); + EXPECT_EQ(false, map()->Destroy(123)); // destroying again should fail. + resource = NULL; + CheckLeaks(); + + // create a new resource, add it to the map, and make sure it gets deleted + // when we assign a new resource to that ID. + resource = new ResourceMock(); + map()->Assign(1, resource); + resource = new ResourceMock(); + map()->Assign(1, resource); + EXPECT_EQ(resource, map()->Get(1)); // check that we have the new resource. + EXPECT_EQ(true, map()->Destroy(1)); + CheckLeaks(); + + // Adds 3 resources, then call DestroyAllResources(). + resource = new ResourceMock(); + map()->Assign(1, resource); + resource = new ResourceMock(); + map()->Assign(2, resource); + resource = new ResourceMock(); + map()->Assign(3, resource); + map()->DestroyAllResources(); + EXPECT_EQ(NULL, map()->Get(1)); + EXPECT_EQ(NULL, map()->Get(2)); + EXPECT_EQ(NULL, map()->Get(3)); + CheckLeaks(); +} + +} // namespace command_buffer diff --git a/o3d/command_buffer/service/sampler_d3d9.cc b/o3d/command_buffer/service/sampler_d3d9.cc new file mode 100644 index 0000000..1436d26 --- /dev/null +++ b/o3d/command_buffer/service/sampler_d3d9.cc @@ -0,0 +1,198 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the implementation of the SamplerD3D9 class. + +#include "command_buffer/service/gapi_d3d9.h" +#include "command_buffer/service/sampler_d3d9.h" +#include "command_buffer/service/texture_d3d9.h" + +namespace command_buffer { +namespace o3d { + +namespace { + +// Converts an addressing mode to corresponding D3D values. +D3DTEXTUREADDRESS AddressModeToD3D(sampler::AddressingMode mode) { + switch (mode) { + case sampler::kWrap: + return D3DTADDRESS_WRAP; + case sampler::kMirrorRepeat: + return D3DTADDRESS_MIRROR; + case sampler::kClampToEdge: + return D3DTADDRESS_CLAMP; + case sampler::kClampToBorder: + return D3DTADDRESS_BORDER; + } + DLOG(FATAL) << "Not reached"; + return D3DTADDRESS_WRAP; +} + +// Converts a filtering mode to corresponding D3D values. +D3DTEXTUREFILTERTYPE FilteringModeToD3D(sampler::FilteringMode mode) { + switch (mode) { + case sampler::kNone: + return D3DTEXF_NONE; + case sampler::kPoint: + return D3DTEXF_POINT; + case sampler::kLinear: + return D3DTEXF_LINEAR; + } + DLOG(FATAL) << "Not reached"; + return D3DTEXF_POINT; +} + +} // anonymous namespace + +SamplerD3D9::SamplerD3D9() + : texture_id_(kInvalidResource) { + SetStates(sampler::kClampToEdge, + sampler::kClampToEdge, + sampler::kClampToEdge, + sampler::kLinear, + sampler::kLinear, + sampler::kPoint, + 1); + RGBA black = {0, 0, 0, 1}; + SetBorderColor(black); +} + +bool SamplerD3D9::ApplyStates(GAPID3D9 *gapi, unsigned int unit) const { + DCHECK(gapi); + TextureD3D9 *texture = gapi->GetTexture(texture_id_); + if (!texture) { + return false; + } + IDirect3DDevice9 *d3d_device = gapi->d3d_device(); + HR(d3d_device->SetTexture(unit, texture->d3d_base_texture())); + HR(d3d_device->SetSamplerState(unit, D3DSAMP_ADDRESSU, d3d_address_u_)); + HR(d3d_device->SetSamplerState(unit, D3DSAMP_ADDRESSV, d3d_address_v_)); + HR(d3d_device->SetSamplerState(unit, D3DSAMP_ADDRESSW, d3d_address_w_)); + HR(d3d_device->SetSamplerState(unit, D3DSAMP_MAGFILTER, d3d_mag_filter_)); + HR(d3d_device->SetSamplerState(unit, D3DSAMP_MINFILTER, d3d_min_filter_)); + HR(d3d_device->SetSamplerState(unit, D3DSAMP_MIPFILTER, d3d_mip_filter_)); + HR(d3d_device->SetSamplerState(unit, D3DSAMP_MAXANISOTROPY, + d3d_max_anisotropy_)); + HR(d3d_device->SetSamplerState(unit, D3DSAMP_BORDERCOLOR, d3d_border_color_)); + return true; +} + +void SamplerD3D9::SetStates(sampler::AddressingMode addressing_u, + sampler::AddressingMode addressing_v, + sampler::AddressingMode addressing_w, + sampler::FilteringMode mag_filter, + sampler::FilteringMode min_filter, + sampler::FilteringMode mip_filter, + unsigned int max_anisotropy) { + // These are validated in GAPIDecoder.cc + DCHECK_NE(mag_filter, sampler::kNone); + DCHECK_NE(min_filter, sampler::kNone); + DCHECK_GT(max_anisotropy, 0U); + d3d_address_u_ = AddressModeToD3D(addressing_u); + d3d_address_v_ = AddressModeToD3D(addressing_v); + d3d_address_w_ = AddressModeToD3D(addressing_w); + d3d_mag_filter_ = FilteringModeToD3D(mag_filter); + d3d_min_filter_ = FilteringModeToD3D(min_filter); + d3d_mip_filter_ = FilteringModeToD3D(mip_filter); + if (max_anisotropy > 1) { + d3d_mag_filter_ = D3DTEXF_ANISOTROPIC; + d3d_min_filter_ = D3DTEXF_ANISOTROPIC; + } + d3d_max_anisotropy_ = max_anisotropy; +} + +void SamplerD3D9::SetBorderColor(const RGBA &color) { + d3d_border_color_ = RGBAToD3DCOLOR(color); +} + +parse_error::ParseError GAPID3D9::CreateSampler( + ResourceId id) { + // Dirty effect, because this sampler id may be used + DirtyEffect(); + samplers_.Assign(id, new SamplerD3D9()); + return parse_error::kParseNoError; +} + +// Destroys the Sampler resource. +parse_error::ParseError GAPID3D9::DestroySampler(ResourceId id) { + // Dirty effect, because this sampler id may be used + DirtyEffect(); + return samplers_.Destroy(id) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +parse_error::ParseError GAPID3D9::SetSamplerStates( + ResourceId id, + sampler::AddressingMode addressing_u, + sampler::AddressingMode addressing_v, + sampler::AddressingMode addressing_w, + sampler::FilteringMode mag_filter, + sampler::FilteringMode min_filter, + sampler::FilteringMode mip_filter, + unsigned int max_anisotropy) { + SamplerD3D9 *sampler = samplers_.Get(id); + if (!sampler) + return parse_error::kParseInvalidArguments; + // Dirty effect, because this sampler id may be used + DirtyEffect(); + sampler->SetStates(addressing_u, addressing_v, addressing_w, + mag_filter, min_filter, mip_filter, max_anisotropy); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPID3D9::SetSamplerBorderColor( + ResourceId id, + const RGBA &color) { + SamplerD3D9 *sampler = samplers_.Get(id); + if (!sampler) + return parse_error::kParseInvalidArguments; + // Dirty effect, because this sampler id may be used + DirtyEffect(); + sampler->SetBorderColor(color); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPID3D9::SetSamplerTexture( + ResourceId id, + ResourceId texture_id) { + SamplerD3D9 *sampler = samplers_.Get(id); + if (!sampler) + return parse_error::kParseInvalidArguments; + // Dirty effect, because this sampler id may be used + DirtyEffect(); + sampler->SetTexture(texture_id); + return parse_error::kParseNoError; +} + +} // namespace o3d +} // namespace command_buffer diff --git a/o3d/command_buffer/service/sampler_d3d9.h b/o3d/command_buffer/service/sampler_d3d9.h new file mode 100644 index 0000000..2f1c31b --- /dev/null +++ b/o3d/command_buffer/service/sampler_d3d9.h @@ -0,0 +1,85 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the definition of the SamplerD3D9 class, implementing +// samplers for D3D. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_WIN_D3D9_SAMPLER_D3D9_H_ +#define GPU_COMMAND_BUFFER_SERVICE_WIN_D3D9_SAMPLER_D3D9_H_ + +#include "command_buffer/common/gapi_interface.h" +#include "command_buffer/service/d3d9_utils.h" +#include "command_buffer/service/resource.h" + +namespace command_buffer { +namespace o3d { + +class GAPID3D9; + +// D3D9 version of Sampler. +class SamplerD3D9 : public Sampler { + public: + SamplerD3D9(); + + // Applies sampler states to D3D. + bool ApplyStates(GAPID3D9 *gapi, unsigned int unit) const; + + // Sets sampler states. + void SetStates(sampler::AddressingMode addressing_u, + sampler::AddressingMode addressing_v, + sampler::AddressingMode addressing_w, + sampler::FilteringMode mag_filter, + sampler::FilteringMode min_filter, + sampler::FilteringMode mip_filter, + unsigned int max_anisotropy); + + // Sets the border color states. + void SetBorderColor(const RGBA &color); + + // Sets the texture. + void SetTexture(ResourceId texture) { texture_id_ = texture; } + private: + D3DTEXTUREADDRESS d3d_address_u_; + D3DTEXTUREADDRESS d3d_address_v_; + D3DTEXTUREADDRESS d3d_address_w_; + D3DTEXTUREFILTERTYPE d3d_mag_filter_; + D3DTEXTUREFILTERTYPE d3d_min_filter_; + D3DTEXTUREFILTERTYPE d3d_mip_filter_; + DWORD d3d_max_anisotropy_; + D3DCOLOR d3d_border_color_; + ResourceId texture_id_; +}; + +} // namespace o3d +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_WIN_D3D9_SAMPLER_D3D9_H_ diff --git a/o3d/command_buffer/service/sampler_gl.cc b/o3d/command_buffer/service/sampler_gl.cc new file mode 100644 index 0000000..2c6622e --- /dev/null +++ b/o3d/command_buffer/service/sampler_gl.cc @@ -0,0 +1,237 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file implements the sampler-related GAPI functions on GL. + +#include "command_buffer/service/gapi_gl.h" +#include "command_buffer/service/sampler_gl.h" + +namespace command_buffer { +namespace o3d { + +namespace { + +// Gets the GL enum corresponding to an addressing mode. +GLenum GLAddressMode(sampler::AddressingMode o3d_mode) { + switch (o3d_mode) { + case sampler::kWrap: + return GL_REPEAT; + case sampler::kMirrorRepeat: + return GL_MIRRORED_REPEAT; + case sampler::kClampToEdge: + return GL_CLAMP_TO_EDGE; + case sampler::kClampToBorder: + return GL_CLAMP_TO_BORDER; + default: + DLOG(FATAL) << "Not Reached"; + return GL_REPEAT; + } +} + +// Gets the GL enum for the minification filter based on the command buffer min +// and mip filtering modes. +GLenum GLMinFilter(sampler::FilteringMode min_filter, + sampler::FilteringMode mip_filter) { + switch (min_filter) { + case sampler::kPoint: + if (mip_filter == sampler::kNone) + return GL_NEAREST; + else if (mip_filter == sampler::kPoint) + return GL_NEAREST_MIPMAP_NEAREST; + else if (mip_filter == sampler::kLinear) + return GL_NEAREST_MIPMAP_LINEAR; + case sampler::kLinear: + if (mip_filter == sampler::kNone) + return GL_LINEAR; + else if (mip_filter == sampler::kPoint) + return GL_LINEAR_MIPMAP_NEAREST; + else if (mip_filter == sampler::kLinear) + return GL_LINEAR_MIPMAP_LINEAR; + default: + DLOG(FATAL) << "Not Reached"; + return GL_LINEAR_MIPMAP_NEAREST; + } +} + +// Gets the GL enum for the magnification filter based on the command buffer mag +// filtering mode. +GLenum GLMagFilter(sampler::FilteringMode mag_filter) { + switch (mag_filter) { + case sampler::kPoint: + return GL_NEAREST; + case sampler::kLinear: + return GL_LINEAR; + default: + DLOG(FATAL) << "Not Reached"; + return GL_LINEAR; + } +} + +// Gets the GL enum representing the GL target based on the texture type. +GLenum GLTextureTarget(texture::Type type) { + switch (type) { + case texture::kTexture2d: + return GL_TEXTURE_2D; + case texture::kTexture3d: + return GL_TEXTURE_3D; + case texture::kTextureCube: + return GL_TEXTURE_CUBE_MAP; + default: + DLOG(FATAL) << "Not Reached"; + return GL_TEXTURE_2D; + } +} + +} // anonymous namespace + +SamplerGL::SamplerGL() + : texture_id_(kInvalidResource), + gl_texture_(0) { + SetStates(sampler::kClampToEdge, + sampler::kClampToEdge, + sampler::kClampToEdge, + sampler::kLinear, + sampler::kLinear, + sampler::kPoint, + 1); + RGBA black = {0, 0, 0, 1}; + SetBorderColor(black); +} + +bool SamplerGL::ApplyStates(GAPIGL *gapi) { + DCHECK(gapi); + TextureGL *texture = gapi->GetTexture(texture_id_); + if (!texture) { + gl_texture_ = 0; + return false; + } + GLenum target = GLTextureTarget(texture->type()); + gl_texture_ = texture->gl_texture(); + glBindTexture(target, gl_texture_); + glTexParameteri(target, GL_TEXTURE_WRAP_S, gl_wrap_s_); + glTexParameteri(target, GL_TEXTURE_WRAP_T, gl_wrap_t_); + glTexParameteri(target, GL_TEXTURE_WRAP_R, gl_wrap_r_); + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, gl_min_filter_); + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, gl_mag_filter_); + glTexParameteri(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_max_anisotropy_); + glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, gl_border_color_); + return true; +} + +void SamplerGL::SetStates(sampler::AddressingMode addressing_u, + sampler::AddressingMode addressing_v, + sampler::AddressingMode addressing_w, + sampler::FilteringMode mag_filter, + sampler::FilteringMode min_filter, + sampler::FilteringMode mip_filter, + unsigned int max_anisotropy) { + // These are validated in GAPIDecoder.cc + DCHECK_NE(mag_filter, sampler::kNone); + DCHECK_NE(min_filter, sampler::kNone); + DCHECK_GT(max_anisotropy, 0U); + gl_wrap_s_ = GLAddressMode(addressing_u); + gl_wrap_t_ = GLAddressMode(addressing_v); + gl_wrap_r_ = GLAddressMode(addressing_w); + gl_mag_filter_ = GLMagFilter(mag_filter); + gl_min_filter_ = GLMinFilter(min_filter, mip_filter); + gl_max_anisotropy_ = max_anisotropy; +} + +void SamplerGL::SetBorderColor(const RGBA &color) { + gl_border_color_[0] = color.red; + gl_border_color_[1] = color.green; + gl_border_color_[2] = color.blue; + gl_border_color_[3] = color.alpha; +} + +parse_error::ParseError GAPIGL::CreateSampler( + ResourceId id) { + // Dirty effect, because this sampler id may be used. + DirtyEffect(); + samplers_.Assign(id, new SamplerGL()); + return parse_error::kParseNoError; +} + +// Destroys the Sampler resource. +parse_error::ParseError GAPIGL::DestroySampler(ResourceId id) { + // Dirty effect, because this sampler id may be used. + DirtyEffect(); + return samplers_.Destroy(id) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +parse_error::ParseError GAPIGL::SetSamplerStates( + ResourceId id, + sampler::AddressingMode addressing_u, + sampler::AddressingMode addressing_v, + sampler::AddressingMode addressing_w, + sampler::FilteringMode mag_filter, + sampler::FilteringMode min_filter, + sampler::FilteringMode mip_filter, + unsigned int max_anisotropy) { + SamplerGL *sampler = samplers_.Get(id); + if (!sampler) + return parse_error::kParseInvalidArguments; + // Dirty effect, because this sampler id may be used. + DirtyEffect(); + sampler->SetStates(addressing_u, addressing_v, addressing_w, + mag_filter, min_filter, mip_filter, max_anisotropy); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIGL::SetSamplerBorderColor( + ResourceId id, + const RGBA &color) { + SamplerGL *sampler = samplers_.Get(id); + if (!sampler) + return parse_error::kParseInvalidArguments; + // Dirty effect, because this sampler id may be used. + DirtyEffect(); + sampler->SetBorderColor(color); + return parse_error::kParseNoError; +} + +parse_error::ParseError GAPIGL::SetSamplerTexture( + ResourceId id, + ResourceId texture_id) { + SamplerGL *sampler = samplers_.Get(id); + if (!sampler) + return parse_error::kParseInvalidArguments; + // Dirty effect, because this sampler id may be used. + DirtyEffect(); + sampler->SetTexture(texture_id); + return parse_error::kParseNoError; +} + +} // namespace o3d +} // namespace command_buffer diff --git a/o3d/command_buffer/service/sampler_gl.h b/o3d/command_buffer/service/sampler_gl.h new file mode 100644 index 0000000..eae8f2c --- /dev/null +++ b/o3d/command_buffer/service/sampler_gl.h @@ -0,0 +1,87 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file declares the SamplerGL class. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_GL_SAMPLER_GL_H_ +#define GPU_COMMAND_BUFFER_SERVICE_CROSS_GL_SAMPLER_GL_H_ + +#include "command_buffer/common/gapi_interface.h" +#include "command_buffer/service/gl_utils.h" +#include "command_buffer/service/resource.h" + +namespace command_buffer { +namespace o3d { + +class GAPIGL; + +// GL version of Sampler. +class SamplerGL : public Sampler { + public: + SamplerGL(); + + // Applies sampler states to GL. + bool ApplyStates(GAPIGL *gapi); + + // Sets sampler states. + void SetStates(sampler::AddressingMode addressing_u, + sampler::AddressingMode addressing_v, + sampler::AddressingMode addressing_w, + sampler::FilteringMode mag_filter, + sampler::FilteringMode min_filter, + sampler::FilteringMode mip_filter, + unsigned int max_anisotropy); + + // Sets the border color states. + void SetBorderColor(const o3d::RGBA &color); + + // Sets the texture. + void SetTexture(ResourceId texture) { texture_id_ = texture; } + + GLuint gl_texture() const { return gl_texture_; } + + private: + GLenum gl_wrap_s_; + GLenum gl_wrap_t_; + GLenum gl_wrap_r_; + GLenum gl_mag_filter_; + GLenum gl_min_filter_; + GLuint gl_max_anisotropy_; + GLfloat gl_border_color_[4]; + GLuint gl_texture_; + ResourceId texture_id_; +}; + +} // namespace o3d +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_GL_SAMPLER_GL_H_ diff --git a/o3d/command_buffer/service/states_d3d9.cc b/o3d/command_buffer/service/states_d3d9.cc new file mode 100644 index 0000000..8252e28 --- /dev/null +++ b/o3d/command_buffer/service/states_d3d9.cc @@ -0,0 +1,352 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the implementation of the state-related GAPID3D9 +// functions. + +#include +#include "command_buffer/common/o3d_cmd_format.h" +#include "command_buffer/service/gapi_d3d9.h" + +namespace command_buffer { +namespace o3d { + +namespace { + +// Checks that a command_buffer enum matches a D3D enum so that it can be +// converted quickly. +#define CHECK_CB_ENUM_MATCHES_D3D(CB_ENUM, D3D_ENUM) \ + COMPILE_ASSERT(CB_ENUM + 1 == D3D_ENUM, \ + CB_ENUM ## _plus_1_not_ ## D3D_ENUM) + +// Converts values from the PolygonMode enum to corresponding D3D values +inline D3DFILLMODE PolygonModeToD3D(PolygonMode fill_mode) { + DCHECK_LT(fill_mode, kNumPolygonMode); + + // Check that all acceptable values translate to D3D values by adding 1. + + CHECK_CB_ENUM_MATCHES_D3D(kPolygonModePoints, D3DFILL_POINT); + CHECK_CB_ENUM_MATCHES_D3D(kPolygonModeLines, D3DFILL_WIREFRAME); + CHECK_CB_ENUM_MATCHES_D3D(kPolygonModeFill, D3DFILL_SOLID); + return static_cast(fill_mode + 1); +} + +// Converts values from the FaceCullMode enum to corresponding D3D values +inline D3DCULL FaceCullModeToD3D(FaceCullMode cull_mode) { + DCHECK_LT(cull_mode, kNumFaceCullMode); + + // Check that all acceptable values translate to D3D values by adding 1. + CHECK_CB_ENUM_MATCHES_D3D(kCullNone, D3DCULL_NONE); + CHECK_CB_ENUM_MATCHES_D3D(kCullCW, D3DCULL_CW); + CHECK_CB_ENUM_MATCHES_D3D(kCullCCW, D3DCULL_CCW); + return static_cast(cull_mode + 1); +} + +// Converts values from the Comparison enum to corresponding D3D values +inline D3DCMPFUNC ComparisonToD3D(Comparison comp) { + DCHECK_LT(comp, kNumComparison); + + // Check that all acceptable values translate to D3D values by adding 1. + CHECK_CB_ENUM_MATCHES_D3D(kNever, D3DCMP_NEVER); + CHECK_CB_ENUM_MATCHES_D3D(kLess, D3DCMP_LESS); + CHECK_CB_ENUM_MATCHES_D3D(kEqual, D3DCMP_EQUAL); + CHECK_CB_ENUM_MATCHES_D3D(kLEqual, D3DCMP_LESSEQUAL); + CHECK_CB_ENUM_MATCHES_D3D(kGreater, D3DCMP_GREATER); + CHECK_CB_ENUM_MATCHES_D3D(kNotEqual, D3DCMP_NOTEQUAL); + CHECK_CB_ENUM_MATCHES_D3D(kGEqual, D3DCMP_GREATEREQUAL); + CHECK_CB_ENUM_MATCHES_D3D(kAlways, D3DCMP_ALWAYS); + return static_cast(comp + 1); +} + +// Converts values from the StencilOp enum to corresponding D3D values +inline D3DSTENCILOP StencilOpToD3D(StencilOp stencil_op) { + DCHECK_LT(stencil_op, kNumStencilOp); + + // Check that all acceptable values translate to D3D values by adding 1. + CHECK_CB_ENUM_MATCHES_D3D(kKeep, D3DSTENCILOP_KEEP); + CHECK_CB_ENUM_MATCHES_D3D(kZero, D3DSTENCILOP_ZERO); + CHECK_CB_ENUM_MATCHES_D3D(kReplace, D3DSTENCILOP_REPLACE); + CHECK_CB_ENUM_MATCHES_D3D(kIncNoWrap, D3DSTENCILOP_INCRSAT); + CHECK_CB_ENUM_MATCHES_D3D(kDecNoWrap, D3DSTENCILOP_DECRSAT); + CHECK_CB_ENUM_MATCHES_D3D(kInvert, D3DSTENCILOP_INVERT); + CHECK_CB_ENUM_MATCHES_D3D(kIncWrap, D3DSTENCILOP_INCR); + CHECK_CB_ENUM_MATCHES_D3D(kDecWrap, D3DSTENCILOP_DECR); + return static_cast(stencil_op + 1); +} + +// Converts values from the BlendEq enum to corresponding D3D values +inline D3DBLENDOP BlendEqToD3D(BlendEq blend_eq) { + DCHECK_LT(blend_eq, kNumBlendEq); + // Check that all acceptable values translate to D3D values by adding 1. + CHECK_CB_ENUM_MATCHES_D3D(kBlendEqAdd, D3DBLENDOP_ADD); + CHECK_CB_ENUM_MATCHES_D3D(kBlendEqSub, D3DBLENDOP_SUBTRACT); + CHECK_CB_ENUM_MATCHES_D3D(kBlendEqRevSub, D3DBLENDOP_REVSUBTRACT); + CHECK_CB_ENUM_MATCHES_D3D(kBlendEqMin, D3DBLENDOP_MIN); + CHECK_CB_ENUM_MATCHES_D3D(kBlendEqMax, D3DBLENDOP_MAX); + return static_cast(blend_eq + 1); +} + +// Converts values from the BlendFunc enum to corresponding D3D values +D3DBLEND BlendFuncToD3D(BlendFunc blend_func) { + // The D3DBLEND enum values don't map 1-to-1 to BlendFunc, so we use a switch + // here. + switch (blend_func) { + case kBlendFuncZero: + return D3DBLEND_ZERO; + case kBlendFuncOne: + return D3DBLEND_ONE; + case kBlendFuncSrcColor: + return D3DBLEND_SRCCOLOR; + case kBlendFuncInvSrcColor: + return D3DBLEND_INVSRCCOLOR; + case kBlendFuncSrcAlpha: + return D3DBLEND_SRCALPHA; + case kBlendFuncInvSrcAlpha: + return D3DBLEND_INVSRCALPHA; + case kBlendFuncDstAlpha: + return D3DBLEND_DESTALPHA; + case kBlendFuncInvDstAlpha: + return D3DBLEND_INVDESTALPHA; + case kBlendFuncDstColor: + return D3DBLEND_DESTCOLOR; + case kBlendFuncInvDstColor: + return D3DBLEND_INVDESTCOLOR; + case kBlendFuncSrcAlphaSaturate: + return D3DBLEND_SRCALPHASAT; + case kBlendFuncBlendColor: + return D3DBLEND_BLENDFACTOR; + case kBlendFuncInvBlendColor: + return D3DBLEND_INVBLENDFACTOR; + default: + DLOG(FATAL) << "Invalid BlendFunc"; + return D3DBLEND_ZERO; + } +} + +// Decodes stencil test function and operations from the bitfield. +void DecodeStencilFuncOps(Uint32 params, + Comparison *func, + StencilOp *pass, + StencilOp *fail, + StencilOp *zfail) { + // Sanity check. The value has already been tested in + // GAPIDecoder::DecodeSetStencilTest in gapi_decoder.cc. + DCHECK_EQ(SetStencilTest::Unused1::Get(params), 0); + // Check that the bitmask get cannot generate values outside of the allowed + // range. + COMPILE_ASSERT(SetStencilTest::CWFunc::kMask < + kNumComparison, + set_stencil_test_CWFunc_may_produce_invalid_values); + *func = static_cast(SetStencilTest::CWFunc::Get(params)); + + COMPILE_ASSERT(SetStencilTest::CWPassOp::kMask < + kNumStencilOp, + set_stencil_test_CWPassOp_may_produce_invalid_values); + *pass = static_cast(SetStencilTest::CWPassOp::Get(params)); + + COMPILE_ASSERT(SetStencilTest::CWFailOp::kMask < + kNumStencilOp, + set_stencil_test_CWFailOp_may_produce_invalid_values); + *fail = static_cast(SetStencilTest::CWFailOp::Get(params)); + + COMPILE_ASSERT(SetStencilTest::CWZFailOp::kMask < + kNumStencilOp, + set_stencil_test_CWZFailOp_may_produce_invalid_values); + *zfail = static_cast(SetStencilTest::CWZFailOp::Get(params)); +} + +} // anonymous namespace + +void GAPID3D9::SetScissor(bool enable, + unsigned int x, + unsigned int y, + unsigned int width, + unsigned int height) { + HR(d3d_device_->SetRenderState(D3DRS_SCISSORTESTENABLE, + enable ? TRUE : FALSE)); + RECT rect = {x, y, x + width, y + height}; + HR(d3d_device_->SetScissorRect(&rect)); +} + +void GAPID3D9::SetPolygonOffset(float slope_factor, float units) { + HR(d3d_device_->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, + FloatAsDWORD(slope_factor))); + // TODO: this value is hard-coded currently because we only create a + // 24-bit depth buffer. Move this to a member of GAPID3D9 if this changes. + const float kUnitScale = 1.f / (1 << 24); + HR(d3d_device_->SetRenderState(D3DRS_DEPTHBIAS, + FloatAsDWORD(units * kUnitScale))); +} + +void GAPID3D9::SetPointLineRaster(bool line_smooth, + bool point_sprite, + float point_size) { + HR(d3d_device_->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, + line_smooth ? TRUE : FALSE)); + HR(d3d_device_->SetRenderState(D3DRS_POINTSPRITEENABLE, + point_sprite ? TRUE : FALSE)); + HR(d3d_device_->SetRenderState(D3DRS_POINTSIZE, + FloatAsDWORD(point_size))); +} + +void GAPID3D9::SetPolygonRaster(PolygonMode fill_mode, + FaceCullMode cull_mode) { + HR(d3d_device_->SetRenderState(D3DRS_FILLMODE, PolygonModeToD3D(fill_mode))); + HR(d3d_device_->SetRenderState(D3DRS_CULLMODE, FaceCullModeToD3D(cull_mode))); +} + +void GAPID3D9::SetAlphaTest(bool enable, + float reference, + Comparison comp) { + HR(d3d_device_->SetRenderState(D3DRS_ALPHABLENDENABLE, + enable ? TRUE : FALSE)); + HR(d3d_device_->SetRenderState(D3DRS_ALPHAREF, + FloatToClampedByte(reference))); + HR(d3d_device_->SetRenderState(D3DRS_ALPHAFUNC, ComparisonToD3D(comp))); +} + +void GAPID3D9::SetDepthTest(bool enable, + bool write_enable, + Comparison comp) { + HR(d3d_device_->SetRenderState(D3DRS_ZENABLE, + enable ? TRUE : FALSE)); + HR(d3d_device_->SetRenderState(D3DRS_ZWRITEENABLE, + write_enable ? TRUE : FALSE)); + HR(d3d_device_->SetRenderState(D3DRS_ZFUNC, ComparisonToD3D(comp))); +} + +void GAPID3D9::SetStencilTest(bool enable, + bool separate_ccw, + unsigned int write_mask, + unsigned int compare_mask, + unsigned int ref, + Uint32 func_ops) { + HR(d3d_device_->SetRenderState(D3DRS_STENCILENABLE, + enable ? TRUE : FALSE)); + HR(d3d_device_->SetRenderState(D3DRS_STENCILWRITEMASK, write_mask)); + HR(d3d_device_->SetRenderState(D3DRS_STENCILMASK, compare_mask)); + HR(d3d_device_->SetRenderState(D3DRS_STENCILREF, ref)); + + Comparison func; + StencilOp pass; + StencilOp fail; + StencilOp zfail; + DecodeStencilFuncOps(func_ops, &func, &pass, &fail, &zfail); + HR(d3d_device_->SetRenderState(D3DRS_STENCILFUNC, + ComparisonToD3D(func))); + HR(d3d_device_->SetRenderState(D3DRS_STENCILPASS, + StencilOpToD3D(pass))); + HR(d3d_device_->SetRenderState(D3DRS_STENCILFAIL, + StencilOpToD3D(fail))); + HR(d3d_device_->SetRenderState(D3DRS_STENCILZFAIL, + StencilOpToD3D(zfail))); + + if (separate_ccw) { + HR(d3d_device_->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE)); + // Check that the definition of the counter-clockwise func/ops match the + // clockwise ones, just shifted by 16 bits, so that we can use + // DecodeStencilFuncOps on both of them. +#define CHECK_CCW_MATCHES_CW(FIELD) \ + COMPILE_ASSERT(SetStencilTest::CW ## FIELD::kLength == \ + SetStencilTest::CCW ## FIELD::kLength, \ + CCW ## FIELD ## _length_does_not_match_ ## CW ## FIELD); \ + COMPILE_ASSERT(SetStencilTest::CW ## FIELD::kShift + 16 == \ + SetStencilTest::CCW ## FIELD::kShift, \ + CCW ## FIELD ## _shift_does_not_match_ ## CW ## FIELD) + CHECK_CCW_MATCHES_CW(Func); + CHECK_CCW_MATCHES_CW(PassOp); + CHECK_CCW_MATCHES_CW(FailOp); + CHECK_CCW_MATCHES_CW(ZFailOp); +#undef CHECK_CCW_MATCHES_CW + // Extract upper 16 bits. + Uint32 ccw_func_ops = BitField<16, 16>::Get(func_ops); + + DecodeStencilFuncOps(ccw_func_ops, &func, &pass, &fail, &zfail); + HR(d3d_device_->SetRenderState(D3DRS_CCW_STENCILFUNC, + ComparisonToD3D(func))); + HR(d3d_device_->SetRenderState(D3DRS_CCW_STENCILPASS, + StencilOpToD3D(pass))); + HR(d3d_device_->SetRenderState(D3DRS_CCW_STENCILFAIL, + StencilOpToD3D(fail))); + HR(d3d_device_->SetRenderState(D3DRS_CCW_STENCILZFAIL, + StencilOpToD3D(zfail))); + } else { + HR(d3d_device_->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE)); + } +} + +void GAPID3D9::SetColorWrite(bool red, + bool green, + bool blue, + bool alpha, + bool dither) { + Uint32 mask = red ? D3DCOLORWRITEENABLE_RED : 0; + mask |= green ? D3DCOLORWRITEENABLE_GREEN : 0; + mask |= blue ? D3DCOLORWRITEENABLE_BLUE : 0; + mask |= alpha ? D3DCOLORWRITEENABLE_ALPHA : 0; + HR(d3d_device_->SetRenderState(D3DRS_COLORWRITEENABLE, mask)); + HR(d3d_device_->SetRenderState(D3DRS_DITHERENABLE, dither ? TRUE : FALSE)); +} + +void GAPID3D9::SetBlending(bool enable, + bool separate_alpha, + BlendEq color_eq, + BlendFunc color_src_func, + BlendFunc color_dst_func, + BlendEq alpha_eq, + BlendFunc alpha_src_func, + BlendFunc alpha_dst_func) { + HR(d3d_device_->SetRenderState(D3DRS_ALPHABLENDENABLE, + enable ? TRUE : FALSE)); + HR(d3d_device_->SetRenderState(D3DRS_BLENDOP, BlendEqToD3D(color_eq))); + HR(d3d_device_->SetRenderState(D3DRS_SRCBLEND, + BlendFuncToD3D(color_src_func))); + HR(d3d_device_->SetRenderState(D3DRS_DESTBLEND, + BlendFuncToD3D(color_dst_func))); + if (separate_alpha) { + HR(d3d_device_->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE)); + HR(d3d_device_->SetRenderState(D3DRS_BLENDOP, BlendEqToD3D(alpha_eq))); + HR(d3d_device_->SetRenderState(D3DRS_SRCBLEND, + BlendFuncToD3D(alpha_src_func))); + HR(d3d_device_->SetRenderState(D3DRS_DESTBLEND, + BlendFuncToD3D(alpha_dst_func))); + } else { + HR(d3d_device_->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE)); + } +} + +void GAPID3D9::SetBlendingColor(const RGBA &color) { + HR(d3d_device_->SetRenderState(D3DRS_BLENDFACTOR, RGBAToD3DCOLOR(color))); +} + +} // namespace o3d +} // namespace command_buffer diff --git a/o3d/command_buffer/service/states_gl.cc b/o3d/command_buffer/service/states_gl.cc new file mode 100644 index 0000000..49859ec --- /dev/null +++ b/o3d/command_buffer/service/states_gl.cc @@ -0,0 +1,345 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file implements the render state-related GAPI functions on GL. + +#include "command_buffer/common/o3d_cmd_format.h" +#include "command_buffer/service/gapi_gl.h" + +namespace command_buffer { +namespace o3d { + +namespace { + +GLenum kGLPolygonModes[] = { + GL_POINT, + GL_LINE, + GL_FILL, +}; +COMPILE_ASSERT(o3d::kNumPolygonMode == arraysize(kGLPolygonModes), + kGLPolygonModes_does_not_match_command_buffer_PolygonMode); + +GLenum kGLComparison[] = { + GL_NEVER, + GL_LESS, + GL_EQUAL, + GL_LEQUAL, + GL_GREATER, + GL_NOTEQUAL, + GL_GEQUAL, + GL_ALWAYS, +}; +COMPILE_ASSERT(o3d::kNumComparison == arraysize(kGLComparison), + kGLComparison_does_not_match_command_buffer_Comparison); + +GLenum kGLBlendFunc[] = { + GL_ZERO, + GL_ONE, + GL_SRC_COLOR, + GL_ONE_MINUS_SRC_COLOR, + GL_SRC_ALPHA, + GL_ONE_MINUS_SRC_ALPHA, + GL_DST_ALPHA, + GL_ONE_MINUS_DST_ALPHA, + GL_DST_COLOR, + GL_ONE_MINUS_DST_COLOR, + GL_SRC_ALPHA_SATURATE, + GL_CONSTANT_COLOR, + GL_ONE_MINUS_CONSTANT_COLOR, +}; +COMPILE_ASSERT(o3d::kNumBlendFunc == arraysize(kGLBlendFunc), + kGLBlendFunc_does_not_match_command_buffer_BlendFunc); + +GLenum kGLBlendEq[] = { + GL_FUNC_ADD, + GL_FUNC_SUBTRACT, + GL_FUNC_REVERSE_SUBTRACT, + GL_MIN, + GL_MAX, +}; +COMPILE_ASSERT(o3d::kNumBlendEq == arraysize(kGLBlendEq), + kGLBlendEq_does_not_match_command_buffer_BlendEq); + +GLenum kGLStencilOp[] = { + GL_KEEP, + GL_ZERO, + GL_REPLACE, + GL_INCR, + GL_DECR, + GL_INVERT, + GL_INCR_WRAP, + GL_DECR_WRAP, +}; +COMPILE_ASSERT(o3d::kNumStencilOp == arraysize(kGLStencilOp), + kGLStencilOp_does_not_match_command_buffer_StencilOp); + +// Check that the definition of the counter-clockwise func/ops match the +// clockwise ones, just shifted by 16 bits, so that we can use +// DecodeStencilFuncOps on both of them. +#define CHECK_CCW_MATCHES_CW(FIELD) \ + COMPILE_ASSERT(o3d::SetStencilTest::CW ## FIELD::kLength == \ + o3d::SetStencilTest::CCW ## FIELD::kLength, \ + CCW ## FIELD ## _length_does_not_match_ ## CW ## FIELD); \ + COMPILE_ASSERT(o3d::SetStencilTest::CW ## FIELD::kShift + 16 == \ + o3d::SetStencilTest::CCW ## FIELD::kShift, \ + CCW ## FIELD ## _shift_does_not_match_ ## CW ## FIELD) + +CHECK_CCW_MATCHES_CW(Func); +CHECK_CCW_MATCHES_CW(PassOp); +CHECK_CCW_MATCHES_CW(FailOp); +CHECK_CCW_MATCHES_CW(ZFailOp); + +#undef CHECK_CCW_MATCHES_CW + +// Decodes stencil test function and operations from the bitfield. +void DecodeStencilFuncOps(Uint32 params, + GLenum *func, + GLenum *pass, + GLenum *fail, + GLenum *zfail) { + // Sanity check. The value has already been tested in + // GAPIDecoder::DecodeSetStencilTest in gapi_decoder.cc. + DCHECK_EQ(o3d::SetStencilTest::Unused1::Get(params), 0); + // Check that the bitmask get cannot generate values outside of the allowed + // range. + COMPILE_ASSERT(o3d::SetStencilTest::CWFunc::kMask < + o3d::kNumComparison, + set_stencil_test_CWFunc_may_produce_invalid_values); + *func = kGLComparison[o3d::SetStencilTest::CWFunc::Get(params)]; + + COMPILE_ASSERT(o3d::SetStencilTest::CWPassOp::kMask < + o3d::kNumStencilOp, + set_stencil_test_CWPassOp_may_produce_invalid_values); + *pass = kGLStencilOp[o3d::SetStencilTest::CWPassOp::Get(params)]; + + COMPILE_ASSERT(o3d::SetStencilTest::CWFailOp::kMask < + o3d::kNumStencilOp, + set_stencil_test_CWFailOp_may_produce_invalid_values); + *fail = kGLStencilOp[o3d::SetStencilTest::CWFailOp::Get(params)]; + + COMPILE_ASSERT(o3d::SetStencilTest::CWZFailOp::kMask < + o3d::kNumStencilOp, + set_stencil_test_CWZFailOp_may_produce_invalid_values); + *zfail = kGLStencilOp[o3d::SetStencilTest::CWZFailOp::Get(params)]; +} + +} // anonymous namespace + +void GAPIGL::SetViewport(unsigned int x, + unsigned int y, + unsigned int width, + unsigned int height, + float z_min, + float z_max) { + glViewport(x, y, width, height); + glDepthRange(z_min, z_max); + // Update the helper constant used for the D3D -> GL remapping. + // See effect_gl.cc for details. + glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 0, + 1.f / width, 1.f / height, 2.f, 0.f); + CHECK_GL_ERROR(); +} + +void GAPIGL::SetScissor(bool enable, + unsigned int x, + unsigned int y, + unsigned int width, + unsigned int height) { + if (enable) { + glEnable(GL_SCISSOR_TEST); + glScissor(x, y, width, height); + } else { + glDisable(GL_SCISSOR_TEST); + } +} + +void GAPIGL::SetPointLineRaster(bool line_smooth, + bool point_sprite, + float point_size) { + if (line_smooth) { + glEnable(GL_LINE_SMOOTH); + } else { + glDisable(GL_LINE_SMOOTH); + } + if (point_sprite) { + glEnable(GL_POINT_SPRITE); + // TODO: check which TC gets affected by point sprites in D3D. + glActiveTextureARB(GL_TEXTURE0); + glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); + } else { + glActiveTextureARB(GL_TEXTURE0); + glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_FALSE); + glDisable(GL_POINT_SPRITE); + } + glPointSize(point_size); +} + +void GAPIGL::SetPolygonOffset(float slope_factor, float units) { + glPolygonOffset(slope_factor, units); +} + +void GAPIGL::SetPolygonRaster(o3d::PolygonMode fill_mode, + o3d::FaceCullMode cull_mode) { + DCHECK_LT(fill_mode, kNumPolygonMode); + glPolygonMode(GL_FRONT_AND_BACK, kGLPolygonModes[fill_mode]); + DCHECK_LT(cull_mode, kNumFaceCullMode); + switch (cull_mode) { + case kCullCW: + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + break; + case kCullCCW: + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); + break; + default: + glDisable(GL_CULL_FACE); + break; + } +} + +void GAPIGL::SetAlphaTest(bool enable, + float reference, + o3d::Comparison comp) { + DCHECK_LT(comp, kNumComparison); + if (enable) { + glEnable(GL_ALPHA_TEST); + glAlphaFunc(kGLComparison[comp], reference); + } else { + glDisable(GL_ALPHA_TEST); + } +} + +void GAPIGL::SetDepthTest(bool enable, + bool write_enable, + o3d::Comparison comp) { + DCHECK_LT(comp, kNumComparison); + if (enable) { + glEnable(GL_DEPTH_TEST); + glDepthFunc(kGLComparison[comp]); + } else { + glDisable(GL_DEPTH_TEST); + } + glDepthMask(write_enable); +} + +void GAPIGL::SetStencilTest(bool enable, + bool separate_ccw, + unsigned int write_mask, + unsigned int compare_mask, + unsigned int ref, + Uint32 func_ops) { + if (enable) { + glEnable(GL_STENCIL_TEST); + glStencilMask(write_mask); + + GLenum func; + GLenum pass; + GLenum fail; + GLenum zfail; + DecodeStencilFuncOps(func_ops, &func, &pass, &fail, &zfail); + if (separate_ccw) { + glStencilFuncSeparate(GL_FRONT, func, ref, compare_mask); + glStencilOpSeparate(GL_FRONT, pass, fail, zfail); + // Extract upper 16 bits. + Uint32 ccw_func_ops = BitField<16, 16>::Get(func_ops); + GLenum ccw_func; + GLenum ccw_pass; + GLenum ccw_fail; + GLenum ccw_zfail; + DecodeStencilFuncOps(ccw_func_ops, &ccw_func, &ccw_pass, &ccw_fail, + &ccw_zfail); + glStencilFuncSeparate(GL_BACK, ccw_func, ref, compare_mask); + glStencilOpSeparate(GL_BACK, ccw_pass, ccw_fail, ccw_zfail); + } else { + glStencilFunc(func, ref, compare_mask); + glStencilOp(pass, fail, zfail); + } + } else { + glDisable(GL_STENCIL_TEST); + } +} + +void GAPIGL::SetColorWrite(bool red, + bool green, + bool blue, + bool alpha, + bool dither) { + glColorMask(red, green, blue, alpha); + if (dither) { + glEnable(GL_DITHER); + } else { + glDisable(GL_DITHER); + } +} + +void GAPIGL::SetBlending(bool enable, + bool separate_alpha, + BlendEq color_eq, + BlendFunc color_src_func, + BlendFunc color_dst_func, + BlendEq alpha_eq, + BlendFunc alpha_src_func, + BlendFunc alpha_dst_func) { + DCHECK_LT(color_eq, kNumBlendEq); + DCHECK_LT(color_src_func, kNumBlendFunc); + DCHECK_LT(color_dst_func, kNumBlendFunc); + DCHECK_LT(alpha_eq, kNumBlendEq); + DCHECK_LT(alpha_src_func, kNumBlendFunc); + DCHECK_LT(alpha_dst_func, kNumBlendFunc); + if (enable) { + glEnable(GL_BLEND); + GLenum gl_color_eq = kGLBlendEq[color_eq]; + GLenum gl_color_src_func = kGLBlendFunc[color_src_func]; + GLenum gl_color_dst_func = kGLBlendFunc[color_dst_func]; + if (separate_alpha) { + GLenum gl_alpha_eq = kGLBlendEq[alpha_eq]; + GLenum gl_alpha_src_func = kGLBlendFunc[alpha_src_func]; + GLenum gl_alpha_dst_func = kGLBlendFunc[alpha_dst_func]; + glBlendFuncSeparate(gl_color_src_func, gl_color_dst_func, + gl_alpha_src_func, gl_alpha_dst_func); + glBlendEquationSeparate(gl_color_eq, gl_alpha_eq); + } else { + glBlendFunc(gl_color_src_func, gl_color_dst_func); + glBlendEquation(gl_color_eq); + } + } else { + glDisable(GL_BLEND); + } +} + +void GAPIGL::SetBlendingColor(const RGBA &color) { + glBlendColor(color.red, color.green, color.blue, color.alpha); +} + +} // namespace o3d +} // namespace command_buffer diff --git a/o3d/command_buffer/service/texture_d3d9.cc b/o3d/command_buffer/service/texture_d3d9.cc new file mode 100644 index 0000000..ec55850 --- /dev/null +++ b/o3d/command_buffer/service/texture_d3d9.cc @@ -0,0 +1,730 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file implements the D3D9 versions of the texture resources, as well as +// the related GAPID3D9 function implementations. + +#include "command_buffer/service/gapi_d3d9.h" +#include "command_buffer/service/texture_d3d9.h" + +namespace command_buffer { +namespace o3d { + +// Converts a texture format to a D3D texture format. +D3DFORMAT TextureD3D9::D3DFormat(texture::Format format) { + switch (format) { + case texture::kXRGB8: return D3DFMT_X8R8G8B8; + case texture::kARGB8: return D3DFMT_A8R8G8B8; + case texture::kABGR16F: return D3DFMT_A16B16G16R16F; + case texture::kR32F: return D3DFMT_R32F; + case texture::kABGR32F: return D3DFMT_A32B32G32R32F; + case texture::kDXT1: return D3DFMT_DXT1; + // TODO(petersont): Add DXT3/5 support. + default: return D3DFMT_UNKNOWN; + }; +} + +// Converts a cube map face to a D3D face. +D3DCUBEMAP_FACES TextureD3D9::D3DFace(texture::Face face) { + switch (face) { + case texture::kFacePositiveX: + return D3DCUBEMAP_FACE_POSITIVE_X; + case texture::kFaceNegativeX: + return D3DCUBEMAP_FACE_NEGATIVE_X; + case texture::kFacePositiveY: + return D3DCUBEMAP_FACE_POSITIVE_Y; + case texture::kFaceNegativeY: + return D3DCUBEMAP_FACE_NEGATIVE_Y; + case texture::kFacePositiveZ: + return D3DCUBEMAP_FACE_POSITIVE_Z; + case texture::kFaceNegativeZ: + return D3DCUBEMAP_FACE_NEGATIVE_Z; + } + LOG(FATAL) << "Not reached."; + return D3DCUBEMAP_FACE_POSITIVE_X; +} + +// Texture 2D functions + +// Destroys the 2D texture, releasing the D3D texture, and its shadow if any. +Texture2DD3D9::~Texture2DD3D9() { + DCHECK(d3d_texture_); + d3d_texture_ = NULL; + if (d3d_shadow_) { + d3d_shadow_->Release(); + d3d_shadow_ = NULL; + } +} + +// Creates a 2D texture. For dynamic textures, create it in the default pool, +// and a shadow version in the system memory pool (that we can lock). For +// regular texture, simply create one in the managed pool. +Texture2DD3D9 *Texture2DD3D9::Create(GAPID3D9 *gapi, + unsigned int width, + unsigned int height, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces) { + DCHECK_GT(width, 0U); + DCHECK_GT(height, 0U); + DCHECK_GT(levels, 0U); + D3DFORMAT d3d_format = D3DFormat(format); + IDirect3DDevice9 *device = gapi->d3d_device(); + if (enable_render_surfaces) { + CComPtr d3d_texture = NULL; + HRESULT result = device->CreateTexture(width, height, levels, + D3DUSAGE_RENDERTARGET, d3d_format, + D3DPOOL_DEFAULT, &d3d_texture, + NULL); + if (result != D3D_OK) { + LOG(ERROR) << "DirectX error when calling CreateTexture: " + << DXGetErrorStringA(result); + return NULL; + } + return new Texture2DD3D9(levels, format, flags, width, height, d3d_texture, + NULL, enable_render_surfaces); + } else if (flags & texture::kDynamic) { + CComPtr d3d_texture = NULL; + HRESULT result = device->CreateTexture(width, height, levels, + D3DUSAGE_DYNAMIC, d3d_format, + D3DPOOL_DEFAULT, &d3d_texture, + NULL); + if (result != D3D_OK) { + LOG(ERROR) << "DirectX error when calling CreateTexture: " + << DXGetErrorStringA(result); + return NULL; + } + CComPtr d3d_shadow = NULL; + result = device->CreateTexture(width, height, levels, D3DUSAGE_DYNAMIC, + d3d_format, D3DPOOL_SYSTEMMEM, &d3d_shadow, + NULL); + if (result != D3D_OK) { + LOG(ERROR) << "DirectX error when calling CreateTexture: " + << DXGetErrorStringA(result); + return NULL; + } + return new Texture2DD3D9(levels, format, flags, width, height, d3d_texture, + d3d_shadow, enable_render_surfaces); + } else { + CComPtr d3d_texture = NULL; + HRESULT result = device->CreateTexture(width, height, levels, 0, d3d_format, + D3DPOOL_MANAGED, &d3d_texture, NULL); + if (result != D3D_OK) { + LOG(ERROR) << "DirectX error when calling CreateTexture: " + << DXGetErrorStringA(result); + return NULL; + } + return new Texture2DD3D9(levels, format, flags, width, height, d3d_texture, + NULL, enable_render_surfaces); + } +} + +// Sets the data in the texture, using LockRect()/UnlockRect(). For dynamic +// textures, it copies the data to the shadow texture, then updates the actual +// texture. For regular texture, it directly modifies the actual texture. +bool Texture2DD3D9::SetData(GAPID3D9 *gapi, + const Volume &volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + const void *data) { + DCHECK(d3d_texture_); + IDirect3DTexture9 *lock_texture = d3d_shadow_ ? d3d_shadow_ : d3d_texture_; + + MipLevelInfo mip_info; + MakeMipLevelInfo(&mip_info, format(), width_, height_, 1, level); + TransferInfo src_transfer_info; + MakeTransferInfo(&src_transfer_info, mip_info, volume, row_pitch, + slice_pitch); + if (!CheckVolume(mip_info, volume) || level >= levels() || + size < src_transfer_info.total_size) + return false; + + bool full_rect = IsFullVolume(mip_info, volume); + D3DLOCKED_RECT locked_rect; + RECT rect = {volume.x, volume.y, volume.x+volume.width, + volume.y+volume.height}; + DWORD lock_flags = + full_rect && (flags() & texture::kDynamic) ? D3DLOCK_DISCARD : 0; + HR(lock_texture->LockRect(level, &locked_rect, full_rect ? NULL : &rect, + lock_flags)); + + TransferInfo dst_transfer_info; + MakeTransferInfo(&dst_transfer_info, mip_info, volume, locked_rect.Pitch, + slice_pitch); + TransferVolume(volume, mip_info, dst_transfer_info, locked_rect.pBits, + src_transfer_info, data); + + HR(lock_texture->UnlockRect(level)); + if (d3d_shadow_) { + HR(gapi->d3d_device()->UpdateTexture(d3d_shadow_, d3d_texture_)); + } + return true; +} + +// Gets the data from the texture, using LockRect()/UnlockRect(). For dynamic +// textures, it gets the data from the shadow texture, For regular texture, it +// gets it directly from the actual texture. +bool Texture2DD3D9::GetData(GAPID3D9 *gapi, + const Volume &volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + void *data) { + DCHECK(d3d_texture_); + IDirect3DTexture9 *lock_texture = d3d_shadow_ ? d3d_shadow_ : d3d_texture_; + + MipLevelInfo mip_info; + MakeMipLevelInfo(&mip_info, format(), width_, height_, 1, level); + TransferInfo dst_transfer_info; + MakeTransferInfo(&dst_transfer_info, mip_info, volume, row_pitch, + slice_pitch); + if (!CheckVolume(mip_info, volume) || level >= levels() || + size < dst_transfer_info.total_size) + return false; + + bool full_rect = IsFullVolume(mip_info, volume); + D3DLOCKED_RECT locked_rect; + RECT rect = {volume.x, volume.y, volume.x+volume.width, + volume.y+volume.height}; + DWORD lock_flags = D3DLOCK_READONLY; + HR(lock_texture->LockRect(level, &locked_rect, full_rect ? NULL : &rect, + lock_flags)); + TransferInfo src_transfer_info; + MakeTransferInfo(&src_transfer_info, mip_info, volume, locked_rect.Pitch, + slice_pitch); + TransferVolume(volume, mip_info, dst_transfer_info, data, + src_transfer_info, locked_rect.pBits); + HR(lock_texture->UnlockRect(level)); + return true; +} + +bool Texture2DD3D9::CreateRenderSurface(int width, + int height, + int mip_level, + int side, + IDirect3DSurface9** direct3d_surface) { + IDirect3DTexture9* d3d_texture = + static_cast(d3d_base_texture()); + D3DSURFACE_DESC surface_desc; + d3d_texture->GetLevelDesc(mip_level, &surface_desc); + if (width != surface_desc.Width || height != surface_desc.Height) { + return false; + } + HR(d3d_texture->GetSurfaceLevel(mip_level, direct3d_surface)); + return true; +} + +// Texture 3D functions + +// Destroys the 3D texture. +Texture3DD3D9::~Texture3DD3D9() { + DCHECK(d3d_texture_); + d3d_texture_ = NULL; + if (d3d_shadow_) { + d3d_shadow_->Release(); + d3d_shadow_ = NULL; + } +} + +// Creates a 3D texture. For dynamic textures, create it in the default pool, +// and a shadow version in the system memory pool (that we can lock). For +// regular texture, simply create one in the managed pool. +Texture3DD3D9 *Texture3DD3D9::Create(GAPID3D9 *gapi, + unsigned int width, + unsigned int height, + unsigned int depth, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces) { + DCHECK_GT(width, 0U); + DCHECK_GT(height, 0U); + DCHECK_GT(depth, 0U); + DCHECK_GT(levels, 0U); + D3DFORMAT d3d_format = D3DFormat(format); + IDirect3DDevice9 *device = gapi->d3d_device(); + if (enable_render_surfaces) { + CComPtr d3d_texture = NULL; + HRESULT result = device->CreateVolumeTexture(width, height, depth, levels, + D3DUSAGE_RENDERTARGET, + d3d_format, D3DPOOL_DEFAULT, + &d3d_texture, NULL); + if (result != D3D_OK) { + LOG(ERROR) << "DirectX error when calling CreateTexture: " + << DXGetErrorStringA(result); + return NULL; + } + return new Texture3DD3D9(levels, format, flags, width, height, depth, + d3d_texture, NULL, enable_render_surfaces); + } else if (flags & texture::kDynamic) { + CComPtr d3d_texture = NULL; + HRESULT result = device->CreateVolumeTexture(width, height, depth, levels, + D3DUSAGE_DYNAMIC, d3d_format, + D3DPOOL_DEFAULT, &d3d_texture, + NULL); + if (result != D3D_OK) { + LOG(ERROR) << "DirectX error when calling CreateTexture: " + << DXGetErrorStringA(result); + return NULL; + } + CComPtr d3d_shadow = NULL; + result = device->CreateVolumeTexture(width, height, depth, levels, + D3DUSAGE_DYNAMIC, d3d_format, + D3DPOOL_SYSTEMMEM, &d3d_shadow, NULL); + if (result != D3D_OK) { + LOG(ERROR) << "DirectX error when calling CreateTexture: " + << DXGetErrorStringA(result); + return NULL; + } + return new Texture3DD3D9(levels, format, flags, width, height, depth, + d3d_texture, d3d_shadow, enable_render_surfaces); + } else { + CComPtr d3d_texture = NULL; + HRESULT result = device->CreateVolumeTexture(width, height, depth, levels, + D3DUSAGE_DYNAMIC, d3d_format, + D3DPOOL_MANAGED, &d3d_texture, + NULL); + if (result != D3D_OK) { + LOG(ERROR) << "DirectX error when calling CreateTexture: " + << DXGetErrorStringA(result); + return NULL; + } + return new Texture3DD3D9(levels, format, flags, width, height, depth, + d3d_texture, NULL, enable_render_surfaces); + } +} + +// Sets the data in the texture, using LockBox()/UnlockBox(). For dynamic +// textures, it copies the data to the shadow texture, then updates the actual +// texture. For regular texture, it directly modifies the actual texture. +bool Texture3DD3D9::SetData(GAPID3D9 *gapi, + const Volume &volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + const void *data) { + DCHECK(d3d_texture_); + IDirect3DVolumeTexture9 *lock_texture = + d3d_shadow_ ? d3d_shadow_ : d3d_texture_; + + MipLevelInfo mip_info; + MakeMipLevelInfo(&mip_info, format(), width_, height_, depth_, level); + TransferInfo src_transfer_info; + MakeTransferInfo(&src_transfer_info, mip_info, volume, row_pitch, + slice_pitch); + if (!CheckVolume(mip_info, volume) || level >= levels() || + size < src_transfer_info.total_size) + return false; + + bool full_box = IsFullVolume(mip_info, volume); + D3DLOCKED_BOX locked_box; + D3DBOX box = {volume.x, volume.y, volume.z, volume.x+volume.width, + volume.y+volume.height, volume.z+volume.depth}; + DWORD lock_flags = + full_box && (flags() & texture::kDynamic) ? D3DLOCK_DISCARD : 0; + HR(lock_texture->LockBox(level, &locked_box, full_box ? NULL : &box, + lock_flags)); + + TransferInfo dst_transfer_info; + MakeTransferInfo(&dst_transfer_info, mip_info, volume, locked_box.RowPitch, + locked_box.SlicePitch); + TransferVolume(volume, mip_info, dst_transfer_info, locked_box.pBits, + src_transfer_info, data); + + HR(lock_texture->UnlockBox(level)); + if (d3d_shadow_) { + HR(gapi->d3d_device()->UpdateTexture(d3d_shadow_, d3d_texture_)); + } + return true; +} + +// Gets the data from the texture, using LockBox()/UnlockBox(). For dynamic +// textures, it gets the data from the shadow texture, For regular texture, it +// gets it directly from the actual texture. +bool Texture3DD3D9::GetData(GAPID3D9 *gapi, + const Volume &volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + void *data) { + DCHECK(d3d_texture_); + IDirect3DVolumeTexture9 *lock_texture = + d3d_shadow_ ? d3d_shadow_ : d3d_texture_; + + MipLevelInfo mip_info; + MakeMipLevelInfo(&mip_info, format(), width_, height_, depth_, level); + TransferInfo dst_transfer_info; + MakeTransferInfo(&dst_transfer_info, mip_info, volume, row_pitch, + slice_pitch); + if (!CheckVolume(mip_info, volume) || level >= levels() || + size < dst_transfer_info.total_size) + return false; + + bool full_box = IsFullVolume(mip_info, volume); + D3DLOCKED_BOX locked_box; + D3DBOX box = {volume.x, volume.y, volume.z, volume.x+volume.width, + volume.y+volume.height, volume.z+volume.depth}; + DWORD lock_flags = D3DLOCK_READONLY; + HR(lock_texture->LockBox(level, &locked_box, full_box ? NULL : &box, + lock_flags)); + TransferInfo src_transfer_info; + MakeTransferInfo(&src_transfer_info, mip_info, volume, locked_box.RowPitch, + locked_box.SlicePitch); + TransferVolume(volume, mip_info, dst_transfer_info, data, + src_transfer_info, locked_box.pBits); + HR(lock_texture->UnlockBox(level)); + return true; +} + +bool Texture3DD3D9::CreateRenderSurface(int width, + int height, + int mip_level, + int side, + IDirect3DSurface9** direct3d_surface) { + // TODO(rlp): Currently unsupported. + DCHECK(false); + return false; +} + +// Texture Cube functions. + +// Destroys the cube map texture, releasing the D3D texture, and its shadow if +// any. +TextureCubeD3D9::~TextureCubeD3D9() { + DCHECK(d3d_texture_); + d3d_texture_ = NULL; + if (d3d_shadow_) { + d3d_shadow_->Release(); + d3d_shadow_ = NULL; + } +} + +// Creates a cube map texture. For dynamic textures, create it in the default +// pool, and a shadow version in the system memory pool (that we can lock). For +// regular texture, simply create one in the managed pool. +TextureCubeD3D9 *TextureCubeD3D9::Create(GAPID3D9 *gapi, + unsigned int side, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces) { + DCHECK_GT(side, 0U); + DCHECK_GT(levels, 0U); + D3DFORMAT d3d_format = D3DFormat(format); + IDirect3DDevice9 *device = gapi->d3d_device(); + if (enable_render_surfaces) { + CComPtr d3d_texture = NULL; + HRESULT result = device->CreateCubeTexture(side, levels, + D3DUSAGE_RENDERTARGET, + d3d_format, D3DPOOL_DEFAULT, + &d3d_texture, NULL); + if (result != D3D_OK) { + LOG(ERROR) << "DirectX error when calling CreateTexture: " + << DXGetErrorStringA(result); + return NULL; + } + return new TextureCubeD3D9(levels, format, flags, side, d3d_texture, NULL, + enable_render_surfaces); + } else if (flags & texture::kDynamic) { + CComPtr d3d_texture = NULL; + HRESULT result = device->CreateCubeTexture(side, levels, D3DUSAGE_DYNAMIC, + d3d_format, D3DPOOL_DEFAULT, + &d3d_texture, NULL); + if (result != D3D_OK) { + LOG(ERROR) << "DirectX error when calling CreateTexture: " + << DXGetErrorStringA(result); + return NULL; + } + CComPtr d3d_shadow = NULL; + result = device->CreateCubeTexture(side, levels, D3DUSAGE_DYNAMIC, + d3d_format, D3DPOOL_SYSTEMMEM, + &d3d_shadow, NULL); + if (result != D3D_OK) { + LOG(ERROR) << "DirectX error when calling CreateTexture: " + << DXGetErrorStringA(result); + return NULL; + } + return new TextureCubeD3D9(levels, format, flags, side, d3d_texture, + d3d_shadow, enable_render_surfaces); + } else { + CComPtr d3d_texture = NULL; + HRESULT result = device->CreateCubeTexture(side, levels, 0, d3d_format, + D3DPOOL_MANAGED, &d3d_texture, + NULL); + if (result != D3D_OK) { + LOG(ERROR) << "DirectX error when calling CreateTexture: " + << DXGetErrorStringA(result); + return NULL; + } + return new TextureCubeD3D9(levels, format, flags, side, d3d_texture, NULL, + enable_render_surfaces); + } +} + +// Sets the data in the texture, using LockRect()/UnlockRect(). For dynamic +// textures, it copies the data to the shadow texture, then updates the actual +// texture. For regular texture, it directly modifies the actual texture. +bool TextureCubeD3D9::SetData(GAPID3D9 *gapi, + const Volume &volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + const void *data) { + DCHECK(d3d_texture_); + IDirect3DCubeTexture9 *lock_texture = + d3d_shadow_ ? d3d_shadow_ : d3d_texture_; + MipLevelInfo mip_info; + MakeMipLevelInfo(&mip_info, format(), side_, side_, 1, level); + TransferInfo src_transfer_info; + MakeTransferInfo(&src_transfer_info, mip_info, volume, row_pitch, + slice_pitch); + if (!CheckVolume(mip_info, volume) || level >= levels() || + size < src_transfer_info.total_size) + return false; + + D3DCUBEMAP_FACES d3d_face = D3DFace(face); + bool full_rect = IsFullVolume(mip_info, volume); + D3DLOCKED_RECT locked_rect; + RECT rect = {volume.x, volume.y, volume.x+volume.width, + volume.y+volume.height}; + DWORD lock_flags = + full_rect && (flags() & texture::kDynamic) ? D3DLOCK_DISCARD : 0; + HR(lock_texture->LockRect(d3d_face, level, &locked_rect, + full_rect ? NULL : &rect, lock_flags)); + + TransferInfo dst_transfer_info; + MakeTransferInfo(&dst_transfer_info, mip_info, volume, locked_rect.Pitch, + slice_pitch); + TransferVolume(volume, mip_info, dst_transfer_info, locked_rect.pBits, + src_transfer_info, data); + + HR(lock_texture->UnlockRect(d3d_face, level)); + if (d3d_shadow_) { + HR(gapi->d3d_device()->UpdateTexture(d3d_shadow_, d3d_texture_)); + } + return true; +} + +// Gets the data from the texture, using LockRect()/UnlockRect(). For dynamic +// textures, it gets the data from the shadow texture, For regular texture, it +// gets it directly from the actual texture. +bool TextureCubeD3D9::GetData(GAPID3D9 *gapi, + const Volume &volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + void *data) { + DCHECK(d3d_texture_); + IDirect3DCubeTexture9 *lock_texture = + d3d_shadow_ ? d3d_shadow_ : d3d_texture_; + + MipLevelInfo mip_info; + MakeMipLevelInfo(&mip_info, format(), side_, side_, 1, level); + TransferInfo dst_transfer_info; + MakeTransferInfo(&dst_transfer_info, mip_info, volume, row_pitch, + slice_pitch); + if (!CheckVolume(mip_info, volume) || level >= levels() || + size < dst_transfer_info.total_size) + return false; + + D3DCUBEMAP_FACES d3d_face = D3DFace(face); + bool full_rect = IsFullVolume(mip_info, volume); + D3DLOCKED_RECT locked_rect; + RECT rect = {volume.x, volume.y, volume.x+volume.width, + volume.y+volume.height}; + DWORD lock_flags = D3DLOCK_READONLY; + HR(lock_texture->LockRect(d3d_face, level, &locked_rect, + full_rect ? NULL : &rect, lock_flags)); + TransferInfo src_transfer_info; + MakeTransferInfo(&src_transfer_info, mip_info, volume, locked_rect.Pitch, + slice_pitch); + TransferVolume(volume, mip_info, dst_transfer_info, data, + src_transfer_info, locked_rect.pBits); + HR(lock_texture->UnlockRect(d3d_face, level)); + return true; +} + +bool TextureCubeD3D9::CreateRenderSurface( + int width, + int height, + int mip_level, + int side, + IDirect3DSurface9** direct3d_surface) { + IDirect3DCubeTexture9* d3d_cube_texture = + static_cast(d3d_base_texture()); + D3DSURFACE_DESC surface_desc; + d3d_cube_texture->GetLevelDesc(mip_level, &surface_desc); + if (width != surface_desc.Width || height != surface_desc.Height || + side < 0 || side > 5) { + return false; + } + HR(d3d_cube_texture->GetCubeMapSurface( + D3DFace(static_cast(side)), + mip_level, + direct3d_surface)); + return true; +} + +// GAPID3D9 functions. + +// Destroys a texture resource. +parse_error::ParseError GAPID3D9::DestroyTexture(ResourceId id) { + // Dirty effect, because this texture id may be used + DirtyEffect(); + return textures_.Destroy(id) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +// Creates a 2D texture resource. +parse_error::ParseError GAPID3D9::CreateTexture2D( + ResourceId id, + unsigned int width, + unsigned int height, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces) { + Texture2DD3D9 *texture = Texture2DD3D9::Create(this, width, height, levels, + format, flags, + enable_render_surfaces); + if (!texture) return parse_error::kParseInvalidArguments; + // Dirty effect, because this texture id may be used + DirtyEffect(); + textures_.Assign(id, texture); + return parse_error::kParseNoError; +} + +// Creates a 3D texture resource. +parse_error::ParseError GAPID3D9::CreateTexture3D( + ResourceId id, + unsigned int width, + unsigned int height, + unsigned int depth, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces) { + Texture3DD3D9 *texture = Texture3DD3D9::Create(this, width, height, depth, + levels, format, flags, + enable_render_surfaces); + if (!texture) return parse_error::kParseInvalidArguments; + // Dirty effect, because this texture id may be used + DirtyEffect(); + textures_.Assign(id, texture); + return parse_error::kParseNoError; +} + +// Creates a cube map texture resource. +parse_error::ParseError GAPID3D9::CreateTextureCube( + ResourceId id, + unsigned int side, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces) { + TextureCubeD3D9 *texture = TextureCubeD3D9::Create(this, side, levels, + format, flags, + enable_render_surfaces); + if (!texture) return parse_error::kParseInvalidArguments; + // Dirty effect, because this texture id may be used + DirtyEffect(); + textures_.Assign(id, texture); + return parse_error::kParseNoError; +} + +// Copies the data into a texture resource. +parse_error::ParseError GAPID3D9::SetTextureData( + ResourceId id, + unsigned int x, + unsigned int y, + unsigned int z, + unsigned int width, + unsigned int height, + unsigned int depth, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + const void *data) { + TextureD3D9 *texture = textures_.Get(id); + if (!texture) + return parse_error::kParseInvalidArguments; + Volume volume = {x, y, z, width, height, depth}; + return texture->SetData(this, volume, level, face, row_pitch, slice_pitch, + size, data) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +// Copies the data from a texture resource. +parse_error::ParseError GAPID3D9::GetTextureData( + ResourceId id, + unsigned int x, + unsigned int y, + unsigned int z, + unsigned int width, + unsigned int height, + unsigned int depth, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + void *data) { + TextureD3D9 *texture = textures_.Get(id); + if (!texture) + return parse_error::kParseInvalidArguments; + Volume volume = {x, y, z, width, height, depth}; + return texture->GetData(this, volume, level, face, row_pitch, slice_pitch, + size, data) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +} // namespace o3d +} // namespace command_buffer diff --git a/o3d/command_buffer/service/texture_d3d9.h b/o3d/command_buffer/service/texture_d3d9.h new file mode 100644 index 0000000..5171d04 --- /dev/null +++ b/o3d/command_buffer/service/texture_d3d9.h @@ -0,0 +1,282 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef GPU_COMMAND_BUFFER_SERVICE_WIN_D3D9_TEXTURE_D3D9_H_ +#define GPU_COMMAND_BUFFER_SERVICE_WIN_D3D9_TEXTURE_D3D9_H_ + +// This file contains the definition of the D3D9 versions of texture-related +// resource classes. +#include + +#include "command_buffer/common/gapi_interface.h" +#include "command_buffer/service/d3d9_utils.h" +#include "command_buffer/service/resource.h" +#include "command_buffer/service/texture_utils.h" + +namespace command_buffer { +namespace o3d { + +class GAPID3D9; + +// The base class for a D3D texture resource, providing access to the base D3D +// texture that can be assigned to an effect parameter or a sampler unit. +class TextureD3D9 : public Texture { + public: + TextureD3D9(texture::Type type, + unsigned int levels, + texture::Format format, + bool enable_render_surfaces, + unsigned int flags) + : Texture(type, levels, format, enable_render_surfaces, flags) {} + // Gets the D3D base texture. + virtual IDirect3DBaseTexture9 *d3d_base_texture() const = 0; + // Sets data into a texture resource. + virtual bool SetData(GAPID3D9 *gapi, + const Volume& volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + const void *data) = 0; + // Gets data from a texture resource. + virtual bool GetData(GAPID3D9 *gapi, + const Volume& volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + void *data) = 0; + // Creates the render surface, returning false if unable to. + virtual bool CreateRenderSurface(int width, + int height, + int mip_level, + int side, + IDirect3DSurface9** direct3d_surface) = 0; + static D3DFORMAT D3DFormat(texture::Format format); + static D3DCUBEMAP_FACES D3DFace(texture::Face face); + private: + DISALLOW_COPY_AND_ASSIGN(TextureD3D9); +}; + +// A 2D texture resource for D3D. +class Texture2DD3D9 : public TextureD3D9 { + public: + Texture2DD3D9(unsigned int levels, + texture::Format format, + unsigned int flags, + unsigned int width, + unsigned int height, + IDirect3DTexture9 *texture, + IDirect3DTexture9 *shadow, + bool enable_render_surfaces) + : TextureD3D9(texture::kTexture2d, levels, format, + enable_render_surfaces, flags), + width_(width), + height_(height), + d3d_texture_(texture), + d3d_shadow_(shadow) {} + virtual ~Texture2DD3D9(); + + // Creates a 2D texture resource. + static Texture2DD3D9 *Create(GAPID3D9 *gapi, + unsigned int width, + unsigned int height, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces); + // Sets data into a 2D texture resource. + virtual bool SetData(GAPID3D9 *gapi, + const Volume& volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + const void *data); + // Gets data from a 2D texture resource. + virtual bool GetData(GAPID3D9 *gapi, + const Volume& volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + void *data); + // Create a render surface which matches this texture type. + virtual bool CreateRenderSurface(int width, + int height, + int mip_level, + int side, + IDirect3DSurface9** direct3d_surface); + // Gets the D3D base texture. + virtual IDirect3DBaseTexture9 *d3d_base_texture() const { + return d3d_texture_; + } + private: + unsigned int width_; + unsigned int height_; + CComPtr d3d_texture_; + IDirect3DTexture9 *d3d_shadow_; + DISALLOW_COPY_AND_ASSIGN(Texture2DD3D9); +}; + +// A 3D texture resource for D3D. +class Texture3DD3D9 : public TextureD3D9 { + public: + Texture3DD3D9(unsigned int levels, + texture::Format format, + unsigned int flags, + unsigned int width, + unsigned int height, + unsigned int depth, + IDirect3DVolumeTexture9 *texture, + IDirect3DVolumeTexture9 *shadow, + bool enable_render_surfaces) + : TextureD3D9(texture::kTexture3d, levels, format, + enable_render_surfaces, flags), + width_(width), + height_(height), + depth_(depth), + d3d_texture_(texture), + d3d_shadow_(shadow) {} + virtual ~Texture3DD3D9(); + // Creates a 3D texture resource. + static Texture3DD3D9 *Create(GAPID3D9 *gapi, + unsigned int width, + unsigned int height, + unsigned int depth, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces); + // Sets data into a 3D texture resource. + virtual bool SetData(GAPID3D9 *gapi, + const Volume& volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + const void *data); + // Gets data from a 3D texture resource. + virtual bool GetData(GAPID3D9 *gapi, + const Volume& volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + void *data); + // Create a render surface which matches this texture type. + virtual bool CreateRenderSurface(int width, + int height, + int mip_level, + int side, + IDirect3DSurface9** direct3d_surface); + // Gets the D3D base texture. + virtual IDirect3DBaseTexture9 *d3d_base_texture() const { + return d3d_texture_; + } + private: + unsigned int width_; + unsigned int height_; + unsigned int depth_; + CComPtr d3d_texture_; + IDirect3DVolumeTexture9 *d3d_shadow_; + DISALLOW_COPY_AND_ASSIGN(Texture3DD3D9); +}; + +// A cube map texture resource for D3D. +class TextureCubeD3D9 : public TextureD3D9 { + public: + TextureCubeD3D9(unsigned int levels, + texture::Format format, + unsigned int flags, + unsigned int side, + IDirect3DCubeTexture9 *texture, + IDirect3DCubeTexture9 *shadow, + bool enable_render_surfaces) + : TextureD3D9(texture::kTextureCube, levels, format, + enable_render_surfaces, flags), + side_(side), + d3d_texture_(texture), + d3d_shadow_(shadow) {} + virtual ~TextureCubeD3D9(); + // Creates a cube map texture resource. + static TextureCubeD3D9 *Create(GAPID3D9 *gapi, + unsigned int side, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces); + // Sets data into a cube map texture resource. + virtual bool SetData(GAPID3D9 *gapi, + const Volume& volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + const void *data); + // Gets data from a cube map texture resource. + virtual bool GetData(GAPID3D9 *gapi, + const Volume& volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + void *data); + // Create a render surface which matches this texture type. + virtual bool CreateRenderSurface(int width, + int height, + int mip_level, + int side, + IDirect3DSurface9** direct3d_surface); + // Gets the D3D base texture. + virtual IDirect3DBaseTexture9 *d3d_base_texture() const { + return d3d_texture_; + } + private: + unsigned int side_; + CComPtr d3d_texture_; + IDirect3DCubeTexture9 *d3d_shadow_; + DISALLOW_COPY_AND_ASSIGN(TextureCubeD3D9); +}; + +} // namespace o3d +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_WIN_D3D9_TEXTURE_D3D9_H_ diff --git a/o3d/command_buffer/service/texture_gl.cc b/o3d/command_buffer/service/texture_gl.cc new file mode 100644 index 0000000..954a007 --- /dev/null +++ b/o3d/command_buffer/service/texture_gl.cc @@ -0,0 +1,766 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file implements the texture-related GAPI functions on GL. + +#include "command_buffer/service/gapi_gl.h" +#include "command_buffer/service/texture_gl.h" + +namespace command_buffer { +namespace o3d { + +namespace { + +// Gets the GL internal format, format and type corresponding to a command +// buffer texture format. +bool GetGLFormatType(texture::Format format, + GLenum *internal_format, + GLenum *gl_format, + GLenum *gl_type) { + switch (format) { + case texture::kXRGB8: { + *internal_format = GL_RGB; + *gl_format = GL_BGRA; + *gl_type = GL_UNSIGNED_BYTE; + break; + } + case texture::kARGB8: { + *internal_format = GL_RGBA; + *gl_format = GL_BGRA; + *gl_type = GL_UNSIGNED_BYTE; + break; + } + case texture::kABGR16F: { + *internal_format = GL_RGBA16F_ARB; + *gl_format = GL_RGBA; + *gl_type = GL_HALF_FLOAT_ARB; + break; + } + case texture::kR32F: { + *internal_format = GL_LUMINANCE32F_ARB; + *gl_format = GL_LUMINANCE; + *gl_type = GL_FLOAT; + break; + } + case texture::kABGR32F: { + *internal_format = GL_RGBA32F_ARB; + *gl_format = GL_BGRA; + *gl_type = GL_FLOAT; + break; + } + case texture::kDXT1: { + *internal_format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + *gl_format = 0; + *gl_type = 0; + break; + } + // TODO(petersont): Add DXT3/5 support. + default: + return false; + } + + return true; +} + +// Helper class used to prepare image data to match the layout that +// glTexImage* and glCompressedTexImage* expect. +class SetImageHelper { + public: + SetImageHelper() + : buffer_(NULL), + image_data_(NULL), + image_size_(0) { + } + + // Initializes the helper with the input data, re-using the input buffer if + // possible, or copying it into a temporary one. + bool Initialize(const MipLevelInfo &mip_info, + const Volume& volume, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int src_size, + const void *data) { + TransferInfo src_transfer_info; + MakeTransferInfo(&src_transfer_info, mip_info, volume, row_pitch, + slice_pitch); + if (!CheckVolume(mip_info, volume) || + src_size < src_transfer_info.total_size) + return false; + if (!src_transfer_info.packed) { + TransferInfo dst_transfer_info; + MakePackedTransferInfo(&dst_transfer_info, mip_info, volume); + buffer_.reset(new unsigned char[dst_transfer_info.total_size]); + TransferVolume(volume, mip_info, dst_transfer_info, buffer_.get(), + src_transfer_info, data); + image_data_ = buffer_.get(); + image_size_ = dst_transfer_info.total_size; + } else { + image_data_ = data; + image_size_ = src_transfer_info.total_size; + } + return true; + } + + // Gets the buffer that contains the data in the GL format. + const void *image_data() { return image_data_; } + // Gets the size of the buffer as GL expects it. + unsigned int image_size() { return image_size_; } + + private: + scoped_array buffer_; + const void *image_data_; + unsigned int image_size_; + DISALLOW_COPY_AND_ASSIGN(SetImageHelper); +}; + +// Helper class used to retrieve image data to match the layout that +// glGetTexImage and glGetCompressedTexImage expect. +class GetImageHelper { + public: + GetImageHelper() + : dst_data_(NULL), + buffer_(NULL), + image_data_(NULL) { + memset(&mip_info_, 0, sizeof(mip_info_)); + memset(&volume_, 0, sizeof(volume_)); + memset(&dst_transfer_info_, 0, sizeof(dst_transfer_info_)); + memset(&src_transfer_info_, 0, sizeof(src_transfer_info_)); + } + + // Initialize the helper to make available a buffer to get the data from GL. + // It will re-use the passed in buffer if the layout matches GL, or allocate + // a temporary one. + bool Initialize(const MipLevelInfo &mip_info, + const Volume& volume, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int dst_size, + void *dst_data) { + mip_info_ = mip_info; + volume_ = volume; + dst_data_ = dst_data; + MakeTransferInfo(&dst_transfer_info_, mip_info, volume, row_pitch, + slice_pitch); + if (!CheckVolume(mip_info, volume) || + dst_size < dst_transfer_info_.total_size) + return false; + + if (!IsFullVolume(mip_info, volume) || !dst_transfer_info_.packed) { + // We can only retrieve the full image from GL. + Volume full_volume = { + 0, 0, 0, + mip_info.width, mip_info.height, mip_info.depth + }; + MakePackedTransferInfo(&src_transfer_info_, mip_info, full_volume); + buffer_.reset(new unsigned char[src_transfer_info_.total_size]); + image_data_ = buffer_.get(); + } else { + image_data_ = dst_data; + } + return true; + } + + // Finalize the helper, copying the data into the final buffer if needed. + void Finalize() { + if (!buffer_.get()) return; + unsigned int offset = + volume_.x / mip_info_.block_size_x * mip_info_.block_bpp + + volume_.y / mip_info_.block_size_y * src_transfer_info_.row_pitch + + volume_.z * src_transfer_info_.slice_pitch; + src_transfer_info_.row_size = dst_transfer_info_.row_size; + TransferVolume(volume_, mip_info_, dst_transfer_info_, dst_data_, + src_transfer_info_, buffer_.get() + offset); + } + + // Gets the buffer that can receive the data from GL. + void *image_data() { return image_data_; } + + private: + MipLevelInfo mip_info_; + Volume volume_; + TransferInfo dst_transfer_info_; + TransferInfo src_transfer_info_; + void *dst_data_; + scoped_array buffer_; + void *image_data_; + DISALLOW_COPY_AND_ASSIGN(GetImageHelper); +}; + +} // anonymous namespace + +TextureGL::~TextureGL() { + glDeleteTextures(1, &gl_texture_); + CHECK_GL_ERROR(); +} + +Texture2DGL *Texture2DGL::Create(unsigned int width, + unsigned int height, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces) { + DCHECK_GT(width, 0U); + DCHECK_GT(height, 0U); + DCHECK_GT(levels, 0U); + GLenum gl_internal_format = 0; + GLenum gl_format = 0; + GLenum gl_type = 0; + bool r = GetGLFormatType(format, &gl_internal_format, &gl_format, &gl_type); + DCHECK(r); // Was checked in the decoder. + GLuint gl_texture = 0; + glGenTextures(1, &gl_texture); + glBindTexture(GL_TEXTURE_2D, gl_texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, levels - 1); + // glCompressedTexImage2D does't accept NULL as a parameter, so we need + // to pass in some data. + scoped_array buffer; + MipLevelInfo mip_info; + MakeMipLevelInfo(&mip_info, format, width, height, 1, 0); + unsigned int size = GetMipLevelSize(mip_info); + buffer.reset(new unsigned char[size]); + memset(buffer.get(), 0, size); + + unsigned int mip_width = width; + unsigned int mip_height = height; + + for (unsigned int i = 0; i < levels; ++i) { + if (gl_format) { + glTexImage2D(GL_TEXTURE_2D, i, gl_internal_format, mip_width, mip_height, + 0, gl_format, gl_type, buffer.get()); + } else { + MipLevelInfo mip_info; + MakeMipLevelInfo(&mip_info, format, width, height, 1, i); + unsigned int size = GetMipLevelSize(mip_info); + glCompressedTexImage2D(GL_TEXTURE_2D, i, gl_internal_format, mip_width, + mip_height, 0, size, buffer.get()); + } + mip_width = std::max(1U, mip_width >> 1); + mip_height = std::max(1U, mip_height >> 1); + } + return new Texture2DGL( + levels, format, enable_render_surfaces, flags, width, height, gl_texture); +} + +// Sets data into a 2D texture resource. +bool Texture2DGL::SetData(const Volume& volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + const void *data) { + if (level >= levels()) + return false; + MipLevelInfo mip_info; + MakeMipLevelInfo(&mip_info, format(), width_, height_, 1, level); + SetImageHelper helper; + if (!helper.Initialize(mip_info, volume, row_pitch, slice_pitch, size, data)) + return false; + + GLenum gl_internal_format = 0; + GLenum gl_format = 0; + GLenum gl_type = 0; + bool r = GetGLFormatType(format(), &gl_internal_format, &gl_format, &gl_type); + DCHECK(r); + glBindTexture(GL_TEXTURE_2D, gl_texture_); + if (gl_format) { + glTexSubImage2D(GL_TEXTURE_2D, level, volume.x, volume.y, volume.width, + volume.height, gl_format, gl_type, helper.image_data()); + } else { + glCompressedTexSubImage2D(GL_TEXTURE_2D, level, volume.x, volume.y, + volume.width, volume.height, gl_internal_format, + helper.image_size(), helper.image_data()); + } + return true; +} + +bool Texture2DGL::GetData(const Volume& volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + void *data) { + if (level >= levels()) + return false; + MipLevelInfo mip_info; + MakeMipLevelInfo(&mip_info, format(), width_, height_, 1, level); + GetImageHelper helper; + if (!helper.Initialize(mip_info, volume, row_pitch, slice_pitch, size, data)) + return false; + + GLenum gl_internal_format = 0; + GLenum gl_format = 0; + GLenum gl_type = 0; + bool r = GetGLFormatType(format(), &gl_internal_format, &gl_format, &gl_type); + DCHECK(r); + glBindTexture(GL_TEXTURE_2D, gl_texture_); + if (gl_format) { + glGetTexImage(GL_TEXTURE_2D, level, gl_format, gl_type, + helper.image_data()); + } else { + glGetCompressedTexImage(GL_TEXTURE_2D, level, helper.image_data()); + } + + helper.Finalize(); + return true; +} + +bool Texture2DGL::CreateRenderSurface(int width, + int height, + int mip_level, + int side) { + return false; +} + +bool Texture2DGL::InstallFrameBufferObjects( + RenderSurfaceGL *gl_surface) { + ::glFramebufferTexture2DEXT( + GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_2D, + gl_texture_, + gl_surface->mip_level()); + + GLenum framebuffer_status = ::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + if (GL_FRAMEBUFFER_COMPLETE_EXT != framebuffer_status) { + return false; + } + + return true; +} + +Texture3DGL *Texture3DGL::Create(unsigned int width, + unsigned int height, + unsigned int depth, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces) { + DCHECK_GT(width, 0U); + DCHECK_GT(height, 0U); + DCHECK_GT(depth, 0U); + DCHECK_GT(levels, 0U); + GLenum gl_internal_format = 0; + GLenum gl_format = 0; + GLenum gl_type = 0; + bool r = GetGLFormatType(format, &gl_internal_format, &gl_format, &gl_type); + DCHECK(r); // Was checked in the decoder. + GLuint gl_texture = 0; + glGenTextures(1, &gl_texture); + glBindTexture(GL_TEXTURE_3D, gl_texture); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, levels - 1); + // glCompressedTexImage3D does't accept NULL as a parameter, so we need + // to pass in some data. + scoped_array buffer; + MipLevelInfo mip_info; + MakeMipLevelInfo(&mip_info, format, width, height, depth, 0); + unsigned int size = GetMipLevelSize(mip_info); + buffer.reset(new unsigned char[size]); + memset(buffer.get(), 0, size); + + unsigned int mip_width = width; + unsigned int mip_height = height; + unsigned int mip_depth = depth; + for (unsigned int i = 0; i < levels; ++i) { + if (gl_format) { + glTexImage3D(GL_TEXTURE_3D, i, gl_internal_format, mip_width, mip_height, + mip_depth, 0, gl_format, gl_type, buffer.get()); + } else { + MipLevelInfo mip_info; + MakeMipLevelInfo(&mip_info, format, width, height, depth, i); + unsigned int size = GetMipLevelSize(mip_info); + glCompressedTexImage3D(GL_TEXTURE_3D, i, gl_internal_format, mip_width, + mip_height, mip_depth, 0, size, buffer.get()); + } + mip_width = std::max(1U, mip_width >> 1); + mip_height = std::max(1U, mip_height >> 1); + mip_depth = std::max(1U, mip_depth >> 1); + } + return new Texture3DGL(levels, format, enable_render_surfaces, flags, width, + height, depth, gl_texture); +} + +bool Texture3DGL::SetData(const Volume& volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + const void *data) { + if (level >= levels()) + return false; + MipLevelInfo mip_info; + MakeMipLevelInfo(&mip_info, format(), width_, height_, depth_, level); + SetImageHelper helper; + if (!helper.Initialize(mip_info, volume, row_pitch, slice_pitch, size, data)) + return false; + + GLenum gl_internal_format = 0; + GLenum gl_format = 0; + GLenum gl_type = 0; + bool r = GetGLFormatType(format(), &gl_internal_format, &gl_format, &gl_type); + DCHECK(r); + glBindTexture(GL_TEXTURE_3D, gl_texture_); + if (gl_format) { + glTexSubImage3D(GL_TEXTURE_3D, level, volume.x, volume.y, volume.z, + volume.width, volume.height, volume.depth, + gl_format, gl_type, helper.image_data()); + } else { + glCompressedTexSubImage3D(GL_TEXTURE_3D, level, volume.x, volume.y, + volume.z, volume.width, volume.height, + volume.depth, gl_internal_format, + helper.image_size(), helper.image_data()); + } + return true; +} + +bool Texture3DGL::GetData(const Volume& volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + void *data) { + if (level >= levels()) + return false; + MipLevelInfo mip_info; + MakeMipLevelInfo(&mip_info, format(), width_, height_, depth_, level); + GetImageHelper helper; + if (!helper.Initialize(mip_info, volume, row_pitch, slice_pitch, size, data)) + return false; + + GLenum gl_internal_format = 0; + GLenum gl_format = 0; + GLenum gl_type = 0; + bool r = GetGLFormatType(format(), &gl_internal_format, &gl_format, &gl_type); + DCHECK(r); + glBindTexture(GL_TEXTURE_3D, gl_texture_); + if (gl_format) { + glGetTexImage(GL_TEXTURE_3D, level, gl_format, gl_type, + helper.image_data()); + } else { + glGetCompressedTexImage(GL_TEXTURE_3D, level, helper.image_data()); + } + + helper.Finalize(); + return true; +} + +bool Texture3DGL::CreateRenderSurface(int width, + int height, + int mip_level, + int side) { + return false; +} + +bool Texture3DGL::InstallFrameBufferObjects( + RenderSurfaceGL *gl_surface) { + return false; +} + +TextureCubeGL *TextureCubeGL::Create(unsigned int side, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces) { + DCHECK_GT(side, 0U); + DCHECK_GT(levels, 0U); + GLenum gl_internal_format = 0; + GLenum gl_format = 0; + GLenum gl_type = 0; + bool r = GetGLFormatType(format, &gl_internal_format, &gl_format, &gl_type); + DCHECK(r); // Was checked in the decoder. + GLuint gl_texture = 0; + glGenTextures(1, &gl_texture); + glBindTexture(GL_TEXTURE_CUBE_MAP, gl_texture); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, + levels-1); + // glCompressedTexImage2D does't accept NULL as a parameter, so we need + // to pass in some data. + scoped_array buffer; + MipLevelInfo mip_info; + MakeMipLevelInfo(&mip_info, format, side, side, 1, 0); + unsigned int size = GetMipLevelSize(mip_info); + buffer.reset(new unsigned char[size]); + memset(buffer.get(), 0, size); + + unsigned int mip_side = side; + for (unsigned int i = 0; i < levels; ++i) { + if (gl_format) { + for (unsigned int face = 0; face < 6; ++face) { + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, i, + gl_internal_format, mip_side, mip_side, + 0, gl_format, gl_type, buffer.get()); + } + } else { + MipLevelInfo mip_info; + MakeMipLevelInfo(&mip_info, format, side, side, 1, i); + unsigned int size = GetMipLevelSize(mip_info); + for (unsigned int face = 0; face < 6; ++face) { + glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, i, + gl_internal_format, mip_side, mip_side, 0, size, + buffer.get()); + } + } + mip_side = std::max(1U, mip_side >> 1); + } + return new TextureCubeGL( + levels, format, enable_render_surfaces, flags, side, gl_texture); +} + +// Check that GL_TEXTURE_CUBE_MAP_POSITIVE_X + face yields the correct GLenum. +COMPILE_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_X + texture::kFacePositiveX == + GL_TEXTURE_CUBE_MAP_POSITIVE_X, POSITIVE_X_ENUMS_DO_NOT_MATCH); +COMPILE_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_X + texture::kFaceNegativeX == + GL_TEXTURE_CUBE_MAP_NEGATIVE_X, NEGATIVE_X_ENUMS_DO_NOT_MATCH); +COMPILE_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_X + texture::kFacePositiveY == + GL_TEXTURE_CUBE_MAP_POSITIVE_Y, POSITIVE_Y_ENUMS_DO_NOT_MATCH); +COMPILE_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_X + texture::kFaceNegativeY == + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, NEGATIVE_Y_ENUMS_DO_NOT_MATCH); +COMPILE_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_X + texture::kFacePositiveZ == + GL_TEXTURE_CUBE_MAP_POSITIVE_Z, POSITIVE_Z_ENUMS_DO_NOT_MATCH); +COMPILE_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_X + texture::kFaceNegativeZ == + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, NEGATIVE_Z_ENUMS_DO_NOT_MATCH); + +bool TextureCubeGL::SetData(const Volume& volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + const void *data) { + if (level >= levels()) + return false; + MipLevelInfo mip_info; + MakeMipLevelInfo(&mip_info, format(), side_, side_, 1, level); + SetImageHelper helper; + if (!helper.Initialize(mip_info, volume, row_pitch, slice_pitch, size, data)) + return false; + + GLenum gl_internal_format = 0; + GLenum gl_format = 0; + GLenum gl_type = 0; + bool r = GetGLFormatType(format(), &gl_internal_format, &gl_format, &gl_type); + DCHECK(r); + glBindTexture(GL_TEXTURE_CUBE_MAP, gl_texture_); + GLenum face_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face; + if (gl_format) { + glTexSubImage2D(face_target, level, volume.x, volume.y, volume.width, + volume.height, gl_format, gl_type, helper.image_data()); + } else { + glCompressedTexSubImage2D(face_target, level, volume.x, volume.y, + volume.width, volume.height, gl_internal_format, + helper.image_size(), helper.image_data()); + } + return true; +} + +bool TextureCubeGL::GetData(const Volume& volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + void *data) { + if (level >= levels()) + return false; + MipLevelInfo mip_info; + MakeMipLevelInfo(&mip_info, format(), side_, side_, 1, level); + GetImageHelper helper; + if (!helper.Initialize(mip_info, volume, row_pitch, slice_pitch, size, data)) + return false; + + GLenum gl_internal_format = 0; + GLenum gl_format = 0; + GLenum gl_type = 0; + bool r = GetGLFormatType(format(), &gl_internal_format, &gl_format, &gl_type); + DCHECK(r); + glBindTexture(GL_TEXTURE_CUBE_MAP, gl_texture_); + GLenum face_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face; + if (gl_format) { + glGetTexImage(face_target, level, gl_format, gl_type, + helper.image_data()); + } else { + glGetCompressedTexImage(face_target, level, helper.image_data()); + } + + helper.Finalize(); + return true; +} + +bool TextureCubeGL::CreateRenderSurface(int width, + int height, + int mip_level, + int side) { + return false; +} + +bool TextureCubeGL::InstallFrameBufferObjects( + RenderSurfaceGL *gl_surface) { + ::glFramebufferTexture2DEXT( + GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, + gl_surface->side(), + gl_texture_, + gl_surface->mip_level()); + + GLenum framebuffer_status = ::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + if (GL_FRAMEBUFFER_COMPLETE_EXT != framebuffer_status) { + return false; + } + + return true; +} + + +// Destroys a texture resource. +parse_error::ParseError GAPIGL::DestroyTexture(ResourceId id) { + // Dirty effect, because this texture id may be used. + DirtyEffect(); + return textures_.Destroy(id) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +// Creates a 2D texture resource. +parse_error::ParseError GAPIGL::CreateTexture2D( + ResourceId id, + unsigned int width, + unsigned int height, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces) { + Texture2DGL *texture = Texture2DGL::Create( + width, height, levels, format, flags, enable_render_surfaces); + if (!texture) return parse_error::kParseInvalidArguments; + // Dirty effect, because this texture id may be used. + DirtyEffect(); + textures_.Assign(id, texture); + return parse_error::kParseNoError; +} + +// Creates a 3D texture resource. +parse_error::ParseError GAPIGL::CreateTexture3D( + ResourceId id, + unsigned int width, + unsigned int height, + unsigned int depth, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces) { + Texture3DGL *texture = Texture3DGL::Create( + width, height, depth, levels, format, flags, enable_render_surfaces); + if (!texture) return parse_error::kParseInvalidArguments; + // Dirty effect, because this texture id may be used. + DirtyEffect(); + textures_.Assign(id, texture); + return parse_error::kParseNoError; +} + +// Creates a cube map texture resource. +parse_error::ParseError GAPIGL::CreateTextureCube( + ResourceId id, + unsigned int side, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces) { + TextureCubeGL *texture = TextureCubeGL::Create( + side, levels, format, flags, enable_render_surfaces); + if (!texture) return parse_error::kParseInvalidArguments; + // Dirty effect, because this texture id may be used. + DirtyEffect(); + textures_.Assign(id, texture); + return parse_error::kParseNoError; +} + +// Copies the data into a texture resource. +parse_error::ParseError GAPIGL::SetTextureData( + ResourceId id, + unsigned int x, + unsigned int y, + unsigned int z, + unsigned int width, + unsigned int height, + unsigned int depth, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + const void *data) { + TextureGL *texture = textures_.Get(id); + if (!texture) + return parse_error::kParseInvalidArguments; + Volume volume = {x, y, z, width, height, depth}; + // Dirty effect: SetData may need to call glBindTexture which will mess up the + // sampler parameters. + DirtyEffect(); + return texture->SetData(volume, level, face, row_pitch, slice_pitch, + size, data) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +// Copies the data from a texture resource. +parse_error::ParseError GAPIGL::GetTextureData( + ResourceId id, + unsigned int x, + unsigned int y, + unsigned int z, + unsigned int width, + unsigned int height, + unsigned int depth, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + void *data) { + TextureGL *texture = textures_.Get(id); + if (!texture) + return parse_error::kParseInvalidArguments; + Volume volume = {x, y, z, width, height, depth}; + // Dirty effect: GetData may need to call glBindTexture which will mess up the + // sampler parameters. + DirtyEffect(); + return texture->GetData(volume, level, face, row_pitch, slice_pitch, + size, data) ? + parse_error::kParseNoError : + parse_error::kParseInvalidArguments; +} + +} // namespace o3d +} // namespace command_buffer diff --git a/o3d/command_buffer/service/texture_gl.h b/o3d/command_buffer/service/texture_gl.h new file mode 100644 index 0000000..9037eb7 --- /dev/null +++ b/o3d/command_buffer/service/texture_gl.h @@ -0,0 +1,284 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file declares the TextureGL, Texture2DGL, Texture3DGL and TextureCubeGL +// classes. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_GL_TEXTURE_GL_H_ +#define GPU_COMMAND_BUFFER_SERVICE_CROSS_GL_TEXTURE_GL_H_ + +#include "command_buffer/common/gapi_interface.h" +#include "command_buffer/service/gl_utils.h" +#include "command_buffer/service/resource.h" +#include "command_buffer/service/texture_utils.h" + +namespace command_buffer { +namespace o3d { + +class RenderDepthStencilSurfaceGL; +class RenderSurfaceGL; + +// The base class for a GL texture resource, providing access to the base GL +// texture that can be assigned to an effect parameter or a sampler unit. +class TextureGL : public Texture { + public: + TextureGL(texture::Type type, + unsigned int levels, + texture::Format format, + bool enable_render_surfaces, + unsigned int flags, + GLuint gl_texture) + : Texture(type, levels, format, enable_render_surfaces, flags), + gl_texture_(gl_texture) {} + virtual ~TextureGL(); + + // Gets the GL texture object. + GLuint gl_texture() const { return gl_texture_; } + + // Sets data into a texture resource. + virtual bool SetData(const Volume& volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + const void *data) = 0; + + // Gets data from a texture resource. + virtual bool GetData(const Volume& volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + void *data) = 0; + + // Creates the render surface, returning false if unable to. + virtual bool CreateRenderSurface(int width, + int height, + int mip_level, + int side) = 0; + + virtual bool InstallFrameBufferObjects( + RenderSurfaceGL *gl_surface) = 0; + + protected: + const GLuint gl_texture_; + + private: + DISALLOW_COPY_AND_ASSIGN(TextureGL); +}; + +// A 2D texture resource for GL. +class Texture2DGL : public TextureGL { + public: + Texture2DGL(unsigned int levels, + texture::Format format, + bool enable_render_surfaces, + unsigned int flags, + unsigned int width, + unsigned int height, + GLuint gl_texture) + : TextureGL(texture::kTexture2d, + levels, + format, + enable_render_surfaces, + flags, + gl_texture), + width_(width), + height_(height) {} + + // Creates a 2D texture resource. + static Texture2DGL *Create(unsigned int width, + unsigned int height, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces); + + // Sets data into a 2D texture resource. + virtual bool SetData(const Volume& volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + const void *data); + + // Gets data from a 2D texture resource. + virtual bool GetData(const Volume& volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + void *data); + + // Create a render surface which matches this texture type. + virtual bool CreateRenderSurface(int width, + int height, + int mip_level, + int side); + + virtual bool InstallFrameBufferObjects( + RenderSurfaceGL *gl_surface); + + private: + unsigned int width_; + unsigned int height_; + DISALLOW_COPY_AND_ASSIGN(Texture2DGL); +}; + +// A 3D texture resource for GL. +class Texture3DGL : public TextureGL { + public: + Texture3DGL(unsigned int levels, + texture::Format format, + bool enable_render_surfaces, + unsigned int flags, + unsigned int width, + unsigned int height, + unsigned int depth, + GLuint gl_texture) + : TextureGL(texture::kTexture3d, + levels, + format, + enable_render_surfaces, + flags, + gl_texture), + width_(width), + height_(height), + depth_(depth) {} + + // Creates a 3D texture resource. + static Texture3DGL *Create(unsigned int width, + unsigned int height, + unsigned int depth, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces); + + // Sets data into a 3D texture resource. + virtual bool SetData(const Volume& volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + const void *data); + + // Gets data from a 3D texture resource. + virtual bool GetData(const Volume& volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + void *data); + + // Create a render surface which matches this texture type. + virtual bool CreateRenderSurface(int width, + int height, + int mip_level, + int side); + + virtual bool InstallFrameBufferObjects( + RenderSurfaceGL *gl_surface); + + private: + unsigned int width_; + unsigned int height_; + unsigned int depth_; + DISALLOW_COPY_AND_ASSIGN(Texture3DGL); +}; + +// A cube map texture resource for GL. +class TextureCubeGL : public TextureGL { + public: + TextureCubeGL(unsigned int levels, + texture::Format format, + bool render_surface_enabled, + unsigned int flags, + unsigned int side, + GLuint gl_texture) + : TextureGL(texture::kTextureCube, + levels, + format, + render_surface_enabled, + flags, + gl_texture), + side_(side) {} + + // Creates a cube map texture resource. + static TextureCubeGL *Create(unsigned int side, + unsigned int levels, + texture::Format format, + unsigned int flags, + bool enable_render_surfaces); + + // Sets data into a cube map texture resource. + virtual bool SetData(const Volume& volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + const void *data); + + // Gets data from a cube map texture resource. + virtual bool GetData(const Volume& volume, + unsigned int level, + texture::Face face, + unsigned int row_pitch, + unsigned int slice_pitch, + unsigned int size, + void *data); + + // Create a render surface which matches this texture type. + virtual bool CreateRenderSurface(int width, + int height, + int mip_level, + int side); + + virtual bool InstallFrameBufferObjects( + RenderSurfaceGL *gl_surface); + + private: + unsigned int side_; + DISALLOW_COPY_AND_ASSIGN(TextureCubeGL); +}; + +} // namespace o3d +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_GL_TEXTURE_GL_H_ diff --git a/o3d/command_buffer/service/texture_utils.cc b/o3d/command_buffer/service/texture_utils.cc new file mode 100644 index 0000000..d1d26dd --- /dev/null +++ b/o3d/command_buffer/service/texture_utils.cc @@ -0,0 +1,102 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the implementation of some utilities for textures. + +#include +#include "command_buffer/service/texture_utils.h" + +namespace command_buffer { + +void MakeTransferInfo(TransferInfo *transfer_info, + const MipLevelInfo &mip_level, + const Volume &volume, + unsigned int row_pitch, + unsigned int slice_pitch) { + transfer_info->row_pitch = row_pitch; + transfer_info->slice_pitch = slice_pitch; + transfer_info->row_size = + volume.width / mip_level.block_size_x * mip_level.block_bpp; + transfer_info->slice_size = transfer_info->row_size + + (volume.height / mip_level.block_size_y - 1) * row_pitch; + transfer_info->total_size = transfer_info->slice_size + + (volume.depth - 1) * slice_pitch; + transfer_info->packed = (transfer_info->row_size == row_pitch) && + (volume.depth == 1 || transfer_info->slice_size == slice_pitch); +} + +void MakePackedTransferInfo(TransferInfo *transfer_info, + const MipLevelInfo &mip_level, + const Volume &volume) { + transfer_info->row_size = + volume.width / mip_level.block_size_x * mip_level.block_bpp; + transfer_info->row_pitch = transfer_info->row_size; + transfer_info->slice_size = + volume.height / mip_level.block_size_y * transfer_info->row_pitch; + transfer_info->slice_pitch = transfer_info->slice_size; + transfer_info->total_size = volume.depth * transfer_info->slice_pitch; + transfer_info->packed = true; +} + +// Transfers a volume of texels. +void TransferVolume(const Volume &volume, + const MipLevelInfo &mip_level, + const TransferInfo &dst_transfer_info, + void *dst_data, + const TransferInfo &src_transfer_info, + const void *src_data) { + DCHECK_EQ(src_transfer_info.row_size, dst_transfer_info.row_size); + if (src_transfer_info.packed && dst_transfer_info.packed) { + // fast path + DCHECK_EQ(src_transfer_info.total_size, dst_transfer_info.total_size); + DCHECK_EQ(src_transfer_info.row_pitch, dst_transfer_info.row_pitch); + DCHECK_EQ(src_transfer_info.slice_pitch, dst_transfer_info.slice_pitch); + memcpy(dst_data, src_data, src_transfer_info.total_size); + } else { + const char *src = static_cast(src_data); + char *dst = static_cast(dst_data); + for (unsigned int slice = 0; slice < volume.depth; ++slice) { + const char *row_src = src; + char *row_dst = dst; + for (unsigned int row = 0; row < volume.height; + row += mip_level.block_size_y) { + memcpy(row_dst, row_src, src_transfer_info.row_size); + row_src += src_transfer_info.row_pitch; + row_dst += dst_transfer_info.row_pitch; + } + src += src_transfer_info.slice_pitch; + dst += dst_transfer_info.slice_pitch; + } + } +} + +} // namespace command_buffer diff --git a/o3d/command_buffer/service/texture_utils.h b/o3d/command_buffer/service/texture_utils.h new file mode 100644 index 0000000..427e06c --- /dev/null +++ b/o3d/command_buffer/service/texture_utils.h @@ -0,0 +1,156 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file declares some utilities for textures, in particular to deal with +// in-memory texture data and layout. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_TEXTURE_UTILS_H_ +#define GPU_COMMAND_BUFFER_SERVICE_CROSS_TEXTURE_UTILS_H_ + +#include "command_buffer/common/logging.h" +#include "command_buffer/common/resource.h" + +namespace command_buffer { + +// Structure describing a volume of pixels. +struct Volume { + unsigned int x; + unsigned int y; + unsigned int z; + unsigned int width; + unsigned int height; + unsigned int depth; +}; + +// Structure describing the dimensions and structure of a mip level. +struct MipLevelInfo { + unsigned int block_bpp; + unsigned int block_size_x; + unsigned int block_size_y; + unsigned int width; + unsigned int height; + unsigned int depth; +}; + +// Structure describing a memory layout for transfers. +struct TransferInfo { + unsigned int row_size; // size in bytes of a row of blocks. + unsigned int row_pitch; // number of bytes between 2 successive rows. + unsigned int slice_size; // size in bytes of a slice of data. + unsigned int slice_pitch; // number of bytes between 2 successive slices. + unsigned int total_size; // total size of the data. + bool packed; // indicates whether the data is tightly packed. +}; + +// Round a value up, so that it is divisible by the block size. +static inline unsigned int RoundToBlockSize(unsigned int base, + unsigned int block) { + DCHECK_GT(base, 0U); + DCHECK_GT(block, 0U); + return block + base - 1 - (base - 1) % block; +} + +// Fills a MipLevelInfo structure from the base texture dimensions. +static inline void MakeMipLevelInfo(MipLevelInfo *mip_info, + texture::Format format, + unsigned int base_width, + unsigned int base_height, + unsigned int base_depth, + unsigned int level) { + mip_info->block_bpp = texture::GetBytesPerBlock(format); + mip_info->block_size_x = texture::GetBlockSizeX(format); + mip_info->block_size_y = texture::GetBlockSizeY(format); + mip_info->width = RoundToBlockSize( + texture::GetMipMapDimension(base_width, level), mip_info->block_size_x); + mip_info->height = RoundToBlockSize( + texture::GetMipMapDimension(base_height, level), mip_info->block_size_y); + mip_info->depth = texture::GetMipMapDimension(base_depth, level); +} + +// Gets the size in bytes of a mip level. +static inline unsigned int GetMipLevelSize(const MipLevelInfo &mip_info) { + return mip_info.block_bpp * mip_info.width / mip_info.block_size_x * + mip_info.height / mip_info.block_size_y * mip_info.depth; +} + +// Checks that [x .. x+width] is contained in [0 .. mip_width], and that both x +// and width are divisible by block_size, and that width is positive. +static inline bool CheckDimension(unsigned int x, + unsigned int width, + unsigned int mip_width, + unsigned int block_size) { + return x < mip_width && x+width <= mip_width && x % block_size == 0 && + width % block_size == 0 && width > 0; +} + +// Checks that given volume fits into a mip level. +static inline bool CheckVolume(const MipLevelInfo &mip_info, + const Volume &volume) { + return CheckDimension(volume.x, volume.width, mip_info.width, + mip_info.block_size_x) && + CheckDimension(volume.y, volume.height, mip_info.height, + mip_info.block_size_y) && + CheckDimension(volume.z, volume.depth, mip_info.depth, 1); +} + +// Checks whether a volume fully maps a mip level. +static inline bool IsFullVolume(const MipLevelInfo &mip_info, + const Volume &volume) { + return (volume.x == 0) && (volume.y == 0) && (volume.z == 0) && + (volume.width == mip_info.width) && + (volume.height == mip_info.height) && + (volume.depth == mip_info.depth); +} + +// Makes a transfer info from a mip level, a volume and row/slice pitches. +void MakeTransferInfo(TransferInfo *transfer_info, + const MipLevelInfo &mip_level, + const Volume &volume, + unsigned int row_pitch, + unsigned int slice_pitch); + +// Makes a transfer info from a mip level and a volume, considering packed data. +void MakePackedTransferInfo(TransferInfo *transfer_info, + const MipLevelInfo &mip_level, + const Volume &volume); + +// Transfers a volume of texels. +void TransferVolume(const Volume &volume, + const MipLevelInfo &mip_level, + const TransferInfo &dst_transfer_info, + void *dst_data, + const TransferInfo &src_transfer_info, + const void *src_data); + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_TEXTURE_UTILS_H_ diff --git a/o3d/command_buffer/service/x_utils.cc b/o3d/command_buffer/service/x_utils.cc new file mode 100644 index 0000000..96e62db --- /dev/null +++ b/o3d/command_buffer/service/x_utils.cc @@ -0,0 +1,91 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This class implements the XWindowWrapper class. + +#include "command_buffer/common/cross/logging.h" +#include "command_buffer/service/linux/x_utils.h" + +namespace command_buffer { + +bool XWindowWrapper::Initialize() { + XWindowAttributes attributes; + XGetWindowAttributes(display_, window_, &attributes); + XVisualInfo visual_info_template; + visual_info_template.visualid = XVisualIDFromVisual(attributes.visual); + int visual_info_count = 0; + XVisualInfo *visual_info_list = XGetVisualInfo(display_, VisualIDMask, + &visual_info_template, + &visual_info_count); + DCHECK(visual_info_list); + DCHECK_GT(visual_info_count, 0); + context_ = 0; + for (int i = 0; i < visual_info_count; ++i) { + context_ = glXCreateContext(display_, visual_info_list + i, 0, + True); + if (context_) break; + } + XFree(visual_info_list); + if (!context_) { + DLOG(ERROR) << "Couldn't create GL context."; + return false; + } + return true; +} + +bool XWindowWrapper::MakeCurrent() { + if (glXMakeCurrent(display_, window_, context_) != True) { + glXDestroyContext(display_, context_); + context_ = 0; + DLOG(ERROR) << "Couldn't make context current."; + return false; + } + return true; +} + +void XWindowWrapper::Destroy() { + Bool result = glXMakeCurrent(display_, 0, 0); + // glXMakeCurrent isn't supposed to fail when unsetting the context, unless + // we have pending draws on an invalid window - which shouldn't be the case + // here. + DCHECK(result); + if (context_) { + glXDestroyContext(display_, context_); + context_ = 0; + } +} + +void XWindowWrapper::SwapBuffers() { + glXSwapBuffers(display_, window_); +} + +} // namespace command_buffer diff --git a/o3d/command_buffer/service/x_utils.h b/o3d/command_buffer/service/x_utils.h new file mode 100644 index 0000000..a05cc35 --- /dev/null +++ b/o3d/command_buffer/service/x_utils.h @@ -0,0 +1,76 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file declares the XWindowWrapper class. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_LINUX_X_UTILS_H_ +#define GPU_COMMAND_BUFFER_SERVICE_LINUX_X_UTILS_H_ + +#include +#include "base/basictypes.h" +#include "command_buffer/common/cross/logging.h" + +namespace command_buffer { + +// This class is a wrapper around an X Window and associated GL context. It is +// useful to isolate intrusive X headers, since it can be forward declared +// (Window and GLXContext can't). +class XWindowWrapper { + public: + XWindowWrapper(Display *display, Window window) + : display_(display), + window_(window) { + DCHECK(display_); + DCHECK(window_); + } + // Initializes the GL context. + bool Initialize(); + + // Destroys the GL context. + void Destroy(); + + // Makes the GL context current on the current thread. + bool MakeCurrent(); + + // Swaps front and back buffers. + void SwapBuffers(); + + private: + Display *display_; + Window window_; + GLXContext context_; + DISALLOW_COPY_AND_ASSIGN(XWindowWrapper); +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_LINUX_X_UTILS_H_ diff --git a/o3d/core/core.gyp b/o3d/core/core.gyp index 1f3afa8..cd2a8d9 100644 --- a/o3d/core/core.gyp +++ b/o3d/core/core.gyp @@ -398,8 +398,8 @@ ['renderer == "cb"', { 'dependencies': [ - '../gpu/gpu.gyp:command_buffer_client', - '../gpu/gpu.gyp:np_utils', + '../command_buffer/command_buffer.gyp:command_buffer_client', + '../gpu_plugin/gpu_plugin.gyp:np_utils', ], 'sources': [ 'cross/command_buffer/buffer_cb.cc', @@ -430,11 +430,11 @@ ['renderer == "cb" and cb_service != "remote"', { 'dependencies': [ - '../gpu/gpu.gyp:command_buffer_service', + '../command_buffer/command_buffer.gyp:command_buffer_service', # These dependencies are only needed for RendererCBLocal. They can # be removed when RendererCBLocal is not needed. - '../gpu/gpu.gyp:command_buffer', + '../gpu_plugin/gpu_plugin.gyp:command_buffer', ], }, ], diff --git a/o3d/core/cross/command_buffer/buffer_cb.cc b/o3d/core/cross/command_buffer/buffer_cb.cc index 301dfa7..d2ee8dc 100644 --- a/o3d/core/cross/command_buffer/buffer_cb.cc +++ b/o3d/core/cross/command_buffer/buffer_cb.cc @@ -34,8 +34,8 @@ #include "core/cross/precompile.h" #include "core/cross/command_buffer/buffer_cb.h" -#include "gpu/command_buffer/client/o3d_cmd_helper.h" -#include "gpu/command_buffer/client/fenced_allocator.h" +#include "command_buffer/client/o3d_cmd_helper.h" +#include "command_buffer/client/fenced_allocator.h" namespace o3d { using command_buffer::CommandBufferEntry; diff --git a/o3d/core/cross/command_buffer/display_window_cb.h b/o3d/core/cross/command_buffer/display_window_cb.h index 74486bf..06b494e 100644 --- a/o3d/core/cross/command_buffer/display_window_cb.h +++ b/o3d/core/cross/command_buffer/display_window_cb.h @@ -34,8 +34,8 @@ #define O3D_CORE_WIN_DISPLAY_WINDOW_CB_H_ #include "core/cross/display_window.h" -#include "gpu/gpu_plugin/command_buffer.h" -#include "gpu/np_utils/np_object_pointer.h" +#include "gpu_plugin/command_buffer.h" +#include "gpu_plugin/np_utils/np_object_pointer.h" namespace o3d { diff --git a/o3d/core/cross/command_buffer/effect_cb.cc b/o3d/core/cross/command_buffer/effect_cb.cc index 9e860dd..a3b5e66 100644 --- a/o3d/core/cross/command_buffer/effect_cb.cc +++ b/o3d/core/cross/command_buffer/effect_cb.cc @@ -37,10 +37,10 @@ #include "core/cross/semantic_manager.h" #include "core/cross/service_locator.h" #include "core/cross/command_buffer/effect_cb.h" -#include "gpu/command_buffer/common/constants.h" -#include "gpu/command_buffer/common/o3d_cmd_format.h" -#include "gpu/command_buffer/client/fenced_allocator.h" -#include "gpu/command_buffer/client/o3d_cmd_helper.h" +#include "command_buffer/common/constants.h" +#include "command_buffer/common/o3d_cmd_format.h" +#include "command_buffer/client/fenced_allocator.h" +#include "command_buffer/client/o3d_cmd_helper.h" namespace o3d { diff --git a/o3d/core/cross/command_buffer/effect_cb.h b/o3d/core/cross/command_buffer/effect_cb.h index 21b4d7c..d193b55 100644 --- a/o3d/core/cross/command_buffer/effect_cb.h +++ b/o3d/core/cross/command_buffer/effect_cb.h @@ -38,7 +38,7 @@ #include #include "core/cross/effect.h" #include "core/cross/command_buffer/renderer_cb.h" -#include "gpu/command_buffer/client/effect_helper.h" +#include "command_buffer/client/effect_helper.h" namespace o3d { diff --git a/o3d/core/cross/command_buffer/param_cache_cb.cc b/o3d/core/cross/command_buffer/param_cache_cb.cc index 5c5f64e..b850ffb 100644 --- a/o3d/core/cross/command_buffer/param_cache_cb.cc +++ b/o3d/core/cross/command_buffer/param_cache_cb.cc @@ -39,8 +39,8 @@ #include "core/cross/command_buffer/effect_cb.h" #include "core/cross/command_buffer/param_cache_cb.h" #include "core/cross/command_buffer/sampler_cb.h" -#include "gpu/command_buffer/common/o3d_cmd_format.h" -#include "gpu/command_buffer/client/o3d_cmd_helper.h" +#include "command_buffer/common/o3d_cmd_format.h" +#include "command_buffer/client/o3d_cmd_helper.h" namespace o3d { diff --git a/o3d/core/cross/command_buffer/primitive_cb.cc b/o3d/core/cross/command_buffer/primitive_cb.cc index f97039a..68d5bbc 100644 --- a/o3d/core/cross/command_buffer/primitive_cb.cc +++ b/o3d/core/cross/command_buffer/primitive_cb.cc @@ -40,8 +40,8 @@ #include "core/cross/command_buffer/effect_cb.h" #include "core/cross/command_buffer/stream_bank_cb.h" #include "core/cross/error.h" -#include "gpu/command_buffer/common/gapi_interface.h" -#include "gpu/command_buffer/client/o3d_cmd_helper.h" +#include "command_buffer/common/gapi_interface.h" +#include "command_buffer/client/o3d_cmd_helper.h" // TODO: add unit tests. diff --git a/o3d/core/cross/command_buffer/primitive_cb.h b/o3d/core/cross/command_buffer/primitive_cb.h index 955150c..3484a1d 100644 --- a/o3d/core/cross/command_buffer/primitive_cb.h +++ b/o3d/core/cross/command_buffer/primitive_cb.h @@ -37,7 +37,7 @@ #include "core/cross/precompile.h" #include "core/cross/primitive.h" -#include "gpu/command_buffer/common/resource.h" +#include "command_buffer/common/resource.h" namespace o3d { diff --git a/o3d/core/cross/command_buffer/render_surface_cb.cc b/o3d/core/cross/command_buffer/render_surface_cb.cc index 83ebce4..773f07c 100644 --- a/o3d/core/cross/command_buffer/render_surface_cb.cc +++ b/o3d/core/cross/command_buffer/render_surface_cb.cc @@ -31,7 +31,7 @@ #include "core/cross/command_buffer/render_surface_cb.h" -#include "gpu/command_buffer/client/o3d_cmd_helper.h" +#include "command_buffer/client/o3d_cmd_helper.h" namespace o3d { diff --git a/o3d/core/cross/command_buffer/render_surface_cb.h b/o3d/core/cross/command_buffer/render_surface_cb.h index 3028b6f..81dccb8 100644 --- a/o3d/core/cross/command_buffer/render_surface_cb.h +++ b/o3d/core/cross/command_buffer/render_surface_cb.h @@ -38,7 +38,7 @@ #include "core/cross/render_surface.h" #include "core/cross/command_buffer/renderer_cb.h" -#include "gpu/command_buffer/common/resource.h" +#include "command_buffer/common/resource.h" namespace o3d { diff --git a/o3d/core/cross/command_buffer/renderer_cb.cc b/o3d/core/cross/command_buffer/renderer_cb.cc index a6a07d8..f4bb89d 100644 --- a/o3d/core/cross/command_buffer/renderer_cb.cc +++ b/o3d/core/cross/command_buffer/renderer_cb.cc @@ -34,9 +34,9 @@ #include "core/cross/precompile.h" -#include "gpu/command_buffer/client/o3d_cmd_helper.h" -#include "gpu/command_buffer/client/fenced_allocator.h" -#include "gpu/command_buffer/common/gapi_interface.h" +#include "command_buffer/client/o3d_cmd_helper.h" +#include "command_buffer/client/fenced_allocator.h" +#include "command_buffer/common/gapi_interface.h" #include "core/cross/command_buffer/buffer_cb.h" #include "core/cross/command_buffer/effect_cb.h" #include "core/cross/command_buffer/param_cache_cb.h" @@ -49,13 +49,13 @@ #include "core/cross/command_buffer/texture_cb.h" #include "core/cross/command_buffer/display_window_cb.h" #include "core/cross/renderer_platform.h" -#include "gpu/gpu_plugin/command_buffer.h" -#include "gpu/gpu_plugin/gpu_processor.h" -#include "gpu/np_utils/np_browser.h" -#include "gpu/np_utils/np_utils.h" +#include "gpu_plugin/command_buffer.h" +#include "gpu_plugin/gpu_processor.h" +#include "gpu_plugin/np_utils/np_browser.h" +#include "gpu_plugin/np_utils/np_utils.h" #if !defined(CB_SERVICE_REMOTE) -#include "gpu/gpu_plugin/gpu_processor.h" +#include "gpu_plugin/gpu_processor.h" #endif namespace o3d { diff --git a/o3d/core/cross/command_buffer/renderer_cb.h b/o3d/core/cross/command_buffer/renderer_cb.h index 9168bb5..a424922 100644 --- a/o3d/core/cross/command_buffer/renderer_cb.h +++ b/o3d/core/cross/command_buffer/renderer_cb.h @@ -39,12 +39,12 @@ #include "core/cross/precompile.h" #include #include "core/cross/renderer.h" -#include "gpu/command_buffer/common/constants.h" -#include "gpu/command_buffer/common/resource.h" -#include "gpu/command_buffer/client/fenced_allocator.h" -#include "gpu/command_buffer/client/id_allocator.h" -#include "gpu/gpu_plugin/command_buffer.h" -#include "gpu/np_utils/np_object_pointer.h" +#include "command_buffer/common/constants.h" +#include "command_buffer/common/resource.h" +#include "command_buffer/client/fenced_allocator.h" +#include "command_buffer/client/id_allocator.h" +#include "gpu_plugin/command_buffer.h" +#include "gpu_plugin/np_utils/np_object_pointer.h" namespace command_buffer { class O3DCmdHelper; diff --git a/o3d/core/cross/command_buffer/sampler_cb.cc b/o3d/core/cross/command_buffer/sampler_cb.cc index 887b9ad..32bccba 100644 --- a/o3d/core/cross/command_buffer/sampler_cb.cc +++ b/o3d/core/cross/command_buffer/sampler_cb.cc @@ -36,8 +36,8 @@ #include "core/cross/error.h" #include "core/cross/command_buffer/sampler_cb.h" #include "core/cross/command_buffer/renderer_cb.h" -#include "gpu/command_buffer/common/o3d_cmd_format.h" -#include "gpu/command_buffer/client/o3d_cmd_helper.h" +#include "command_buffer/common/o3d_cmd_format.h" +#include "command_buffer/client/o3d_cmd_helper.h" namespace o3d { diff --git a/o3d/core/cross/command_buffer/sampler_cb.h b/o3d/core/cross/command_buffer/sampler_cb.h index 25892d55..3543436 100644 --- a/o3d/core/cross/command_buffer/sampler_cb.h +++ b/o3d/core/cross/command_buffer/sampler_cb.h @@ -38,7 +38,7 @@ #include "core/cross/precompile.h" #include "core/cross/sampler.h" -#include "gpu/command_buffer/common/resource.h" +#include "command_buffer/common/resource.h" namespace o3d { diff --git a/o3d/core/cross/command_buffer/states_cb.cc b/o3d/core/cross/command_buffer/states_cb.cc index 8572827d..6903107 100644 --- a/o3d/core/cross/command_buffer/states_cb.cc +++ b/o3d/core/cross/command_buffer/states_cb.cc @@ -37,7 +37,7 @@ #include "core/cross/state.h" #include "core/cross/command_buffer/renderer_cb.h" #include "core/cross/command_buffer/states_cb.h" -#include "gpu/command_buffer/common/gapi_interface.h" +#include "command_buffer/common/gapi_interface.h" namespace o3d { using command_buffer::CommandBufferEntry; diff --git a/o3d/core/cross/command_buffer/states_cb.h b/o3d/core/cross/command_buffer/states_cb.h index 0732978..0b8e1cf 100644 --- a/o3d/core/cross/command_buffer/states_cb.h +++ b/o3d/core/cross/command_buffer/states_cb.h @@ -37,8 +37,8 @@ #define O3D_CORE_CROSS_COMMAND_BUFFER_STATES_CB_H_ #include "core/cross/command_buffer/renderer_cb.h" -#include "gpu/command_buffer/common/o3d_cmd_format.h" -#include "gpu/command_buffer/client/cmd_buffer_helper.h" +#include "command_buffer/common/o3d_cmd_format.h" +#include "command_buffer/client/cmd_buffer_helper.h" namespace o3d { diff --git a/o3d/core/cross/command_buffer/stream_bank_cb.cc b/o3d/core/cross/command_buffer/stream_bank_cb.cc index d7aebf4..c10e256 100644 --- a/o3d/core/cross/command_buffer/stream_bank_cb.cc +++ b/o3d/core/cross/command_buffer/stream_bank_cb.cc @@ -39,8 +39,8 @@ #include "core/cross/command_buffer/buffer_cb.h" #include "core/cross/command_buffer/effect_cb.h" #include "core/cross/command_buffer/stream_bank_cb.h" -#include "gpu/command_buffer/common/gapi_interface.h" -#include "gpu/command_buffer/client/o3d_cmd_helper.h" +#include "command_buffer/common/gapi_interface.h" +#include "command_buffer/client/o3d_cmd_helper.h" // TODO: add unit tests. diff --git a/o3d/core/cross/command_buffer/stream_bank_cb.h b/o3d/core/cross/command_buffer/stream_bank_cb.h index 4f0656c..bef497e 100644 --- a/o3d/core/cross/command_buffer/stream_bank_cb.h +++ b/o3d/core/cross/command_buffer/stream_bank_cb.h @@ -37,7 +37,7 @@ #include "core/cross/precompile.h" #include "core/cross/stream_bank.h" -#include "gpu/command_buffer/common/resource.h" +#include "command_buffer/common/resource.h" namespace o3d { diff --git a/o3d/core/cross/command_buffer/texture_cb.cc b/o3d/core/cross/command_buffer/texture_cb.cc index 8793339..31c1c15 100644 --- a/o3d/core/cross/command_buffer/texture_cb.cc +++ b/o3d/core/cross/command_buffer/texture_cb.cc @@ -38,10 +38,10 @@ #include "core/cross/command_buffer/renderer_cb.h" #include "core/cross/command_buffer/texture_cb.h" -#include "gpu/command_buffer/common/o3d_cmd_format.h" -#include "gpu/command_buffer/common/resource.h" -#include "gpu/command_buffer/client/o3d_cmd_helper.h" -#include "gpu/command_buffer/client/fenced_allocator.h" +#include "command_buffer/common/o3d_cmd_format.h" +#include "command_buffer/common/resource.h" +#include "command_buffer/client/o3d_cmd_helper.h" +#include "command_buffer/client/fenced_allocator.h" namespace o3d { diff --git a/o3d/core/cross/command_buffer/texture_cb.h b/o3d/core/cross/command_buffer/texture_cb.h index 9e37023..6fd21da 100644 --- a/o3d/core/cross/command_buffer/texture_cb.h +++ b/o3d/core/cross/command_buffer/texture_cb.h @@ -39,7 +39,7 @@ #include "core/cross/bitmap.h" #include "core/cross/texture.h" #include "core/cross/types.h" -#include "gpu/command_buffer/common/resource.h" +#include "command_buffer/common/resource.h" #include "core/cross/command_buffer/render_surface_cb.h" namespace o3d { diff --git a/o3d/gpu/command_buffer/client/cmd_buffer_helper.cc b/o3d/gpu/command_buffer/client/cmd_buffer_helper.cc deleted file mode 100644 index e6a49d1..0000000 --- a/o3d/gpu/command_buffer/client/cmd_buffer_helper.cc +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the implementation of the command buffer helper class. - -#include "gpu/command_buffer/client/cmd_buffer_helper.h" -#include "gpu/np_utils/np_utils.h" - -namespace command_buffer { - -using gpu_plugin::CommandBuffer; -using gpu_plugin::NPBrowser; -using gpu_plugin::NPInvoke; -using gpu_plugin::NPObjectPointer; - -CommandBufferHelper::CommandBufferHelper( - NPP npp, - const NPObjectPointer& command_buffer) - : npp_(npp), - command_buffer_(command_buffer), - entries_(NULL), - entry_count_(0), - token_(0), - last_token_read_(-1), - get_(0), - put_(0) { -} - -bool CommandBufferHelper::Initialize() { - ring_buffer_ = command_buffer_->GetRingBuffer(); - if (!ring_buffer_) - return false; - - // Map the ring buffer into this process. - if (!ring_buffer_->Map(ring_buffer_->max_size())) - return false; - - entries_ = static_cast(ring_buffer_->memory()); - entry_count_ = command_buffer_->GetSize(); - get_ = command_buffer_->GetGetOffset(); - put_ = command_buffer_->GetPutOffset(); - last_token_read_ = command_buffer_->GetToken(); - - return true; -} - -CommandBufferHelper::~CommandBufferHelper() { -} - -bool CommandBufferHelper::Flush() { - get_ = command_buffer_->SyncOffsets(put_); - return !command_buffer_->GetErrorStatus(); -} - -// Calls Flush() and then waits until the buffer is empty. Break early if the -// error is set. -bool CommandBufferHelper::Finish() { - do { - // Do not loop forever if the flush fails, meaning the command buffer reader - // has shutdown). - if (!Flush()) - return false; - } while (put_ != get_); - - return true; -} - -// Inserts a new token into the command stream. It uses an increasing value -// scheme so that we don't lose tokens (a token has passed if the current token -// value is higher than that token). Calls Finish() if the token value wraps, -// which will be rare. -int32 CommandBufferHelper::InsertToken() { - // Increment token as 31-bit integer. Negative values are used to signal an - // error. - token_ = (token_ + 1) & 0x7FFFFFFF; - CommandBufferEntry args; - args.value_uint32 = token_; - const uint32 kSetToken = 1; // TODO(gman): add a common set of commands. - AddCommand(kSetToken, 1, &args); - if (token_ == 0) { - // we wrapped - Finish(); - last_token_read_ = command_buffer_->GetToken(); - DCHECK_EQ(token_, last_token_read_); - } - return token_; -} - -// Waits until the current token value is greater or equal to the value passed -// in argument. -void CommandBufferHelper::WaitForToken(int32 token) { - // Return immediately if corresponding InsertToken failed. - if (token < 0) - return; - if (last_token_read_ >= token) return; // fast path. - if (token > token_) return; // we wrapped - Flush(); - last_token_read_ = command_buffer_->GetToken(); - while (last_token_read_ < token) { - if (get_ == put_) { - LOG(FATAL) << "Empty command buffer while waiting on a token."; - return; - } - // Do not loop forever if the flush fails, meaning the command buffer reader - // has shutdown. - if (!Flush()) - return; - last_token_read_ = command_buffer_->GetToken(); - } -} - -// Waits for available entries, basically waiting until get >= put + count + 1. -// It actually waits for contiguous entries, so it may need to wrap the buffer -// around, adding noops. Thus this function may change the value of put_. -// The function will return early if an error occurs, in which case the -// available space may not be available. -void CommandBufferHelper::WaitForAvailableEntries(int32 count) { - CHECK(count < entry_count_); - if (put_ + count > entry_count_) { - // There's not enough room between the current put and the end of the - // buffer, so we need to wrap. We will add noops all the way to the end, - // but we need to make sure get wraps first, actually that get is 1 or - // more (since put will wrap to 0 after we add the noops). - DCHECK_LE(1, put_); - Flush(); - while (get_ > put_ || get_ == 0) { - // Do not loop forever if the flush fails, meaning the command buffer - // reader has shutdown. - if (!Flush()) - return; - } - // Add the noops. By convention, a noop is a command 0 with no args. - // TODO(apatrick): A noop can have a size. It would be better to add a - // single noop with a variable size. Watch out for size limit on - // individual commands. - CommandHeader header; - header.size = 1; - header.command = 0; - while (put_ < entry_count_) { - entries_[put_++].value_header = header; - } - put_ = 0; - } - // If we have enough room, return immediatly. - if (count <= AvailableEntries()) return; - // Otherwise flush, and wait until we do have enough room. - Flush(); - while (AvailableEntries() < count) { - // Do not loop forever if the flush fails, meaning the command buffer reader - // has shutdown. - if (!Flush()) - return; - } -} - -CommandBufferEntry* CommandBufferHelper::GetSpace(uint32 entries) { - WaitForAvailableEntries(entries); - CommandBufferEntry* space = &entries_[put_]; - put_ += entries; - return space; -} - -parse_error::ParseError CommandBufferHelper::GetParseError() { - int32 parse_error = command_buffer_->ResetParseError(); - return static_cast(parse_error); -} - -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/client/cmd_buffer_helper.h b/o3d/gpu/command_buffer/client/cmd_buffer_helper.h deleted file mode 100644 index d63a53e..0000000 --- a/o3d/gpu/command_buffer/client/cmd_buffer_helper.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the command buffer helper class. - -#ifndef GPU_COMMAND_BUFFER_CLIENT_CROSS_CMD_BUFFER_HELPER_H_ -#define GPU_COMMAND_BUFFER_CLIENT_CROSS_CMD_BUFFER_HELPER_H_ - -#include "gpu/command_buffer/common/logging.h" -#include "gpu/command_buffer/common/constants.h" -#include "gpu/command_buffer/common/cmd_buffer_common.h" -#include "gpu/gpu_plugin/command_buffer.h" -#include "gpu/np_utils/np_object_pointer.h" - -namespace command_buffer { - -// Command buffer helper class. This class simplifies ring buffer management: -// it will allocate the buffer, give it to the buffer interface, and let the -// user add commands to it, while taking care of the synchronization (put and -// get). It also provides a way to ensure commands have been executed, through -// the token mechanism: -// -// helper.AddCommand(...); -// helper.AddCommand(...); -// int32 token = helper.InsertToken(); -// helper.AddCommand(...); -// helper.AddCommand(...); -// [...] -// -// helper.WaitForToken(token); // this doesn't return until the first two -// // commands have been executed. -class CommandBufferHelper { - public: - CommandBufferHelper( - NPP npp, - const gpu_plugin::NPObjectPointer& - command_buffer); - virtual ~CommandBufferHelper(); - - bool Initialize(); - - // Flushes the commands, setting the put pointer to let the buffer interface - // know that new commands have been added. After a flush returns, the command - // buffer service is aware of all pending commands and it is guaranteed to - // have made some progress in processing them. Returns whether the flush was - // successful. The flush will fail if the command buffer service has - // disconnected. - bool Flush(); - - // Waits until all the commands have been executed. Returns whether it - // was successful. The function will fail if the command buffer service has - // disconnected. - bool Finish(); - - // Waits until a given number of available entries are available. - // Parameters: - // count: number of entries needed. This value must be at most - // the size of the buffer minus one. - void WaitForAvailableEntries(int32 count); - - // Adds a command data to the command buffer. This may wait until sufficient - // space is available. - // Parameters: - // entries: The command entries to add. - // count: The number of entries. - void AddCommandData(const CommandBufferEntry* entries, int32 count) { - WaitForAvailableEntries(count); - for (; count > 0; --count) { - entries_[put_++] = *entries++; - } - DCHECK_LE(put_, entry_count_); - if (put_ == entry_count_) put_ = 0; - } - - // A typed version of AddCommandData. - template - void AddTypedCmdData(const T& cmd) { - AddCommandData(reinterpret_cast(&cmd), - ComputeNumEntries(sizeof(cmd))); - } - - // Adds a command to the command buffer. This may wait until sufficient space - // is available. - // Parameters: - // command: the command index. - // arg_count: the number of arguments for the command. - // args: the arguments for the command (these are copied before the - // function returns). - void AddCommand(int32 command, - int32 arg_count, - const CommandBufferEntry *args) { - CommandHeader header; - header.size = arg_count + 1; - header.command = command; - WaitForAvailableEntries(header.size); - entries_[put_++].value_header = header; - for (int i = 0; i < arg_count; ++i) { - entries_[put_++] = args[i]; - } - DCHECK_LE(put_, entry_count_); - if (put_ == entry_count_) put_ = 0; - } - - // Inserts a new token into the command buffer. This token either has a value - // different from previously inserted tokens, or ensures that previously - // inserted tokens with that value have already passed through the command - // stream. - // Returns: - // the value of the new token or -1 if the command buffer reader has - // shutdown. - int32 InsertToken(); - - // Waits until the token of a particular value has passed through the command - // stream (i.e. commands inserted before that token have been executed). - // NOTE: This will call Flush if it needs to block. - // Parameters: - // the value of the token to wait for. - void WaitForToken(int32 token); - - // Waits for a certain amount of space to be available. Returns address - // of space. - CommandBufferEntry* GetSpace(uint32 entries); - - // Typed version of GetSpace. Gets enough room for the given type and returns - // a reference to it. - template - T& GetCmdSpace() { - COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed); - uint32 space_needed = ComputeNumEntries(sizeof(T)); - void* data = GetSpace(space_needed); - return *reinterpret_cast(data); - } - - // Typed version of GetSpace for immediate commands. - template - T& GetImmediateCmdSpace(size_t space) { - COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); - uint32 space_needed = ComputeNumEntries(sizeof(T) + space); - void* data = GetSpace(space_needed); - return *reinterpret_cast(data); - } - - parse_error::ParseError GetParseError(); - - // Common Commands - void Noop(uint32 skip_count) { - cmd::Noop& cmd = GetImmediateCmdSpace( - skip_count * sizeof(CommandBufferEntry)); - cmd.Init(skip_count); - } - - void SetToken(uint32 token) { - cmd::SetToken& cmd = GetCmdSpace(); - cmd.Init(token); - } - - - private: - // Waits until get changes, updating the value of get_. - void WaitForGetChange(); - - // Returns the number of available entries (they may not be contiguous). - int32 AvailableEntries() { - return (get_ - put_ - 1 + entry_count_) % entry_count_; - } - - NPP npp_; - gpu_plugin::NPObjectPointer command_buffer_; - ::base::SharedMemory* ring_buffer_; - CommandBufferEntry *entries_; - int32 entry_count_; - int32 token_; - int32 last_token_read_; - int32 get_; - int32 put_; - - friend class CommandBufferHelperTest; - DISALLOW_COPY_AND_ASSIGN(CommandBufferHelper); -}; - -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_CLIENT_CROSS_CMD_BUFFER_HELPER_H_ diff --git a/o3d/gpu/command_buffer/client/cmd_buffer_helper_test.cc b/o3d/gpu/command_buffer/client/cmd_buffer_helper_test.cc deleted file mode 100644 index b2f5bde..0000000 --- a/o3d/gpu/command_buffer/client/cmd_buffer_helper_test.cc +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// Tests for the Command Buffer Helper. - -#include "tests/common/win/testing_common.h" -#include "base/message_loop.h" -#include "gpu/command_buffer/client/cmd_buffer_helper.h" -#include "gpu/command_buffer/service/mocks.h" -#include "gpu/gpu_plugin/command_buffer.h" -#include "gpu/gpu_plugin/gpu_processor.h" -#include "gpu/np_utils/np_object_pointer.h" - -namespace command_buffer { - -using gpu_plugin::CommandBuffer; -using gpu_plugin::GPUProcessor; -using gpu_plugin::NPCreateObject; -using gpu_plugin::NPObjectPointer; -using testing::Return; -using testing::Mock; -using testing::Truly; -using testing::Sequence; -using testing::DoAll; -using testing::Invoke; -using testing::_; - -const int32 kNumCommandEntries = 10; -const int32 kCommandBufferSizeBytes = kNumCommandEntries * sizeof(int32); - -// Test fixture for CommandBufferHelper test - Creates a CommandBufferHelper, -// using a CommandBufferEngine with a mock AsyncAPIInterface for its interface -// (calling it directly, not through the RPC mechanism). -class CommandBufferHelperTest : public testing::Test { - protected: - virtual void SetUp() { - api_mock_.reset(new AsyncAPIMock); - // ignore noops in the mock - we don't want to inspect the internals of the - // helper. - EXPECT_CALL(*api_mock_, DoCommand(0, 0, _)) - .WillRepeatedly(Return(parse_error::kParseNoError)); - - ::base::SharedMemory* ring_buffer = new ::base::SharedMemory; - ring_buffer->Create(std::wstring(), false, false, kCommandBufferSizeBytes); - ring_buffer->Map(1024); - - command_buffer_ = NPCreateObject(NULL); - command_buffer_->Initialize(ring_buffer); - - parser_ = new command_buffer::CommandParser(ring_buffer->memory(), - kCommandBufferSizeBytes, - 0, - kCommandBufferSizeBytes, - 0, - api_mock_.get()); - - scoped_refptr gpu_processor(new GPUProcessor( - NULL, command_buffer_.Get(), NULL, NULL, parser_, 1)); - command_buffer_->SetPutOffsetChangeCallback(NewCallback( - gpu_processor.get(), &GPUProcessor::ProcessCommands)); - - api_mock_->set_engine(gpu_processor.get()); - - helper_.reset(new CommandBufferHelper(NULL, command_buffer_)); - helper_->Initialize(); - } - - virtual void TearDown() { - // If the GPUProcessor posts any tasks, this forces them to run. - MessageLoop::current()->RunAllPending(); - helper_.release(); - } - - // Adds a command to the buffer through the helper, while adding it as an - // expected call on the API mock. - void AddCommandWithExpect(parse_error::ParseError _return, - unsigned int command, - unsigned int arg_count, - CommandBufferEntry *args) { - helper_->AddCommand(command, arg_count, args); - EXPECT_CALL(*api_mock_, DoCommand(command, arg_count, - Truly(AsyncAPIMock::IsArgs(arg_count, args)))) - .InSequence(sequence_) - .WillOnce(Return(_return)); - } - - // Checks that the buffer from put to put+size is free in the parser. - void CheckFreeSpace(CommandBufferOffset put, unsigned int size) { - CommandBufferOffset parser_put = parser_->put(); - CommandBufferOffset parser_get = parser_->get(); - CommandBufferOffset limit = put + size; - if (parser_get > parser_put) { - // "busy" buffer wraps, so "free" buffer is between put (inclusive) and - // get (exclusive). - EXPECT_LE(parser_put, put); - EXPECT_GT(parser_get, limit); - } else { - // "busy" buffer does not wrap, so the "free" buffer is the top side (from - // put to the limit) and the bottom side (from 0 to get). - if (put >= parser_put) { - // we're on the top side, check we are below the limit. - EXPECT_GE(kNumCommandEntries, limit); - } else { - // we're on the bottom side, check we are below get. - EXPECT_GT(parser_get, limit); - } - } - } - - CommandBufferOffset get_helper_put() { return helper_->put_; } - - scoped_ptr api_mock_; - NPObjectPointer command_buffer_; - command_buffer::CommandParser* parser_; - scoped_ptr helper_; - Sequence sequence_; -}; - -// Checks that commands in the buffer are properly executed, and that the -// status/error stay valid. -TEST_F(CommandBufferHelperTest, TestCommandProcessing) { - // Check initial state of the engine - it should have been configured by the - // helper. - EXPECT_TRUE(parser_ != NULL); - EXPECT_FALSE(command_buffer_->GetErrorStatus()); - EXPECT_EQ(parse_error::kParseNoError, command_buffer_->ResetParseError()); - EXPECT_EQ(0u, command_buffer_->GetGetOffset()); - - // Add 3 commands through the helper - AddCommandWithExpect(parse_error::kParseNoError, 1, 0, NULL); - - CommandBufferEntry args1[2]; - args1[0].value_uint32 = 3; - args1[1].value_float = 4.f; - AddCommandWithExpect(parse_error::kParseNoError, 2, 2, args1); - - CommandBufferEntry args2[2]; - args2[0].value_uint32 = 5; - args2[1].value_float = 6.f; - AddCommandWithExpect(parse_error::kParseNoError, 3, 2, args2); - - helper_->Flush(); - // Check that the engine has work to do now. - EXPECT_FALSE(parser_->IsEmpty()); - - // Wait until it's done. - helper_->Finish(); - // Check that the engine has no more work to do. - EXPECT_TRUE(parser_->IsEmpty()); - - // Check that the commands did happen. - Mock::VerifyAndClearExpectations(api_mock_.get()); - - // Check the error status. - EXPECT_FALSE(command_buffer_->GetErrorStatus()); - EXPECT_EQ(parse_error::kParseNoError, command_buffer_->ResetParseError()); -} - -// Checks that commands in the buffer are properly executed when wrapping the -// buffer, and that the status/error stay valid. -TEST_F(CommandBufferHelperTest, TestCommandWrapping) { - // Add 5 commands of size 3 through the helper to make sure we do wrap. - CommandBufferEntry args1[2]; - args1[0].value_uint32 = 3; - args1[1].value_float = 4.f; - - for (unsigned int i = 0; i < 5; ++i) { - AddCommandWithExpect(parse_error::kParseNoError, i + 1, 2, args1); - } - - helper_->Finish(); - // Check that the commands did happen. - Mock::VerifyAndClearExpectations(api_mock_.get()); - - // Check the error status. - EXPECT_FALSE(command_buffer_->GetErrorStatus()); - EXPECT_EQ(parse_error::kParseNoError, command_buffer_->ResetParseError()); -} - - -// Checks that commands in the buffer are properly executed, even if they -// generate a recoverable error. Check that the error status is properly set, -// and reset when queried. -TEST_F(CommandBufferHelperTest, TestRecoverableError) { - CommandBufferEntry args[2]; - args[0].value_uint32 = 3; - args[1].value_float = 4.f; - - // Create a command buffer with 3 commands, 2 of them generating errors - AddCommandWithExpect(parse_error::kParseNoError, 1, 2, args); - AddCommandWithExpect(parse_error::kParseUnknownCommand, 2, 2, args); - AddCommandWithExpect(parse_error::kParseInvalidArguments, 3, 2, - args); - - helper_->Finish(); - // Check that the commands did happen. - Mock::VerifyAndClearExpectations(api_mock_.get()); - - // Check that the error status was set to the first error. - EXPECT_EQ(parse_error::kParseUnknownCommand, - command_buffer_->ResetParseError()); - // Check that the error status was reset after the query. - EXPECT_EQ(parse_error::kParseNoError, command_buffer_->ResetParseError()); -} - -// Checks that asking for available entries work, and that the parser -// effectively won't use that space. -TEST_F(CommandBufferHelperTest, TestAvailableEntries) { - CommandBufferEntry args[2]; - args[0].value_uint32 = 3; - args[1].value_float = 4.f; - - // Add 2 commands through the helper - 8 entries - AddCommandWithExpect(parse_error::kParseNoError, 1, 0, NULL); - AddCommandWithExpect(parse_error::kParseNoError, 2, 0, NULL); - AddCommandWithExpect(parse_error::kParseNoError, 3, 2, args); - AddCommandWithExpect(parse_error::kParseNoError, 4, 2, args); - - // Ask for 5 entries. - helper_->WaitForAvailableEntries(5); - - CommandBufferOffset put = get_helper_put(); - CheckFreeSpace(put, 5); - - // Add more commands. - AddCommandWithExpect(parse_error::kParseNoError, 5, 2, args); - - // Wait until everything is done done. - helper_->Finish(); - - // Check that the commands did happen. - Mock::VerifyAndClearExpectations(api_mock_.get()); - - // Check the error status. - EXPECT_FALSE(command_buffer_->GetErrorStatus()); - EXPECT_EQ(parse_error::kParseNoError, command_buffer_->ResetParseError()); -} - -// Checks that the InsertToken/WaitForToken work. -TEST_F(CommandBufferHelperTest, TestToken) { - CommandBufferEntry args[2]; - args[0].value_uint32 = 3; - args[1].value_float = 4.f; - - // Add a first command. - AddCommandWithExpect(parse_error::kParseNoError, 3, 2, args); - // keep track of the buffer position. - CommandBufferOffset command1_put = get_helper_put(); - int32 token = helper_->InsertToken(); - - EXPECT_CALL(*api_mock_.get(), DoCommand(cmd::kSetToken, 1, _)) - .WillOnce(DoAll(Invoke(api_mock_.get(), &AsyncAPIMock::SetToken), - Return(parse_error::kParseNoError))); - // Add another command. - AddCommandWithExpect(parse_error::kParseNoError, 4, 2, args); - helper_->WaitForToken(token); - // check that the get pointer is beyond the first command. - EXPECT_LE(command1_put, command_buffer_->GetGetOffset()); - helper_->Finish(); - - // Check that the commands did happen. - Mock::VerifyAndClearExpectations(api_mock_.get()); - - // Check the error status. - EXPECT_FALSE(command_buffer_->GetErrorStatus()); - EXPECT_EQ(parse_error::kParseNoError, command_buffer_->ResetParseError()); -} - -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/client/effect_helper.cc b/o3d/gpu/command_buffer/client/effect_helper.cc deleted file mode 100644 index f3daaae..0000000 --- a/o3d/gpu/command_buffer/client/effect_helper.cc +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file implements the EffectHelper class. - -#include "gpu/command_buffer/common/o3d_cmd_format.h" -#include "gpu/command_buffer/client/cmd_buffer_helper.h" -#include "gpu/command_buffer/client/effect_helper.h" -#include "gpu/command_buffer/client/fenced_allocator.h" -#include "gpu/command_buffer/client/id_allocator.h" - -// TODO: write a unit test. - -namespace command_buffer { - -bool EffectHelper::CreateEffectParameters(ResourceId effect_id, - std::vector *descs) { - using effect_param::Desc; - DCHECK_NE(effect_id, kInvalidResource); - DCHECK(descs); - descs->clear(); - - // Get the param count. - Uint32 *retval = shm_allocator_->AllocTyped(1); - helper_->GetParamCount(effect_id, sizeof(*retval), - shm_id_, shm_allocator_->GetOffset(retval)); - // Finish has to be called to get the result. - helper_->Finish(); - - // We could have failed if the effect_id is invalid. - if (helper_->GetParseError() != parse_error::kParseNoError) { - shm_allocator_->Free(retval); - return false; - } - unsigned int param_count = *retval; - - shm_allocator_->Free(retval); - unsigned int max_buffer_size = shm_allocator_->GetLargestFreeOrPendingSize(); - if (max_buffer_size < sizeof(Desc)) { // NOLINT - // Not enough memory to get at least 1 param desc. - return false; - } - descs->resize(param_count); - for (unsigned int i = 0; i < param_count; ++i) { - EffectParamDesc *desc = &((*descs)[i]); - desc->id = param_id_allocator_->AllocateID(); - helper_->CreateParam(desc->id, effect_id, i); - } - - // Read param descriptions in batches. We use as much shared memory as - // possible so that we only call Finish as little as possible. - unsigned int max_param_per_batch = - std::min(static_cast(param_count), - static_cast(max_buffer_size / sizeof(Desc))); // NOLINT - Desc *raw_descs = shm_allocator_->AllocTyped(max_param_per_batch); - DCHECK(raw_descs); - for (unsigned int i = 0; i < param_count; i += max_param_per_batch) { - unsigned int count = std::min(param_count - i, max_param_per_batch); - for (unsigned int j = 0 ; j < count; ++j) { - EffectParamDesc *desc = &((*descs)[i + j]); - Desc *raw_desc = raw_descs + j; - helper_->GetParamDesc(desc->id, sizeof(*raw_desc), - shm_id_, - shm_allocator_->GetOffset(raw_desc)); - } - // Finish to get the results. - helper_->Finish(); - DCHECK_EQ(helper_->GetParseError(), parse_error::kParseNoError); - for (unsigned int j = 0 ; j < count; ++j) { - EffectParamDesc *desc = &((*descs)[i + j]); - Desc *raw_desc = raw_descs + j; - desc->data_type = raw_desc->data_type; - desc->data_size = raw_desc->data_size; - desc->num_elements = raw_desc->num_elements; - desc->cmd_desc_size = raw_desc->size; - } - } - shm_allocator_->Free(raw_descs); - return true; -} - -bool EffectHelper::GetParamStrings(EffectParamDesc *desc) { - using effect_param::Desc; - DCHECK(desc); - DCHECK_NE(desc->id, kInvalidResource); - // desc may not have come directly from CreateEffectParameters, so it may be - // less than the minimum required size. - unsigned int size = std::max(static_cast(desc->cmd_desc_size), - static_cast(sizeof(Desc))); // NOLINT - Desc *raw_desc = static_cast(shm_allocator_->Alloc(size)); - if (!raw_desc) { - // Not enough memory to get the param desc. - return false; - } - helper_->GetParamDesc(desc->id, size, - shm_id_, - shm_allocator_->GetOffset(raw_desc)); - - // Finish to get the results. - helper_->Finish(); - - // We could have failed if the param ID is invalid. - if (helper_->GetParseError() != parse_error::kParseNoError) { - shm_allocator_->Free(raw_desc); - return false; - } - - if (raw_desc->size > size) { - // We had not allocated enough memory the first time (e.g. if the - // EffectParamDesc didn't come from CreateEffectParameters, so the user had - // no way of knowing what size was needed for the strings), so re-allocate - // and try again. - size = raw_desc->size; - desc->cmd_desc_size = size; - shm_allocator_->Free(raw_desc); - raw_desc = static_cast(shm_allocator_->Alloc(size)); - if (!raw_desc) { - // Not enough memory to get the param desc. - return false; - } - helper_->GetParamDesc(desc->id, size, - shm_id_, - shm_allocator_->GetOffset(raw_desc)); - // Finish to get the results. - helper_->Finish(); - DCHECK_EQ(helper_->GetParseError(), parse_error::kParseNoError); - DCHECK_EQ(raw_desc->size, size); - } - - const char *raw_desc_string = reinterpret_cast(raw_desc); - if (raw_desc->name_offset) { - DCHECK_LE(raw_desc->name_offset + raw_desc->name_size, raw_desc->size); - DCHECK_GT(raw_desc->name_size, 0U); - DCHECK_EQ(raw_desc_string[raw_desc->name_offset + raw_desc->name_size - 1], - 0); - desc->name = String(raw_desc_string + raw_desc->name_offset, - raw_desc->name_size - 1); - } else { - desc->name.clear(); - } - if (raw_desc->semantic_offset) { - DCHECK_LE(raw_desc->semantic_offset + raw_desc->semantic_size, - raw_desc->size); - DCHECK_GT(raw_desc->semantic_size, 0U); - DCHECK_EQ(raw_desc_string[raw_desc->semantic_offset + - raw_desc->semantic_size - 1], - 0); - desc->semantic = String(raw_desc_string + raw_desc->semantic_offset, - raw_desc->semantic_size - 1); - } else { - desc->semantic.clear(); - } - shm_allocator_->Free(raw_desc); - return true; -} - -void EffectHelper::DestroyEffectParameters( - const std::vector &descs) { - for (unsigned int i = 0; i < descs.size(); ++i) { - const EffectParamDesc &desc = descs[i]; - helper_->DestroyParam(desc.id); - param_id_allocator_->FreeID(desc.id); - } -} - -bool EffectHelper::GetEffectStreams(ResourceId effect_id, - std::vector *descs) { - using effect_stream::Desc; - DCHECK_NE(effect_id, kInvalidResource); - - // Get the param count. - Uint32 *retval = shm_allocator_->AllocTyped(1); - helper_->GetStreamCount(effect_id, sizeof(*retval), - shm_id_, - shm_allocator_->GetOffset(retval)); - // Finish has to be called to get the result. - helper_->Finish(); - - // We could have failed if the effect_id is invalid. - if (helper_->GetParseError() != parse_error::kParseNoError) { - shm_allocator_->Free(retval); - return false; - } - unsigned int stream_count = *retval; - shm_allocator_->Free(retval); - unsigned int max_buffer_size = shm_allocator_->GetLargestFreeOrPendingSize(); - if (max_buffer_size < sizeof(Desc)) { // NOLINT - // Not enough memory to get at least 1 stream desc. - return false; - } - descs->resize(stream_count); - - // Read stream descriptions in batches. We use as much shared memory as - // possible so that we only call Finish as little as possible. - unsigned int max_stream_per_batch = - std::min(static_cast(stream_count), - static_cast(max_buffer_size / sizeof(Desc))); // NOLINT - Desc *raw_descs = shm_allocator_->AllocTyped(max_stream_per_batch); - DCHECK(raw_descs); - for (unsigned int i = 0; i < stream_count; i += max_stream_per_batch) { - unsigned int count = std::min(stream_count - i, max_stream_per_batch); - for (unsigned int j = 0 ; j < count; ++j) { - Desc *raw_desc = raw_descs + j; - helper_->GetStreamDesc(effect_id, i + j, sizeof(*raw_desc), - shm_id_, - shm_allocator_->GetOffset(raw_desc)); - } - // Finish to get the results. - helper_->Finish(); - DCHECK_EQ(helper_->GetParseError(), parse_error::kParseNoError); - for (unsigned int j = 0 ; j < count; ++j) { - EffectStreamDesc *desc = &((*descs)[i + j]); - Desc *raw_desc = raw_descs + j; - desc->semantic = static_cast(raw_desc->semantic); - desc->semantic_index = raw_desc->semantic_index; - } - } - shm_allocator_->Free(raw_descs); - return true; -} -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/client/effect_helper.h b/o3d/gpu/command_buffer/client/effect_helper.h deleted file mode 100644 index dc11b24..0000000 --- a/o3d/gpu/command_buffer/client/effect_helper.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file defines the EffectHelper class. - -#ifndef GPU_COMMAND_BUFFER_CLIENT_CROSS_EFFECT_HELPER_H_ -#define GPU_COMMAND_BUFFER_CLIENT_CROSS_EFFECT_HELPER_H_ - -#include -#include "gpu/command_buffer/common/resource.h" -#include "gpu/command_buffer/client/o3d_cmd_helper.h" - -namespace command_buffer { - -class FencedAllocatorWrapper; -class IdAllocator; -class CommandBufferHelper; - -// A helper class to find parameters in an effect. -class EffectHelper { - public: - // A more usable version of effect_param::Desc - struct EffectParamDesc { - ResourceId id; // The resource ID for the param. - String name; // The name of the param. - String semantic; // The semantic of the param. - effect_param::DataType data_type; // The data type of a param. - unsigned int data_size; // The size of the data for a param. - int num_elements; // The number of array entries if the - // parameter is an array, 0 otherwise. - unsigned int cmd_desc_size; // The size of the effect_param::Desc - // structure (counting strings) for a - // param. - }; - struct EffectStreamDesc { - vertex_struct::Semantic semantic; // The semantic enum type. - unsigned int semantic_index; - }; - - EffectHelper(O3DCmdHelper *helper, - FencedAllocatorWrapper *shm_allocator, - unsigned int shm_id, - IdAllocator *param_id_allocator) - : helper_(helper), - shm_allocator_(shm_allocator), - shm_id_(shm_id), - param_id_allocator_(param_id_allocator) { - DCHECK(helper); - DCHECK(shm_allocator); - DCHECK(param_id_allocator); - } - - // Creates all the parameters in an effect and gets their descriptions. The - // strings will not be retrieved, so name and semantic will be empty. The - // cmd_desc_size field will be set to the proper size to be able to get the - // strings with a single command within GetParamStrings, so it should be left - // alone. - // - // The ResourceIDs will be allocated in the param_id_allocator. - // Temporary buffers will be allocated in the shm_allocator, but they will be - // freed before the function returns (possibly pending a token). At least - // sizeof(effect_param::Desc) must be available for this function to succeed. - // This function will call Finish(), hence will block. - // - // Parameters: - // effect_id: the ResourceId of the effect. - // descs: A pointer to a vector containing the returned descriptions. - // The pointed vector will be cleared. - // Returns: - // true if successful. Reasons for failure are: - // - invalid effect_id, - // - not enough memory in the shm_allocator_. - bool CreateEffectParameters(ResourceId effect_id, - std::vector *descs); - - // Gets the strings for a desc. This will fill in the values for the name and - // semantic fields. - // Temporary buffers will be allocated in the shm_allocator, but they will be - // freed before the function returns (possibly pending a token). At least - // desc.cmd_desc_size (as returned by CreateEffectParameters) must be - // available for this function to succeed. - // This function will call Finish(), hence will block. - // - // Parameters: - // desc: a pointer to the description for a parameter. The id field should - // be set to the ResourceId of the parameter. - // Returns: - // true if successful. Reasons for failure are: - // - invalid parameter ResourceId, - // - not enough memory in the shm_allocator_. - bool GetParamStrings(EffectParamDesc *desc); - - // Destroys all parameter resources referenced by the descriptions. The - // ResourceId will be freed from the param_id_allocator. - // Parameters: - // descs: the vector of descriptions containing the ResourceIDs of the - // parameters to destroy. - void DestroyEffectParameters(const std::vector &descs); - - // Gets all the input stream semantics and semantic indices in an - // array. These will be retrieved as many as possible at a time. At least - // sizeof(effect_param::Desc) must be available for this function to succeed. - // This function will call Finish(), hence will block. - // - // Parameters: - // effect_id: the ResourceId of the effect. - // descs: A pointer to a vector containing the returned descriptions. - // The pointed vector will be cleared. - // Returns: - // true if successful. Reasons for failure are: - // - invalid effect_id, - // - not enough memory in the shm_allocator_. - bool GetEffectStreams(ResourceId effect_id, - std::vector *descs); - - private: - O3DCmdHelper *helper_; - FencedAllocatorWrapper *shm_allocator_; - unsigned int shm_id_; - IdAllocator *param_id_allocator_; - - DISALLOW_COPY_AND_ASSIGN(EffectHelper); -}; - -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_CLIENT_CROSS_EFFECT_HELPER_H_ diff --git a/o3d/gpu/command_buffer/client/fenced_allocator.cc b/o3d/gpu/command_buffer/client/fenced_allocator.cc deleted file mode 100644 index 810feb5..0000000 --- a/o3d/gpu/command_buffer/client/fenced_allocator.cc +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the implementation of the FencedAllocator class. - -#include "gpu/command_buffer/client/fenced_allocator.h" -#include -#include "gpu/command_buffer/client/cmd_buffer_helper.h" - -namespace command_buffer { - -#ifndef COMPILER_MSVC -const FencedAllocator::Offset FencedAllocator::kInvalidOffset; -#endif - -FencedAllocator::~FencedAllocator() { - // Free blocks pending tokens. - for (unsigned int i = 0; i < blocks_.size(); ++i) { - if (blocks_[i].state == FREE_PENDING_TOKEN) { - i = WaitForTokenAndFreeBlock(i); - } - } - DCHECK_EQ(blocks_.size(), 1u); - DCHECK_EQ(blocks_[0].state, FREE); -} - -// Looks for a non-allocated block that is big enough. Search in the FREE -// blocks first (for direct usage), first-fit, then in the FREE_PENDING_TOKEN -// blocks, waiting for them. The current implementation isn't smart about -// optimizing what to wait for, just looks inside the block in order (first-fit -// as well). -FencedAllocator::Offset FencedAllocator::Alloc(unsigned int size) { - // Similarly to malloc, an allocation of 0 allocates at least 1 byte, to - // return different pointers every time. - if (size == 0) size = 1; - - // Try first to allocate in a free block. - for (unsigned int i = 0; i < blocks_.size(); ++i) { - Block &block = blocks_[i]; - if (block.state == FREE && block.size >= size) { - return AllocInBlock(i, size); - } - } - - // No free block is available. Look for blocks pending tokens, and wait for - // them to be re-usable. - for (unsigned int i = 0; i < blocks_.size(); ++i) { - if (blocks_[i].state != FREE_PENDING_TOKEN) - continue; - i = WaitForTokenAndFreeBlock(i); - if (blocks_[i].size >= size) - return AllocInBlock(i, size); - } - return kInvalidOffset; -} - -// Looks for the corresponding block, mark it FREE, and collapse it if -// necessary. -void FencedAllocator::Free(FencedAllocator::Offset offset) { - BlockIndex index = GetBlockByOffset(offset); - DCHECK_NE(blocks_[index].state, FREE); - blocks_[index].state = FREE; - CollapseFreeBlock(index); -} - -// Looks for the corresponding block, mark it FREE_PENDING_TOKEN. -void FencedAllocator::FreePendingToken(FencedAllocator::Offset offset, - unsigned int token) { - BlockIndex index = GetBlockByOffset(offset); - Block &block = blocks_[index]; - block.state = FREE_PENDING_TOKEN; - block.token = token; -} - -// Gets the max of the size of the blocks marked as free. -unsigned int FencedAllocator::GetLargestFreeSize() { - unsigned int max_size = 0; - for (unsigned int i = 0; i < blocks_.size(); ++i) { - Block &block = blocks_[i]; - if (block.state == FREE) - max_size = std::max(max_size, block.size); - } - return max_size; -} - -// Gets the size of the largest segment of blocks that are either FREE or -// FREE_PENDING_TOKEN. -unsigned int FencedAllocator::GetLargestFreeOrPendingSize() { - unsigned int max_size = 0; - unsigned int current_size = 0; - for (unsigned int i = 0; i < blocks_.size(); ++i) { - Block &block = blocks_[i]; - if (block.state == IN_USE) { - max_size = std::max(max_size, current_size); - current_size = 0; - } else { - DCHECK(block.state == FREE || block.state == FREE_PENDING_TOKEN); - current_size += block.size; - } - } - return std::max(max_size, current_size); -} - -// Makes sure that: -// - there is at least one block. -// - there are no contiguous FREE blocks (they should have been collapsed). -// - the successive offsets match the block sizes, and they are in order. -bool FencedAllocator::CheckConsistency() { - if (blocks_.size() < 1) return false; - for (unsigned int i = 0; i < blocks_.size() - 1; ++i) { - Block ¤t = blocks_[i]; - Block &next = blocks_[i + 1]; - // This test is NOT included in the next one, because offset is unsigned. - if (next.offset <= current.offset) - return false; - if (next.offset != current.offset + current.size) - return false; - if (current.state == FREE && next.state == FREE) - return false; - } - return true; -} - -// Collapse the block to the next one, then to the previous one. Provided the -// structure is consistent, those are the only blocks eligible for collapse. -FencedAllocator::BlockIndex FencedAllocator::CollapseFreeBlock( - BlockIndex index) { - if (index + 1 < blocks_.size()) { - Block &next = blocks_[index + 1]; - if (next.state == FREE) { - blocks_[index].size += next.size; - blocks_.erase(blocks_.begin() + index + 1); - } - } - if (index > 0) { - Block &prev = blocks_[index - 1]; - if (prev.state == FREE) { - prev.size += blocks_[index].size; - blocks_.erase(blocks_.begin() + index); - --index; - } - } - return index; -} - -// Waits for the block's token, then mark the block as free, then collapse it. -FencedAllocator::BlockIndex FencedAllocator::WaitForTokenAndFreeBlock( - BlockIndex index) { - Block &block = blocks_[index]; - DCHECK_EQ(block.state, FREE_PENDING_TOKEN); - helper_->WaitForToken(block.token); - block.state = FREE; - return CollapseFreeBlock(index); -} - -// If the block is exactly the requested size, simply mark it IN_USE, otherwise -// split it and mark the first one (of the requested size) IN_USE. -FencedAllocator::Offset FencedAllocator::AllocInBlock(BlockIndex index, - unsigned int size) { - Block &block = blocks_[index]; - DCHECK_GE(block.size, size); - DCHECK_EQ(block.state, FREE); - Offset offset = block.offset; - if (block.size == size) { - block.state = IN_USE; - return offset; - } - Block newblock = { FREE, offset + size, block.size - size, kUnusedToken}; - block.state = IN_USE; - block.size = size; - // this is the last thing being done because it may invalidate block; - blocks_.insert(blocks_.begin() + index + 1, newblock); - return offset; -} - -// The blocks are in offset order, so we can do a binary search. -FencedAllocator::BlockIndex FencedAllocator::GetBlockByOffset(Offset offset) { - Block templ = { IN_USE, offset, 0, kUnusedToken }; - Container::iterator it = std::lower_bound(blocks_.begin(), blocks_.end(), - templ, OffsetCmp()); - DCHECK(it != blocks_.end() && it->offset == offset); - return it-blocks_.begin(); -} - -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/client/fenced_allocator.h b/o3d/gpu/command_buffer/client/fenced_allocator.h deleted file mode 100644 index 72bba33..0000000 --- a/o3d/gpu/command_buffer/client/fenced_allocator.h +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the definition of the FencedAllocator class. - -#ifndef GPU_COMMAND_BUFFER_CLIENT_CROSS_FENCED_ALLOCATOR_H_ -#define GPU_COMMAND_BUFFER_CLIENT_CROSS_FENCED_ALLOCATOR_H_ - -#include -#include "base/basictypes.h" -#include "gpu/command_buffer/common/logging.h" - -namespace command_buffer { -class CommandBufferHelper; - -// FencedAllocator provides a mechanism to manage allocations within a fixed -// block of memory (storing the book-keeping externally). Furthermore this -// class allows to free data "pending" the passage of a command buffer token, -// that is, the memory won't be reused until the command buffer has processed -// that token. -// -// NOTE: Although this class is intended to be used in the command buffer -// environment which is multi-process, this class isn't "thread safe", because -// it isn't meant to be shared across modules. It is thread-compatible though -// (see http://www.corp.google.com/eng/doc/cpp_primer.html#thread_safety). -class FencedAllocator { - public: - typedef unsigned int Offset; - // Invalid offset, returned by Alloc in case of failure. - static const Offset kInvalidOffset = 0xffffffffU; - - // Creates a FencedAllocator. Note that the size of the buffer is passed, but - // not its base address: everything is handled as offsets into the buffer. - FencedAllocator(unsigned int size, - CommandBufferHelper *helper) - : helper_(helper) { - Block block = { FREE, 0, size, kUnusedToken }; - blocks_.push_back(block); - } - - ~FencedAllocator(); - - // Allocates a block of memory. If the buffer is out of directly available - // memory, this function may wait until memory that was freed "pending a - // token" can be re-used. - // - // Parameters: - // size: the size of the memory block to allocate. - // - // Returns: - // the offset of the allocated memory block, or kInvalidOffset if out of - // memory. - Offset Alloc(unsigned int size); - - // Frees a block of memory. - // - // Parameters: - // offset: the offset of the memory block to free. - void Free(Offset offset); - - // Frees a block of memory, pending the passage of a token. That memory won't - // be re-allocated until the token has passed through the command stream. - // - // Parameters: - // offset: the offset of the memory block to free. - // token: the token value to wait for before re-using the memory. - void FreePendingToken(Offset offset, unsigned int token); - - // Gets the size of the largest free block that is available without waiting. - unsigned int GetLargestFreeSize(); - - // Gets the size of the largest free block that can be allocated if the - // caller can wait. Allocating a block of this size will succeed, but may - // block. - unsigned int GetLargestFreeOrPendingSize(); - - // Checks for consistency inside the book-keeping structures. Used for - // testing. - bool CheckConsistency(); - - private: - // Status of a block of memory, for book-keeping. - enum State { - IN_USE, - FREE, - FREE_PENDING_TOKEN - }; - - // Book-keeping sturcture that describes a block of memory. - struct Block { - State state; - Offset offset; - unsigned int size; - unsigned int token; // token to wait for in the FREE_PENDING_TOKEN case. - }; - - // Comparison functor for memory block sorting. - class OffsetCmp { - public: - bool operator() (const Block &left, const Block &right) { - return left.offset < right.offset; - } - }; - - typedef std::vector Container; - typedef unsigned int BlockIndex; - - static const unsigned int kUnusedToken = 0; - - // Gets the index of a memory block, given its offset. - BlockIndex GetBlockByOffset(Offset offset); - - // Collapse a free block with its neighbours if they are free. Returns the - // index of the collapsed block. - // NOTE: this will invalidate block indices. - BlockIndex CollapseFreeBlock(BlockIndex index); - - // Waits for a FREE_PENDING_TOKEN block to be usable, and free it. Returns - // the new index of that block (since it may have been collapsed). - // NOTE: this will invalidate block indices. - BlockIndex WaitForTokenAndFreeBlock(BlockIndex index); - - // Allocates a block of memory inside a given block, splitting it in two - // (unless that block is of the exact requested size). - // NOTE: this will invalidate block indices. - // Returns the offset of the allocated block (NOTE: this is different from - // the other functions that return a block index). - Offset AllocInBlock(BlockIndex index, unsigned int size); - - command_buffer::CommandBufferHelper *helper_; - Container blocks_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(FencedAllocator); -}; - -// This class functions just like FencedAllocator, but its API uses pointers -// instead of offsets. -class FencedAllocatorWrapper { - public: - FencedAllocatorWrapper(unsigned int size, - CommandBufferHelper *helper, - void *base) - : allocator_(size, helper), - base_(base) { } - - // Allocates a block of memory. If the buffer is out of directly available - // memory, this function may wait until memory that was freed "pending a - // token" can be re-used. - // - // Parameters: - // size: the size of the memory block to allocate. - // - // Returns: - // the pointer to the allocated memory block, or NULL if out of - // memory. - void *Alloc(unsigned int size) { - FencedAllocator::Offset offset = allocator_.Alloc(size); - return GetPointer(offset); - } - - // Allocates a block of memory. If the buffer is out of directly available - // memory, this function may wait until memory that was freed "pending a - // token" can be re-used. - // This is a type-safe version of Alloc, returning a typed pointer. - // - // Parameters: - // count: the number of elements to allocate. - // - // Returns: - // the pointer to the allocated memory block, or NULL if out of - // memory. - template T *AllocTyped(unsigned int count) { - return static_cast(Alloc(count * sizeof(T))); - } - - // Frees a block of memory. - // - // Parameters: - // pointer: the pointer to the memory block to free. - void Free(void *pointer) { - DCHECK(pointer); - allocator_.Free(GetOffset(pointer)); - } - - // Frees a block of memory, pending the passage of a token. That memory won't - // be re-allocated until the token has passed through the command stream. - // - // Parameters: - // pointer: the pointer to the memory block to free. - // token: the token value to wait for before re-using the memory. - void FreePendingToken(void *pointer, unsigned int token) { - DCHECK(pointer); - allocator_.FreePendingToken(GetOffset(pointer), token); - } - - // Gets a pointer to a memory block given the base memory and the offset. - // It translates FencedAllocator::kInvalidOffset to NULL. - void *GetPointer(FencedAllocator::Offset offset) { - return (offset == FencedAllocator::kInvalidOffset) ? - NULL : static_cast(base_) + offset; - } - - // Gets the offset to a memory block given the base memory and the address. - // It translates NULL to FencedAllocator::kInvalidOffset. - FencedAllocator::Offset GetOffset(void *pointer) { - return pointer ? static_cast(pointer) - static_cast(base_) : - FencedAllocator::kInvalidOffset; - } - - // Gets the size of the largest free block that is available without waiting. - unsigned int GetLargestFreeSize() { - return allocator_.GetLargestFreeSize(); - } - - // Gets the size of the largest free block that can be allocated if the - // caller can wait. - unsigned int GetLargestFreeOrPendingSize() { - return allocator_.GetLargestFreeOrPendingSize(); - } - - // Checks for consistency inside the book-keeping structures. Used for - // testing. - bool CheckConsistency() { - return allocator_.CheckConsistency(); - } - - FencedAllocator &allocator() { return allocator_; } - - private: - FencedAllocator allocator_; - void *base_; - DISALLOW_IMPLICIT_CONSTRUCTORS(FencedAllocatorWrapper); -}; - -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_CLIENT_CROSS_FENCED_ALLOCATOR_H_ diff --git a/o3d/gpu/command_buffer/client/fenced_allocator_test.cc b/o3d/gpu/command_buffer/client/fenced_allocator_test.cc deleted file mode 100644 index ce76542..0000000 --- a/o3d/gpu/command_buffer/client/fenced_allocator_test.cc +++ /dev/null @@ -1,496 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the tests for the FencedAllocator class. - -#include "tests/common/win/testing_common.h" -#include "base/message_loop.h" -#include "gpu/command_buffer/client/cmd_buffer_helper.h" -#include "gpu/command_buffer/client/fenced_allocator.h" -#include "gpu/command_buffer/service/cmd_buffer_engine.h" -#include "gpu/command_buffer/service/mocks.h" -#include "gpu/gpu_plugin/command_buffer.h" -#include "gpu/gpu_plugin/gpu_processor.h" -#include "gpu/np_utils/np_object_pointer.h" - -namespace command_buffer { - -using gpu_plugin::CommandBuffer; -using gpu_plugin::GPUProcessor; -using gpu_plugin::NPCreateObject; -using gpu_plugin::NPObjectPointer; -using testing::Return; -using testing::Mock; -using testing::Truly; -using testing::Sequence; -using testing::DoAll; -using testing::Invoke; -using testing::_; - -class BaseFencedAllocatorTest : public testing::Test { - protected: - static const unsigned int kBufferSize = 1024; - - virtual void SetUp() { - api_mock_.reset(new AsyncAPIMock); - // ignore noops in the mock - we don't want to inspect the internals of the - // helper. - EXPECT_CALL(*api_mock_, DoCommand(cmd::kNoop, 0, _)) - .WillRepeatedly(Return(parse_error::kParseNoError)); - // Forward the SetToken calls to the engine - EXPECT_CALL(*api_mock_.get(), DoCommand(cmd::kSetToken, 1, _)) - .WillRepeatedly(DoAll(Invoke(api_mock_.get(), &AsyncAPIMock::SetToken), - Return(parse_error::kParseNoError))); - - ::base::SharedMemory* ring_buffer = new ::base::SharedMemory; - ring_buffer->Create(std::wstring(), false, false, 1024); - ring_buffer->Map(1024); - - command_buffer_ = NPCreateObject(NULL); - command_buffer_->Initialize(ring_buffer); - - parser_ = new command_buffer::CommandParser(ring_buffer->memory(), - kBufferSize, - 0, - kBufferSize, - 0, - api_mock_.get()); - - scoped_refptr gpu_processor(new GPUProcessor( - NULL, command_buffer_.Get(), NULL, NULL, parser_, INT_MAX)); - command_buffer_->SetPutOffsetChangeCallback(NewCallback( - gpu_processor.get(), &GPUProcessor::ProcessCommands)); - - api_mock_->set_engine(gpu_processor.get()); - - helper_.reset(new CommandBufferHelper(NULL, command_buffer_)); - helper_->Initialize(); - } - - virtual void TearDown() { - helper_.release(); - } - - scoped_ptr api_mock_; - NPObjectPointer command_buffer_; - command_buffer::CommandParser* parser_; - scoped_ptr helper_; -}; - -#ifndef COMPILER_MSVC -const unsigned int BaseFencedAllocatorTest::kBufferSize; -#endif - -// Test fixture for FencedAllocator test - Creates a FencedAllocator, using a -// CommandBufferHelper with a mock AsyncAPIInterface for its interface (calling -// it directly, not through the RPC mechanism), making sure Noops are ignored -// and SetToken are properly forwarded to the engine. -class FencedAllocatorTest : public BaseFencedAllocatorTest { - protected: - virtual void SetUp() { - BaseFencedAllocatorTest::SetUp(); - allocator_.reset(new FencedAllocator(kBufferSize, helper_.get())); - } - - virtual void TearDown() { - // If the GPUProcessor posts any tasks, this forces them to run. - MessageLoop::current()->RunAllPending(); - - EXPECT_TRUE(allocator_->CheckConsistency()); - allocator_.release(); - - BaseFencedAllocatorTest::TearDown(); - } - - scoped_ptr allocator_; -}; - -// Checks basic alloc and free. -TEST_F(FencedAllocatorTest, TestBasic) { - allocator_->CheckConsistency(); - - const unsigned int kSize = 16; - FencedAllocator::Offset offset = allocator_->Alloc(kSize); - EXPECT_NE(FencedAllocator::kInvalidOffset, offset); - EXPECT_GE(kBufferSize, offset+kSize); - EXPECT_TRUE(allocator_->CheckConsistency()); - - allocator_->Free(offset); - EXPECT_TRUE(allocator_->CheckConsistency()); -} - -// Checks out-of-memory condition. -TEST_F(FencedAllocatorTest, TestOutOfMemory) { - EXPECT_TRUE(allocator_->CheckConsistency()); - - const unsigned int kSize = 16; - const unsigned int kAllocCount = kBufferSize / kSize; - CHECK(kAllocCount * kSize == kBufferSize); - - // Allocate several buffers to fill in the memory. - FencedAllocator::Offset offsets[kAllocCount]; - for (unsigned int i = 0; i < kAllocCount; ++i) { - offsets[i] = allocator_->Alloc(kSize); - EXPECT_NE(FencedAllocator::kInvalidOffset, offsets[i]); - EXPECT_GE(kBufferSize, offsets[i]+kSize); - EXPECT_TRUE(allocator_->CheckConsistency()); - } - - // This allocation should fail. - FencedAllocator::Offset offset_failed = allocator_->Alloc(kSize); - EXPECT_EQ(FencedAllocator::kInvalidOffset, offset_failed); - EXPECT_TRUE(allocator_->CheckConsistency()); - - // Free one successful allocation, reallocate with half the size - allocator_->Free(offsets[0]); - EXPECT_TRUE(allocator_->CheckConsistency()); - offsets[0] = allocator_->Alloc(kSize/2); - EXPECT_NE(FencedAllocator::kInvalidOffset, offsets[0]); - EXPECT_GE(kBufferSize, offsets[0]+kSize); - EXPECT_TRUE(allocator_->CheckConsistency()); - - // This allocation should fail as well. - offset_failed = allocator_->Alloc(kSize); - EXPECT_EQ(FencedAllocator::kInvalidOffset, offset_failed); - EXPECT_TRUE(allocator_->CheckConsistency()); - - // Free up everything. - for (unsigned int i = 0; i < kAllocCount; ++i) { - allocator_->Free(offsets[i]); - EXPECT_TRUE(allocator_->CheckConsistency()); - } -} - -// Checks the free-pending-token mechanism. -TEST_F(FencedAllocatorTest, TestFreePendingToken) { - EXPECT_TRUE(allocator_->CheckConsistency()); - - const unsigned int kSize = 16; - const unsigned int kAllocCount = kBufferSize / kSize; - CHECK(kAllocCount * kSize == kBufferSize); - - // Allocate several buffers to fill in the memory. - FencedAllocator::Offset offsets[kAllocCount]; - for (unsigned int i = 0; i < kAllocCount; ++i) { - offsets[i] = allocator_->Alloc(kSize); - EXPECT_NE(FencedAllocator::kInvalidOffset, offsets[i]); - EXPECT_GE(kBufferSize, offsets[i]+kSize); - EXPECT_TRUE(allocator_->CheckConsistency()); - } - - // This allocation should fail. - FencedAllocator::Offset offset_failed = allocator_->Alloc(kSize); - EXPECT_EQ(FencedAllocator::kInvalidOffset, offset_failed); - EXPECT_TRUE(allocator_->CheckConsistency()); - - // Free one successful allocation, pending fence. - int32 token = helper_.get()->InsertToken(); - allocator_->FreePendingToken(offsets[0], token); - EXPECT_TRUE(allocator_->CheckConsistency()); - - // The way we hooked up the helper and engine, it won't process commands - // until it has to wait for something. Which means the token shouldn't have - // passed yet at this point. - EXPECT_GT(token, command_buffer_->GetToken()); - - // This allocation will need to reclaim the space freed above, so that should - // process the commands until the token is passed. - offsets[0] = allocator_->Alloc(kSize); - EXPECT_NE(FencedAllocator::kInvalidOffset, offsets[0]); - EXPECT_GE(kBufferSize, offsets[0]+kSize); - EXPECT_TRUE(allocator_->CheckConsistency()); - // Check that the token has indeed passed. - EXPECT_LE(token, command_buffer_->GetToken()); - - // Free up everything. - for (unsigned int i = 0; i < kAllocCount; ++i) { - allocator_->Free(offsets[i]); - EXPECT_TRUE(allocator_->CheckConsistency()); - } -} - -// Tests GetLargestFreeSize -TEST_F(FencedAllocatorTest, TestGetLargestFreeSize) { - EXPECT_TRUE(allocator_->CheckConsistency()); - EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeSize()); - - FencedAllocator::Offset offset = allocator_->Alloc(kBufferSize); - ASSERT_NE(FencedAllocator::kInvalidOffset, offset); - EXPECT_EQ(0u, allocator_->GetLargestFreeSize()); - allocator_->Free(offset); - EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeSize()); - - const unsigned int kSize = 16; - offset = allocator_->Alloc(kSize); - ASSERT_NE(FencedAllocator::kInvalidOffset, offset); - // The following checks that the buffer is allocated "smartly" - which is - // dependent on the implementation. But both first-fit or best-fit would - // ensure that. - EXPECT_EQ(kBufferSize - kSize, allocator_->GetLargestFreeSize()); - - // Allocate 2 more buffers (now 3), and then free the first two. This is to - // ensure a hole. Note that this is dependent on the first-fit current - // implementation. - FencedAllocator::Offset offset1 = allocator_->Alloc(kSize); - ASSERT_NE(FencedAllocator::kInvalidOffset, offset1); - FencedAllocator::Offset offset2 = allocator_->Alloc(kSize); - ASSERT_NE(FencedAllocator::kInvalidOffset, offset2); - allocator_->Free(offset); - allocator_->Free(offset1); - EXPECT_EQ(kBufferSize - 3 * kSize, allocator_->GetLargestFreeSize()); - - offset = allocator_->Alloc(kBufferSize - 3 * kSize); - ASSERT_NE(FencedAllocator::kInvalidOffset, offset); - EXPECT_EQ(2 * kSize, allocator_->GetLargestFreeSize()); - - offset1 = allocator_->Alloc(2 * kSize); - ASSERT_NE(FencedAllocator::kInvalidOffset, offset1); - EXPECT_EQ(0u, allocator_->GetLargestFreeSize()); - - allocator_->Free(offset); - allocator_->Free(offset1); - allocator_->Free(offset2); -} - -// Tests GetLargestFreeOrPendingSize -TEST_F(FencedAllocatorTest, TestGetLargestFreeOrPendingSize) { - EXPECT_TRUE(allocator_->CheckConsistency()); - EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeOrPendingSize()); - - FencedAllocator::Offset offset = allocator_->Alloc(kBufferSize); - ASSERT_NE(FencedAllocator::kInvalidOffset, offset); - EXPECT_EQ(0u, allocator_->GetLargestFreeOrPendingSize()); - allocator_->Free(offset); - EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeOrPendingSize()); - - const unsigned int kSize = 16; - offset = allocator_->Alloc(kSize); - ASSERT_NE(FencedAllocator::kInvalidOffset, offset); - // The following checks that the buffer is allocates "smartly" - which is - // dependent on the implementation. But both first-fit or best-fit would - // ensure that. - EXPECT_EQ(kBufferSize - kSize, allocator_->GetLargestFreeOrPendingSize()); - - // Allocate 2 more buffers (now 3), and then free the first two. This is to - // ensure a hole. Note that this is dependent on the first-fit current - // implementation. - FencedAllocator::Offset offset1 = allocator_->Alloc(kSize); - ASSERT_NE(FencedAllocator::kInvalidOffset, offset1); - FencedAllocator::Offset offset2 = allocator_->Alloc(kSize); - ASSERT_NE(FencedAllocator::kInvalidOffset, offset2); - allocator_->Free(offset); - allocator_->Free(offset1); - EXPECT_EQ(kBufferSize - 3 * kSize, - allocator_->GetLargestFreeOrPendingSize()); - - // Free the last one, pending a token. - int32 token = helper_.get()->InsertToken(); - allocator_->FreePendingToken(offset2, token); - - // Now all the buffers have been freed... - EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeOrPendingSize()); - // .. but one is still waiting for the token. - EXPECT_EQ(kBufferSize - 3 * kSize, - allocator_->GetLargestFreeSize()); - - // The way we hooked up the helper and engine, it won't process commands - // until it has to wait for something. Which means the token shouldn't have - // passed yet at this point. - EXPECT_GT(token, command_buffer_->GetToken()); - // This allocation will need to reclaim the space freed above, so that should - // process the commands until the token is passed, but it will succeed. - offset = allocator_->Alloc(kBufferSize); - ASSERT_NE(FencedAllocator::kInvalidOffset, offset); - // Check that the token has indeed passed. - EXPECT_LE(token, command_buffer_->GetToken()); - allocator_->Free(offset); - - // Everything now has been freed... - EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeOrPendingSize()); - // ... for real. - EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeSize()); -} - -// Test fixture for FencedAllocatorWrapper test - Creates a -// FencedAllocatorWrapper, using a CommandBufferHelper with a mock -// AsyncAPIInterface for its interface (calling it directly, not through the -// RPC mechanism), making sure Noops are ignored and SetToken are properly -// forwarded to the engine. -class FencedAllocatorWrapperTest : public BaseFencedAllocatorTest { - protected: - virtual void SetUp() { - BaseFencedAllocatorTest::SetUp(); - - // Though allocating this buffer isn't strictly necessary, it makes - // allocations point to valid addresses, so they could be used for - // something. - buffer_.reset(new char[kBufferSize]); - allocator_.reset(new FencedAllocatorWrapper(kBufferSize, helper_.get(), - buffer_.get())); - } - - virtual void TearDown() { - // If the GPUProcessor posts any tasks, this forces them to run. - MessageLoop::current()->RunAllPending(); - - EXPECT_TRUE(allocator_->CheckConsistency()); - allocator_.release(); - buffer_.release(); - - BaseFencedAllocatorTest::TearDown(); - } - - scoped_ptr allocator_; - scoped_array buffer_; -}; - -// Checks basic alloc and free. -TEST_F(FencedAllocatorWrapperTest, TestBasic) { - allocator_->CheckConsistency(); - - const unsigned int kSize = 16; - void *pointer = allocator_->Alloc(kSize); - ASSERT_TRUE(pointer); - EXPECT_LE(buffer_.get(), static_cast(pointer)); - EXPECT_GE(kBufferSize, static_cast(pointer) - buffer_.get() + kSize); - EXPECT_TRUE(allocator_->CheckConsistency()); - - allocator_->Free(pointer); - EXPECT_TRUE(allocator_->CheckConsistency()); - - char *pointer_char = allocator_->AllocTyped(kSize); - ASSERT_TRUE(pointer_char); - EXPECT_LE(buffer_.get(), pointer_char); - EXPECT_GE(buffer_.get() + kBufferSize, pointer_char + kSize); - allocator_->Free(pointer_char); - EXPECT_TRUE(allocator_->CheckConsistency()); - - unsigned int *pointer_uint = allocator_->AllocTyped(kSize); - ASSERT_TRUE(pointer_uint); - EXPECT_LE(buffer_.get(), reinterpret_cast(pointer_uint)); - EXPECT_GE(buffer_.get() + kBufferSize, - reinterpret_cast(pointer_uint + kSize)); - - // Check that it did allocate kSize * sizeof(unsigned int). We can't tell - // directly, except from the remaining size. - EXPECT_EQ(kBufferSize - kSize * sizeof(*pointer_uint), - allocator_->GetLargestFreeSize()); - allocator_->Free(pointer_uint); -} - -// Checks out-of-memory condition. -TEST_F(FencedAllocatorWrapperTest, TestOutOfMemory) { - allocator_->CheckConsistency(); - - const unsigned int kSize = 16; - const unsigned int kAllocCount = kBufferSize / kSize; - CHECK(kAllocCount * kSize == kBufferSize); - - // Allocate several buffers to fill in the memory. - void *pointers[kAllocCount]; - for (unsigned int i = 0; i < kAllocCount; ++i) { - pointers[i] = allocator_->Alloc(kSize); - EXPECT_TRUE(pointers[i]); - EXPECT_TRUE(allocator_->CheckConsistency()); - } - - // This allocation should fail. - void *pointer_failed = allocator_->Alloc(kSize); - EXPECT_FALSE(pointer_failed); - EXPECT_TRUE(allocator_->CheckConsistency()); - - // Free one successful allocation, reallocate with half the size - allocator_->Free(pointers[0]); - EXPECT_TRUE(allocator_->CheckConsistency()); - pointers[0] = allocator_->Alloc(kSize/2); - EXPECT_TRUE(pointers[0]); - EXPECT_TRUE(allocator_->CheckConsistency()); - - // This allocation should fail as well. - pointer_failed = allocator_->Alloc(kSize); - EXPECT_FALSE(pointer_failed); - EXPECT_TRUE(allocator_->CheckConsistency()); - - // Free up everything. - for (unsigned int i = 0; i < kAllocCount; ++i) { - allocator_->Free(pointers[i]); - EXPECT_TRUE(allocator_->CheckConsistency()); - } -} - -// Checks the free-pending-token mechanism. -TEST_F(FencedAllocatorWrapperTest, TestFreePendingToken) { - allocator_->CheckConsistency(); - - const unsigned int kSize = 16; - const unsigned int kAllocCount = kBufferSize / kSize; - CHECK(kAllocCount * kSize == kBufferSize); - - // Allocate several buffers to fill in the memory. - void *pointers[kAllocCount]; - for (unsigned int i = 0; i < kAllocCount; ++i) { - pointers[i] = allocator_->Alloc(kSize); - EXPECT_TRUE(pointers[i]); - EXPECT_TRUE(allocator_->CheckConsistency()); - } - - // This allocation should fail. - void *pointer_failed = allocator_->Alloc(kSize); - EXPECT_FALSE(pointer_failed); - EXPECT_TRUE(allocator_->CheckConsistency()); - - // Free one successful allocation, pending fence. - int32 token = helper_.get()->InsertToken(); - allocator_->FreePendingToken(pointers[0], token); - EXPECT_TRUE(allocator_->CheckConsistency()); - - // The way we hooked up the helper and engine, it won't process commands - // until it has to wait for something. Which means the token shouldn't have - // passed yet at this point. - EXPECT_GT(token, command_buffer_->GetToken()); - - // This allocation will need to reclaim the space freed above, so that should - // process the commands until the token is passed. - pointers[0] = allocator_->Alloc(kSize); - EXPECT_TRUE(pointers[0]); - EXPECT_TRUE(allocator_->CheckConsistency()); - // Check that the token has indeed passed. - EXPECT_LE(token, command_buffer_->GetToken()); - - // Free up everything. - for (unsigned int i = 0; i < kAllocCount; ++i) { - allocator_->Free(pointers[i]); - EXPECT_TRUE(allocator_->CheckConsistency()); - } -} - -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/client/id_allocator.cc b/o3d/gpu/command_buffer/client/id_allocator.cc deleted file mode 100644 index 49104e5..0000000 --- a/o3d/gpu/command_buffer/client/id_allocator.cc +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the implementation of IdAllocator. - -#include "gpu/command_buffer/client/id_allocator.h" - -namespace command_buffer { - -IdAllocator::IdAllocator() : bitmap_(1) { bitmap_[0] = 0; } - -static const unsigned int kBitsPerUint32 = sizeof(Uint32) * 8; // NOLINT - -// Looks for the first non-full entry, and return the first free bit in that -// entry. If all the entries are full, it will return the first bit of an entry -// that would be appended, but doesn't actually append that entry to the vector. -unsigned int IdAllocator::FindFirstFree() const { - size_t size = bitmap_.size(); - for (unsigned int i = 0; i < size; ++i) { - Uint32 value = bitmap_[i]; - if (value != 0xffffffffU) { - for (unsigned int j = 0; j < kBitsPerUint32; ++j) { - if (!(value & (1 << j))) return i * kBitsPerUint32 + j; - } - DLOG(FATAL) << "Code should not reach here."; - } - } - return size*kBitsPerUint32; -} - -// Sets the correct bit in the proper entry, resizing the vector if needed. -void IdAllocator::SetBit(unsigned int bit, bool value) { - size_t size = bitmap_.size(); - if (bit >= size * kBitsPerUint32) { - size_t newsize = bit / kBitsPerUint32 + 1; - bitmap_.resize(newsize); - for (size_t i = size; i < newsize; ++i) bitmap_[i] = 0; - } - Uint32 mask = 1U << (bit % kBitsPerUint32); - if (value) { - bitmap_[bit / kBitsPerUint32] |= mask; - } else { - bitmap_[bit / kBitsPerUint32] &= ~mask; - } -} - -// Gets the bit from the proper entry. This doesn't resize the vector, just -// returns false if the bit is beyond the last entry. -bool IdAllocator::GetBit(unsigned int bit) const { - size_t size = bitmap_.size(); - if (bit / kBitsPerUint32 >= size) return false; - Uint32 mask = 1U << (bit % kBitsPerUint32); - return (bitmap_[bit / kBitsPerUint32] & mask) != 0; -} - -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/client/id_allocator.h b/o3d/gpu/command_buffer/client/id_allocator.h deleted file mode 100644 index b2b14b9..0000000 --- a/o3d/gpu/command_buffer/client/id_allocator.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the definition of the IdAllocator class. - -#ifndef GPU_COMMAND_BUFFER_CLIENT_CROSS_ID_ALLOCATOR_H_ -#define GPU_COMMAND_BUFFER_CLIENT_CROSS_ID_ALLOCATOR_H_ - -#include -#include "base/basictypes.h" -#include "gpu/command_buffer/common/types.h" -#include "gpu/command_buffer/common/resource.h" - -namespace command_buffer { - -// A class to manage the allocation of resource IDs. It uses a bitfield stored -// into a vector of unsigned ints. -class IdAllocator { - public: - IdAllocator(); - - // Allocates a new resource ID. - command_buffer::ResourceId AllocateID() { - unsigned int bit = FindFirstFree(); - SetBit(bit, true); - return bit; - } - - // Frees a resource ID. - void FreeID(command_buffer::ResourceId id) { - SetBit(id, false); - } - - // Checks whether or not a resource ID is in use. - bool InUse(command_buffer::ResourceId id) { - return GetBit(id); - } - private: - void SetBit(unsigned int bit, bool value); - bool GetBit(unsigned int bit) const; - unsigned int FindFirstFree() const; - - std::vector bitmap_; - DISALLOW_COPY_AND_ASSIGN(IdAllocator); -}; - -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_CLIENT_CROSS_ID_ALLOCATOR_H_ diff --git a/o3d/gpu/command_buffer/client/id_allocator_test.cc b/o3d/gpu/command_buffer/client/id_allocator_test.cc deleted file mode 100644 index 10c7809..0000000 --- a/o3d/gpu/command_buffer/client/id_allocator_test.cc +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file has the unit tests for the IdAllocator class. - -#include "tests/common/win/testing_common.h" -#include "gpu/command_buffer/client/id_allocator.h" - -namespace command_buffer { - -using command_buffer::ResourceId; - -class IdAllocatorTest : public testing::Test { - protected: - virtual void SetUp() {} - virtual void TearDown() {} - - IdAllocator* id_allocator() { return &id_allocator_; } - - private: - IdAllocator id_allocator_; -}; - -// Checks basic functionality: AllocateID, FreeID, InUse. -TEST_F(IdAllocatorTest, TestBasic) { - IdAllocator *allocator = id_allocator(); - // Check that resource 0 is not in use - EXPECT_FALSE(allocator->InUse(0)); - - // Allocate an ID, check that it's in use. - ResourceId id1 = allocator->AllocateID(); - EXPECT_TRUE(allocator->InUse(id1)); - - // Allocate another ID, check that it's in use, and different from the first - // one. - ResourceId id2 = allocator->AllocateID(); - EXPECT_TRUE(allocator->InUse(id2)); - EXPECT_NE(id1, id2); - - // Free one of the IDs, check that it's not in use any more. - allocator->FreeID(id1); - EXPECT_FALSE(allocator->InUse(id1)); - - // Frees the other ID, check that it's not in use any more. - allocator->FreeID(id2); - EXPECT_FALSE(allocator->InUse(id2)); -} - -// Checks that the resource IDs are allocated conservatively, and re-used after -// being freed. -TEST_F(IdAllocatorTest, TestAdvanced) { - IdAllocator *allocator = id_allocator(); - - // Allocate a significant number of resources. - const unsigned int kNumResources = 100; - ResourceId ids[kNumResources]; - for (unsigned int i = 0; i < kNumResources; ++i) { - ids[i] = allocator->AllocateID(); - EXPECT_TRUE(allocator->InUse(ids[i])); - } - - // Check that the allocation is conservative with resource IDs, that is that - // the resource IDs don't go over kNumResources - so that the service doesn't - // have to allocate too many internal structures when the resources are used. - for (unsigned int i = 0; i < kNumResources; ++i) { - EXPECT_GT(kNumResources, ids[i]); - } - - // Check that the next resources are still free. - for (unsigned int i = 0; i < kNumResources; ++i) { - EXPECT_FALSE(allocator->InUse(kNumResources + i)); - } - - // Check that a new allocation re-uses the resource we just freed. - ResourceId id1 = ids[kNumResources / 2]; - allocator->FreeID(id1); - EXPECT_FALSE(allocator->InUse(id1)); - ResourceId id2 = allocator->AllocateID(); - EXPECT_TRUE(allocator->InUse(id2)); - EXPECT_EQ(id1, id2); -} - -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/client/o3d_cmd_helper.cc b/o3d/gpu/command_buffer/client/o3d_cmd_helper.cc deleted file mode 100644 index 85c6a27..0000000 --- a/o3d/gpu/command_buffer/client/o3d_cmd_helper.cc +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the implementation of the o3d buffer helper class. - -#include "gpu/command_buffer/client/o3d_cmd_helper.h" - -namespace command_buffer { - -// Currently this is a place holder. - -} // namespace command_buffer - diff --git a/o3d/gpu/command_buffer/client/o3d_cmd_helper.h b/o3d/gpu/command_buffer/client/o3d_cmd_helper.h deleted file mode 100644 index 0dbbff4..0000000 --- a/o3d/gpu/command_buffer/client/o3d_cmd_helper.h +++ /dev/null @@ -1,636 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the o3d command buffer helper class. - -#ifndef GPU_COMMAND_BUFFER_CLIENT_CROSS_O3D_CMD_HELPER_H_ -#define GPU_COMMAND_BUFFER_CLIENT_CROSS_O3D_CMD_HELPER_H_ - -#include "gpu/command_buffer/common/logging.h" -#include "gpu/command_buffer/common/constants.h" -#include "gpu/command_buffer/client/cmd_buffer_helper.h" -#include "gpu/command_buffer/common/o3d_cmd_format.h" -#include "gpu/np_utils/np_object_pointer.h" - -namespace command_buffer { - -// A helper for O3D command buffers. -class O3DCmdHelper : public CommandBufferHelper { - public: - O3DCmdHelper( - NPP npp, - const gpu_plugin::NPObjectPointer& - command_buffer) - : CommandBufferHelper(npp, command_buffer) { - } - virtual ~O3DCmdHelper() { - } - - // ------------------ Individual commands ---------------------- - - void BeginFrame() { - o3d::BeginFrame& cmd = GetCmdSpace(); - cmd.Init(); - } - - - void EndFrame() { - o3d::EndFrame& cmd = GetCmdSpace(); - cmd.Init(); - } - - void Clear( - uint32 buffers, - float red, float green, float blue, float alpha, - float depth, uint32 stencil) { - o3d::Clear& cmd = GetCmdSpace(); - cmd.Init(buffers, red, green, blue, alpha, depth, stencil); - } - - void SetViewport( - uint32 left, - uint32 top, - uint32 width, - uint32 height, - float z_min, - float z_max) { - o3d::SetViewport& cmd = GetCmdSpace(); - cmd.Init(left, top, width, height, z_min, z_max); - } - - void CreateVertexBuffer( - ResourceId vertex_buffer_id, uint32 size, vertex_buffer::Flags flags) { - o3d::CreateVertexBuffer& cmd = GetCmdSpace(); - cmd.Init(vertex_buffer_id, size, flags); - } - - void DestroyVertexBuffer(ResourceId vertex_buffer_id) { - o3d::DestroyVertexBuffer& cmd = GetCmdSpace(); - cmd.Init(vertex_buffer_id); - } - - void SetVertexBufferDataImmediate( - ResourceId vertex_buffer_id, uint32 offset, - const void* data, uint32 size) { - o3d::SetVertexBufferDataImmediate& cmd = - GetImmediateCmdSpace(size); - cmd.Init(vertex_buffer_id, offset, data, size); - } - - void SetVertexBufferData( - ResourceId vertex_buffer_id, uint32 offset, uint32 size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - o3d::SetVertexBufferData& cmd = - GetCmdSpace(); - cmd.Init(vertex_buffer_id, offset, size, - shared_memory_id, shared_memory_offset); - } - - void GetVertexBufferData( - ResourceId vertex_buffer_id, uint32 offset, uint32 size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - o3d::GetVertexBufferData& cmd = - GetCmdSpace(); - cmd.Init(vertex_buffer_id, offset, size, - shared_memory_id, shared_memory_offset); - } - - void CreateIndexBuffer( - ResourceId index_buffer_id, uint32 size, index_buffer::Flags flags) { - o3d::CreateIndexBuffer& cmd = - GetCmdSpace(); - cmd.Init(index_buffer_id, size, flags); - } - - void DestroyIndexBuffer(ResourceId index_buffer_id) { - o3d::DestroyIndexBuffer& cmd = GetCmdSpace(); - cmd.Init(index_buffer_id); - } - - void SetIndexBufferDataImmediate( - ResourceId index_buffer_id, uint32 offset, - const void* data, uint32 size) { - o3d::SetIndexBufferDataImmediate& cmd = - GetImmediateCmdSpace(size); - cmd.Init(index_buffer_id, offset, data, size); - } - - void SetIndexBufferData( - ResourceId index_buffer_id, uint32 offset, uint32 size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - o3d::SetIndexBufferData& cmd = GetCmdSpace(); - cmd.Init(index_buffer_id, offset, size, - shared_memory_id, shared_memory_offset); - } - - void GetIndexBufferData( - ResourceId index_buffer_id, uint32 offset, uint32 size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - o3d::GetIndexBufferData& cmd = GetCmdSpace(); - cmd.Init(index_buffer_id, offset, size, - shared_memory_id, shared_memory_offset); - } - - void CreateVertexStruct(ResourceId vertex_struct_id, uint32 input_count) { - o3d::CreateVertexStruct& cmd = GetCmdSpace(); - cmd.Init(vertex_struct_id, input_count); - } - - void DestroyVertexStruct(ResourceId vertex_struct_id) { - o3d::DestroyVertexStruct& cmd = GetCmdSpace(); - cmd.Init(vertex_struct_id); - } - - void SetVertexInput( - ResourceId vertex_struct_id, - uint32 input_index, - ResourceId vertex_buffer_id, - uint32 offset, - vertex_struct::Semantic semantic, - uint32 semantic_index, - vertex_struct::Type type, - uint32 stride) { - o3d::SetVertexInput& cmd = GetCmdSpace(); - cmd.Init( - vertex_struct_id, - input_index, - vertex_buffer_id, - offset, - semantic, - semantic_index, - type, - stride); - } - - void SetVertexStruct(ResourceId vertex_struct_id) { - o3d::SetVertexStruct& cmd = GetCmdSpace(); - cmd.Init(vertex_struct_id); - } - - void Draw(o3d::PrimitiveType primitive_type, uint32 first, uint32 count) { - o3d::Draw& cmd = GetCmdSpace(); - cmd.Init(primitive_type, first, count); - } - - void DrawIndexed( - o3d::PrimitiveType primitive_type, - ResourceId index_buffer_id, - uint32 first, - uint32 count, - uint32 min_index, - uint32 max_index) { - o3d::DrawIndexed& cmd = GetCmdSpace(); - cmd.Init( - primitive_type, - index_buffer_id, - first, - count, - min_index, - max_index); - } - - void CreateEffect( - ResourceId effect_id, uint32 size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - o3d::CreateEffect& cmd = GetCmdSpace(); - cmd.Init(effect_id, size, shared_memory_id, shared_memory_offset); - } - - void CreateEffectImmediate( - ResourceId effect_id, uint32 size, const void* data) { - o3d::CreateEffectImmediate& cmd = - GetImmediateCmdSpace(size); - cmd.Init(effect_id, size, data); - } - - void DestroyEffect(ResourceId effect_id) { - o3d::DestroyEffect& cmd = GetCmdSpace(); - cmd.Init(effect_id); - } - - void SetEffect(ResourceId effect_id) { - o3d::SetEffect& cmd = GetCmdSpace(); - cmd.Init(effect_id); - } - - void GetParamCount( - ResourceId effect_id, uint32 size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - o3d::GetParamCount& cmd = GetCmdSpace(); - cmd.Init(effect_id, size, shared_memory_id, shared_memory_offset); - } - - void CreateParam(ResourceId param_id, ResourceId effect_id, uint32 index) { - o3d::CreateParam& cmd = GetCmdSpace(); - cmd.Init(param_id, effect_id, index); - } - - void CreateParamByName( - ResourceId param_id, ResourceId effect_id, uint32 size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - o3d::CreateParamByName& cmd = GetCmdSpace(); - cmd.Init(param_id, effect_id, size, shared_memory_id, shared_memory_offset); - } - - void CreateParamByNameImmediate( - ResourceId param_id, ResourceId effect_id, - uint32 size, const void* data) { - o3d::CreateParamByNameImmediate& cmd = - GetImmediateCmdSpace(size); - cmd.Init(param_id, effect_id, size, data); - } - - void DestroyParam(ResourceId param_id) { - o3d::DestroyParam& cmd = GetCmdSpace(); - cmd.Init(param_id); - } - - void SetParamData( - ResourceId param_id, uint32 size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - o3d::SetParamData& cmd = GetCmdSpace(); - cmd.Init(param_id, size, shared_memory_id, shared_memory_offset); - } - - void SetParamDataImmediate( - ResourceId param_id, uint32 size, const void* data) { - o3d::SetParamDataImmediate& cmd = - GetImmediateCmdSpace(size); - cmd.Init(param_id, size, data); - } - - void GetParamDesc( - ResourceId param_id, uint32 size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - o3d::GetParamDesc& cmd = GetCmdSpace(); - cmd.Init(param_id, size, shared_memory_id, shared_memory_offset); - } - - void GetStreamCount( - ResourceId effect_id, uint32 size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - o3d::GetStreamCount& cmd = GetCmdSpace(); - cmd.Init(effect_id, size, shared_memory_id, shared_memory_offset); - } - - void GetStreamDesc( - ResourceId effect_id, uint32 index, uint32 size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - o3d::GetStreamDesc& cmd = GetCmdSpace(); - cmd.Init(effect_id, index, size, shared_memory_id, shared_memory_offset); - } - - void DestroyTexture(ResourceId texture_id) { - o3d::DestroyTexture& cmd = GetCmdSpace(); - cmd.Init(texture_id); - } - - void CreateTexture2d( - ResourceId texture_id, - uint32 width, uint32 height, - uint32 levels, texture::Format format, - bool enable_render_surfaces) { - o3d::CreateTexture2d& cmd = GetCmdSpace(); - cmd.Init(texture_id, - width, height, levels, format, - enable_render_surfaces); - } - - void CreateTexture3d( - ResourceId texture_id, - uint32 width, uint32 height, uint32 depth, - uint32 levels, texture::Format format, - bool enable_render_surfaces) { - o3d::CreateTexture3d& cmd = GetCmdSpace(); - cmd.Init(texture_id, - width, height, depth, - levels, format, - enable_render_surfaces); - } - - void CreateTextureCube( - ResourceId texture_id, - uint32 edge_length, uint32 levels, texture::Format format, - bool enable_render_surfaces) { - o3d::CreateTextureCube& cmd = GetCmdSpace(); - cmd.Init(texture_id, - edge_length, levels, format, - enable_render_surfaces); - } - - void SetTextureData( - ResourceId texture_id, - uint32 x, - uint32 y, - uint32 z, - uint32 width, - uint32 height, - uint32 depth, - uint32 level, - texture::Face face, - uint32 row_pitch, - uint32 slice_pitch, - uint32 size, - uint32 shared_memory_id, - uint32 shared_memory_offset) { - o3d::SetTextureData& cmd = GetCmdSpace(); - cmd.Init( - texture_id, - x, - y, - z, - width, - height, - depth, - level, - face, - row_pitch, - slice_pitch, - size, - shared_memory_id, - shared_memory_offset); - } - - void SetTextureDataImmediate( - ResourceId texture_id, - uint32 x, - uint32 y, - uint32 z, - uint32 width, - uint32 height, - uint32 depth, - uint32 level, - texture::Face face, - uint32 row_pitch, - uint32 slice_pitch, - uint32 size, - const void* data) { - o3d::SetTextureDataImmediate& cmd = - GetImmediateCmdSpace(size); - cmd.Init( - texture_id, - x, - y, - z, - width, - height, - depth, - level, - face, - row_pitch, - slice_pitch, - size, - data); - } - - void GetTextureData( - ResourceId texture_id, - uint32 x, - uint32 y, - uint32 z, - uint32 width, - uint32 height, - uint32 depth, - uint32 level, - texture::Face face, - uint32 row_pitch, - uint32 slice_pitch, - uint32 size, - uint32 shared_memory_id, - uint32 shared_memory_offset) { - o3d::GetTextureData& cmd = GetCmdSpace(); - cmd.Init( - texture_id, - x, - y, - z, - width, - height, - depth, - level, - face, - row_pitch, - slice_pitch, - size, - shared_memory_id, - shared_memory_offset); - } - - void CreateSampler(ResourceId sampler_id) { - o3d::CreateSampler& cmd = GetCmdSpace(); - cmd.Init(sampler_id); - } - - void DestroySampler(ResourceId sampler_id) { - o3d::DestroySampler& cmd = GetCmdSpace(); - cmd.Init(sampler_id); - } - - void SetSamplerStates( - ResourceId sampler_id, - sampler::AddressingMode address_u_value, - sampler::AddressingMode address_v_value, - sampler::AddressingMode address_w_value, - sampler::FilteringMode mag_filter_value, - sampler::FilteringMode min_filter_value, - sampler::FilteringMode mip_filter_value, - uint8 max_anisotropy) { - o3d::SetSamplerStates& cmd = GetCmdSpace(); - cmd.Init( - sampler_id, - address_u_value, - address_v_value, - address_w_value, - mag_filter_value, - min_filter_value, - mip_filter_value, - max_anisotropy); - } - - void SetSamplerBorderColor( - ResourceId sampler_id, - float red, float green, float blue, float alpha) { - o3d::SetSamplerBorderColor& cmd = - GetCmdSpace(); - cmd.Init(sampler_id, red, green, blue, alpha); - } - - void SetSamplerTexture(ResourceId sampler_id, ResourceId texture_id) { - o3d::SetSamplerTexture& cmd = GetCmdSpace(); - cmd.Init(sampler_id, texture_id); - } - - void SetScissor( - uint32 x, - uint32 y, - uint32 width, - uint32 height, - bool enable) { - o3d::SetScissor& cmd = GetCmdSpace(); - cmd.Init( - x, - y, - width, - height, - enable); - } - - void SetPolygonOffset(float slope_factor, float units) { - o3d::SetPolygonOffset& cmd = GetCmdSpace(); - cmd.Init(slope_factor, units); - } - - void SetPointLineRaster( - bool line_smooth_enable, bool point_sprite_enable, float point_size) { - o3d::SetPointLineRaster& cmd = GetCmdSpace(); - cmd.Init(line_smooth_enable, point_sprite_enable, point_size); - } - - void SetPolygonRaster(o3d::PolygonMode fill_mode, - o3d::FaceCullMode cull_mode) { - o3d::SetPolygonRaster& cmd = GetCmdSpace(); - cmd.Init(fill_mode, cull_mode); - } - - void SetAlphaTest(o3d::Comparison func, bool enable, float value) { - o3d::SetAlphaTest& cmd = GetCmdSpace(); - cmd.Init(func, enable, value); - } - - void SetDepthTest(o3d::Comparison func, bool write_enable, bool enable) { - o3d::SetDepthTest& cmd = GetCmdSpace(); - cmd.Init(func, write_enable, enable); - } - - void SetStencilTest( - uint8 write_mask, - uint8 compare_mask, - uint8 reference_value, - bool separate_ccw, - bool enable, - o3d::Comparison cw_func, - o3d::StencilOp cw_pass_op, - o3d::StencilOp cw_fail_op, - o3d::StencilOp cw_z_fail_op, - o3d::Comparison ccw_func, - o3d::StencilOp ccw_pass_op, - o3d::StencilOp ccw_fail_op, - o3d::StencilOp ccw_z_fail_op) { - o3d::SetStencilTest& cmd = GetCmdSpace(); - cmd.Init( - write_mask, - compare_mask, - reference_value, - separate_ccw, - enable, - cw_func, - cw_pass_op, - cw_fail_op, - cw_z_fail_op, - ccw_func, - ccw_pass_op, - ccw_fail_op, - ccw_z_fail_op); - } - - void SetColorWrite(uint8 mask, bool dither_enable) { - o3d::SetColorWrite& cmd = GetCmdSpace(); - cmd.Init(mask, dither_enable); - } - - void SetBlending( - o3d::BlendFunc color_src_func, - o3d::BlendFunc color_dst_func, - o3d::BlendEq color_eq, - o3d::BlendFunc alpha_src_func, - o3d::BlendFunc alpha_dst_func, - o3d::BlendEq alpha_eq, - bool separate_alpha, - bool enable) { - o3d::SetBlending& cmd = GetCmdSpace(); - cmd.Init( - color_src_func, - color_dst_func, - color_eq, - alpha_src_func, - alpha_dst_func, - alpha_eq, - separate_alpha, - enable); - } - - void SetBlendingColor(float red, float green, float blue, float alpha) { - o3d::SetBlendingColor& cmd = GetCmdSpace(); - cmd.Init(red, green, blue, alpha); - } - - void CreateRenderSurface( - ResourceId render_surface_id, ResourceId texture_id, - uint32 width, uint32 height, - uint32 level, uint32 side) { - o3d::CreateRenderSurface& cmd = GetCmdSpace(); - cmd.Init(render_surface_id, texture_id, width, height, level, side); - } - - void DestroyRenderSurface(ResourceId render_surface_id) { - o3d::DestroyRenderSurface& cmd = - GetCmdSpace(); - cmd.Init(render_surface_id); - } - - void CreateDepthSurface( - ResourceId depth_surface_id, uint32 width, uint32 height) { - o3d::CreateDepthSurface& cmd = GetCmdSpace(); - cmd.Init(depth_surface_id, width, height); - } - - void DestroyDepthSurface(ResourceId depth_surface_id) { - o3d::DestroyDepthSurface& cmd = GetCmdSpace(); - cmd.Init(depth_surface_id); - } - - void SetRenderSurface( - ResourceId render_surface_id, ResourceId depth_surface_id) { - o3d::SetRenderSurface& cmd = GetCmdSpace(); - cmd.Init(render_surface_id, depth_surface_id); - } - - void SetBackSurfaces() { - o3d::SetBackSurfaces& cmd = GetCmdSpace(); - cmd.Init(); - } -}; - -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_CLIENT_CROSS_O3D_CMD_HELPER_H_ - diff --git a/o3d/gpu/command_buffer/common/GLES2/gl2.h b/o3d/gpu/command_buffer/common/GLES2/gl2.h deleted file mode 100644 index 94c643b..0000000 --- a/o3d/gpu/command_buffer/common/GLES2/gl2.h +++ /dev/null @@ -1,621 +0,0 @@ -#ifndef __gl2_h_ -#define __gl2_h_ - -/* $Revision: 8784 $ on $Date:: 2009-09-02 09:49:17 -0700 #$ */ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * This document is licensed under the SGI Free Software B License Version - * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . - */ - -/*------------------------------------------------------------------------- - * Data type definitions - *-----------------------------------------------------------------------*/ - -typedef void GLvoid; -typedef unsigned int GLenum; -typedef unsigned char GLboolean; -typedef unsigned int GLbitfield; -typedef khronos_int8_t GLbyte; -typedef short GLshort; -typedef int GLint; -typedef int GLsizei; -typedef khronos_uint8_t GLubyte; -typedef unsigned short GLushort; -typedef unsigned int GLuint; -typedef khronos_float_t GLfloat; -typedef khronos_float_t GLclampf; -typedef khronos_int32_t GLfixed; - -/* GL types for handling large vertex buffer objects */ -typedef khronos_intptr_t GLintptr; -typedef khronos_ssize_t GLsizeiptr; - -/* OpenGL ES core versions */ -#define GL_ES_VERSION_2_0 1 - -/* ClearBufferMask */ -#define GL_DEPTH_BUFFER_BIT 0x00000100 -#define GL_STENCIL_BUFFER_BIT 0x00000400 -#define GL_COLOR_BUFFER_BIT 0x00004000 - -/* Boolean */ -#define GL_FALSE 0 -#define GL_TRUE 1 - -/* BeginMode */ -#define GL_POINTS 0x0000 -#define GL_LINES 0x0001 -#define GL_LINE_LOOP 0x0002 -#define GL_LINE_STRIP 0x0003 -#define GL_TRIANGLES 0x0004 -#define GL_TRIANGLE_STRIP 0x0005 -#define GL_TRIANGLE_FAN 0x0006 - -/* AlphaFunction (not supported in ES20) */ -/* GL_NEVER */ -/* GL_LESS */ -/* GL_EQUAL */ -/* GL_LEQUAL */ -/* GL_GREATER */ -/* GL_NOTEQUAL */ -/* GL_GEQUAL */ -/* GL_ALWAYS */ - -/* BlendingFactorDest */ -#define GL_ZERO 0 -#define GL_ONE 1 -#define GL_SRC_COLOR 0x0300 -#define GL_ONE_MINUS_SRC_COLOR 0x0301 -#define GL_SRC_ALPHA 0x0302 -#define GL_ONE_MINUS_SRC_ALPHA 0x0303 -#define GL_DST_ALPHA 0x0304 -#define GL_ONE_MINUS_DST_ALPHA 0x0305 - -/* BlendingFactorSrc */ -/* GL_ZERO */ -/* GL_ONE */ -#define GL_DST_COLOR 0x0306 -#define GL_ONE_MINUS_DST_COLOR 0x0307 -#define GL_SRC_ALPHA_SATURATE 0x0308 -/* GL_SRC_ALPHA */ -/* GL_ONE_MINUS_SRC_ALPHA */ -/* GL_DST_ALPHA */ -/* GL_ONE_MINUS_DST_ALPHA */ - -/* BlendEquationSeparate */ -#define GL_FUNC_ADD 0x8006 -#define GL_BLEND_EQUATION 0x8009 -#define GL_BLEND_EQUATION_RGB 0x8009 /* same as BLEND_EQUATION */ -#define GL_BLEND_EQUATION_ALPHA 0x883D - -/* BlendSubtract */ -#define GL_FUNC_SUBTRACT 0x800A -#define GL_FUNC_REVERSE_SUBTRACT 0x800B - -/* Separate Blend Functions */ -#define GL_BLEND_DST_RGB 0x80C8 -#define GL_BLEND_SRC_RGB 0x80C9 -#define GL_BLEND_DST_ALPHA 0x80CA -#define GL_BLEND_SRC_ALPHA 0x80CB -#define GL_CONSTANT_COLOR 0x8001 -#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 -#define GL_CONSTANT_ALPHA 0x8003 -#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 -#define GL_BLEND_COLOR 0x8005 - -/* Buffer Objects */ -#define GL_ARRAY_BUFFER 0x8892 -#define GL_ELEMENT_ARRAY_BUFFER 0x8893 -#define GL_ARRAY_BUFFER_BINDING 0x8894 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 - -#define GL_STREAM_DRAW 0x88E0 -#define GL_STATIC_DRAW 0x88E4 -#define GL_DYNAMIC_DRAW 0x88E8 - -#define GL_BUFFER_SIZE 0x8764 -#define GL_BUFFER_USAGE 0x8765 - -#define GL_CURRENT_VERTEX_ATTRIB 0x8626 - -/* CullFaceMode */ -#define GL_FRONT 0x0404 -#define GL_BACK 0x0405 -#define GL_FRONT_AND_BACK 0x0408 - -/* DepthFunction */ -/* GL_NEVER */ -/* GL_LESS */ -/* GL_EQUAL */ -/* GL_LEQUAL */ -/* GL_GREATER */ -/* GL_NOTEQUAL */ -/* GL_GEQUAL */ -/* GL_ALWAYS */ - -/* EnableCap */ -#define GL_TEXTURE_2D 0x0DE1 -#define GL_CULL_FACE 0x0B44 -#define GL_BLEND 0x0BE2 -#define GL_DITHER 0x0BD0 -#define GL_STENCIL_TEST 0x0B90 -#define GL_DEPTH_TEST 0x0B71 -#define GL_SCISSOR_TEST 0x0C11 -#define GL_POLYGON_OFFSET_FILL 0x8037 -#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E -#define GL_SAMPLE_COVERAGE 0x80A0 - -/* ErrorCode */ -#define GL_NO_ERROR 0 -#define GL_INVALID_ENUM 0x0500 -#define GL_INVALID_VALUE 0x0501 -#define GL_INVALID_OPERATION 0x0502 -#define GL_OUT_OF_MEMORY 0x0505 - -/* FrontFaceDirection */ -#define GL_CW 0x0900 -#define GL_CCW 0x0901 - -/* GetPName */ -#define GL_LINE_WIDTH 0x0B21 -#define GL_ALIASED_POINT_SIZE_RANGE 0x846D -#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E -#define GL_CULL_FACE_MODE 0x0B45 -#define GL_FRONT_FACE 0x0B46 -#define GL_DEPTH_RANGE 0x0B70 -#define GL_DEPTH_WRITEMASK 0x0B72 -#define GL_DEPTH_CLEAR_VALUE 0x0B73 -#define GL_DEPTH_FUNC 0x0B74 -#define GL_STENCIL_CLEAR_VALUE 0x0B91 -#define GL_STENCIL_FUNC 0x0B92 -#define GL_STENCIL_FAIL 0x0B94 -#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 -#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 -#define GL_STENCIL_REF 0x0B97 -#define GL_STENCIL_VALUE_MASK 0x0B93 -#define GL_STENCIL_WRITEMASK 0x0B98 -#define GL_STENCIL_BACK_FUNC 0x8800 -#define GL_STENCIL_BACK_FAIL 0x8801 -#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 -#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 -#define GL_STENCIL_BACK_REF 0x8CA3 -#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 -#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 -#define GL_VIEWPORT 0x0BA2 -#define GL_SCISSOR_BOX 0x0C10 -/* GL_SCISSOR_TEST */ -#define GL_COLOR_CLEAR_VALUE 0x0C22 -#define GL_COLOR_WRITEMASK 0x0C23 -#define GL_UNPACK_ALIGNMENT 0x0CF5 -#define GL_PACK_ALIGNMENT 0x0D05 -#define GL_MAX_TEXTURE_SIZE 0x0D33 -#define GL_MAX_VIEWPORT_DIMS 0x0D3A -#define GL_SUBPIXEL_BITS 0x0D50 -#define GL_RED_BITS 0x0D52 -#define GL_GREEN_BITS 0x0D53 -#define GL_BLUE_BITS 0x0D54 -#define GL_ALPHA_BITS 0x0D55 -#define GL_DEPTH_BITS 0x0D56 -#define GL_STENCIL_BITS 0x0D57 -#define GL_POLYGON_OFFSET_UNITS 0x2A00 -/* GL_POLYGON_OFFSET_FILL */ -#define GL_POLYGON_OFFSET_FACTOR 0x8038 -#define GL_TEXTURE_BINDING_2D 0x8069 -#define GL_SAMPLE_BUFFERS 0x80A8 -#define GL_SAMPLES 0x80A9 -#define GL_SAMPLE_COVERAGE_VALUE 0x80AA -#define GL_SAMPLE_COVERAGE_INVERT 0x80AB - -/* GetTextureParameter */ -/* GL_TEXTURE_MAG_FILTER */ -/* GL_TEXTURE_MIN_FILTER */ -/* GL_TEXTURE_WRAP_S */ -/* GL_TEXTURE_WRAP_T */ - -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 -#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 - -/* HintMode */ -#define GL_DONT_CARE 0x1100 -#define GL_FASTEST 0x1101 -#define GL_NICEST 0x1102 - -/* HintTarget */ -#define GL_GENERATE_MIPMAP_HINT 0x8192 - -/* DataType */ -#define GL_BYTE 0x1400 -#define GL_UNSIGNED_BYTE 0x1401 -#define GL_SHORT 0x1402 -#define GL_UNSIGNED_SHORT 0x1403 -#define GL_INT 0x1404 -#define GL_UNSIGNED_INT 0x1405 -#define GL_FLOAT 0x1406 -#define GL_FIXED 0x140C - -/* PixelFormat */ -#define GL_DEPTH_COMPONENT 0x1902 -#define GL_ALPHA 0x1906 -#define GL_RGB 0x1907 -#define GL_RGBA 0x1908 -#define GL_LUMINANCE 0x1909 -#define GL_LUMINANCE_ALPHA 0x190A - -/* PixelType */ -/* GL_UNSIGNED_BYTE */ -#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 -#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 -#define GL_UNSIGNED_SHORT_5_6_5 0x8363 - -/* Shaders */ -#define GL_FRAGMENT_SHADER 0x8B30 -#define GL_VERTEX_SHADER 0x8B31 -#define GL_MAX_VERTEX_ATTRIBS 0x8869 -#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB -#define GL_MAX_VARYING_VECTORS 0x8DFC -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C -#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 -#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD -#define GL_SHADER_TYPE 0x8B4F -#define GL_DELETE_STATUS 0x8B80 -#define GL_LINK_STATUS 0x8B82 -#define GL_VALIDATE_STATUS 0x8B83 -#define GL_ATTACHED_SHADERS 0x8B85 -#define GL_ACTIVE_UNIFORMS 0x8B86 -#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 -#define GL_ACTIVE_ATTRIBUTES 0x8B89 -#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A -#define GL_SHADING_LANGUAGE_VERSION 0x8B8C -#define GL_CURRENT_PROGRAM 0x8B8D - -/* StencilFunction */ -#define GL_NEVER 0x0200 -#define GL_LESS 0x0201 -#define GL_EQUAL 0x0202 -#define GL_LEQUAL 0x0203 -#define GL_GREATER 0x0204 -#define GL_NOTEQUAL 0x0205 -#define GL_GEQUAL 0x0206 -#define GL_ALWAYS 0x0207 - -/* StencilOp */ -/* GL_ZERO */ -#define GL_KEEP 0x1E00 -#define GL_REPLACE 0x1E01 -#define GL_INCR 0x1E02 -#define GL_DECR 0x1E03 -#define GL_INVERT 0x150A -#define GL_INCR_WRAP 0x8507 -#define GL_DECR_WRAP 0x8508 - -/* StringName */ -#define GL_VENDOR 0x1F00 -#define GL_RENDERER 0x1F01 -#define GL_VERSION 0x1F02 -#define GL_EXTENSIONS 0x1F03 - -/* TextureMagFilter */ -#define GL_NEAREST 0x2600 -#define GL_LINEAR 0x2601 - -/* TextureMinFilter */ -/* GL_NEAREST */ -/* GL_LINEAR */ -#define GL_NEAREST_MIPMAP_NEAREST 0x2700 -#define GL_LINEAR_MIPMAP_NEAREST 0x2701 -#define GL_NEAREST_MIPMAP_LINEAR 0x2702 -#define GL_LINEAR_MIPMAP_LINEAR 0x2703 - -/* TextureParameterName */ -#define GL_TEXTURE_MAG_FILTER 0x2800 -#define GL_TEXTURE_MIN_FILTER 0x2801 -#define GL_TEXTURE_WRAP_S 0x2802 -#define GL_TEXTURE_WRAP_T 0x2803 - -/* TextureTarget */ -/* GL_TEXTURE_2D */ -#define GL_TEXTURE 0x1702 - -#define GL_TEXTURE_CUBE_MAP 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C - -/* TextureUnit */ -#define GL_TEXTURE0 0x84C0 -#define GL_TEXTURE1 0x84C1 -#define GL_TEXTURE2 0x84C2 -#define GL_TEXTURE3 0x84C3 -#define GL_TEXTURE4 0x84C4 -#define GL_TEXTURE5 0x84C5 -#define GL_TEXTURE6 0x84C6 -#define GL_TEXTURE7 0x84C7 -#define GL_TEXTURE8 0x84C8 -#define GL_TEXTURE9 0x84C9 -#define GL_TEXTURE10 0x84CA -#define GL_TEXTURE11 0x84CB -#define GL_TEXTURE12 0x84CC -#define GL_TEXTURE13 0x84CD -#define GL_TEXTURE14 0x84CE -#define GL_TEXTURE15 0x84CF -#define GL_TEXTURE16 0x84D0 -#define GL_TEXTURE17 0x84D1 -#define GL_TEXTURE18 0x84D2 -#define GL_TEXTURE19 0x84D3 -#define GL_TEXTURE20 0x84D4 -#define GL_TEXTURE21 0x84D5 -#define GL_TEXTURE22 0x84D6 -#define GL_TEXTURE23 0x84D7 -#define GL_TEXTURE24 0x84D8 -#define GL_TEXTURE25 0x84D9 -#define GL_TEXTURE26 0x84DA -#define GL_TEXTURE27 0x84DB -#define GL_TEXTURE28 0x84DC -#define GL_TEXTURE29 0x84DD -#define GL_TEXTURE30 0x84DE -#define GL_TEXTURE31 0x84DF -#define GL_ACTIVE_TEXTURE 0x84E0 - -/* TextureWrapMode */ -#define GL_REPEAT 0x2901 -#define GL_CLAMP_TO_EDGE 0x812F -#define GL_MIRRORED_REPEAT 0x8370 - -/* Uniform Types */ -#define GL_FLOAT_VEC2 0x8B50 -#define GL_FLOAT_VEC3 0x8B51 -#define GL_FLOAT_VEC4 0x8B52 -#define GL_INT_VEC2 0x8B53 -#define GL_INT_VEC3 0x8B54 -#define GL_INT_VEC4 0x8B55 -#define GL_BOOL 0x8B56 -#define GL_BOOL_VEC2 0x8B57 -#define GL_BOOL_VEC3 0x8B58 -#define GL_BOOL_VEC4 0x8B59 -#define GL_FLOAT_MAT2 0x8B5A -#define GL_FLOAT_MAT3 0x8B5B -#define GL_FLOAT_MAT4 0x8B5C -#define GL_SAMPLER_2D 0x8B5E -#define GL_SAMPLER_CUBE 0x8B60 - -/* Vertex Arrays */ -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A -#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F - -/* Read Format */ -#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A -#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B - -/* Shader Source */ -#define GL_COMPILE_STATUS 0x8B81 -#define GL_INFO_LOG_LENGTH 0x8B84 -#define GL_SHADER_SOURCE_LENGTH 0x8B88 -#define GL_SHADER_COMPILER 0x8DFA - -/* Shader Binary */ -#define GL_SHADER_BINARY_FORMATS 0x8DF8 -#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 - -/* Shader Precision-Specified Types */ -#define GL_LOW_FLOAT 0x8DF0 -#define GL_MEDIUM_FLOAT 0x8DF1 -#define GL_HIGH_FLOAT 0x8DF2 -#define GL_LOW_INT 0x8DF3 -#define GL_MEDIUM_INT 0x8DF4 -#define GL_HIGH_INT 0x8DF5 - -/* Framebuffer Object. */ -#define GL_FRAMEBUFFER 0x8D40 -#define GL_RENDERBUFFER 0x8D41 - -#define GL_RGBA4 0x8056 -#define GL_RGB5_A1 0x8057 -#define GL_RGB565 0x8D62 -#define GL_DEPTH_COMPONENT16 0x81A5 -#define GL_STENCIL_INDEX 0x1901 -#define GL_STENCIL_INDEX8 0x8D48 - -#define GL_RENDERBUFFER_WIDTH 0x8D42 -#define GL_RENDERBUFFER_HEIGHT 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 -#define GL_RENDERBUFFER_RED_SIZE 0x8D50 -#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 -#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 -#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 -#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 -#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 - -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 - -#define GL_COLOR_ATTACHMENT0 0x8CE0 -#define GL_DEPTH_ATTACHMENT 0x8D00 -#define GL_STENCIL_ATTACHMENT 0x8D20 - -#define GL_NONE 0 - -#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 -#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD - -#define GL_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_RENDERBUFFER_BINDING 0x8CA7 -#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 - -#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 - -/*------------------------------------------------------------------------- - * GL core functions. - *-----------------------------------------------------------------------*/ - -GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture); -GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader); -GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const char* name); -GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer); -GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); -GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); -GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture); -GL_APICALL void GL_APIENTRY glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); -GL_APICALL void GL_APIENTRY glBlendEquation ( GLenum mode ); -GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); -GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); -GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void* data, GLenum usage); -GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void* data); -GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target); -GL_APICALL void GL_APIENTRY glClear (GLbitfield mask); -GL_APICALL void GL_APIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); -GL_APICALL void GL_APIENTRY glClearDepthf (GLclampf depth); -GL_APICALL void GL_APIENTRY glClearStencil (GLint s); -GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); -GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader); -GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); -GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data); -GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GL_APICALL GLuint GL_APIENTRY glCreateProgram (void); -GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type); -GL_APICALL void GL_APIENTRY glCullFace (GLenum mode); -GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint* buffers); -GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint* framebuffers); -GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program); -GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint* renderbuffers); -GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader); -GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint* textures); -GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func); -GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag); -GL_APICALL void GL_APIENTRY glDepthRangef (GLclampf zNear, GLclampf zFar); -GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader); -GL_APICALL void GL_APIENTRY glDisable (GLenum cap); -GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index); -GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); -GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void* indices); -GL_APICALL void GL_APIENTRY glEnable (GLenum cap); -GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index); -GL_APICALL void GL_APIENTRY glFinish (void); -GL_APICALL void GL_APIENTRY glFlush (void); -GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode); -GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint* buffers); -GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target); -GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers); -GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers); -GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint* textures); -GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name); -GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name); -GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders); -GL_APICALL int GL_APIENTRY glGetAttribLocation (GLuint program, const char* name); -GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params); -GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint* params); -GL_APICALL GLenum GL_APIENTRY glGetError (void); -GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat* params); -GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufsize, GLsizei* length, char* infolog); -GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog); -GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision); -GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufsize, GLsizei* length, char* source); -GL_APICALL const GLubyte* GL_APIENTRY glGetString (GLenum name); -GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat* params); -GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat* params); -GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint* params); -GL_APICALL int GL_APIENTRY glGetUniformLocation (GLuint program, const char* name); -GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat* params); -GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void** pointer); -GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode); -GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer); -GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap); -GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer); -GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program); -GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer); -GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader); -GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture); -GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width); -GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program); -GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param); -GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); -GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels); -GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); -GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -GL_APICALL void GL_APIENTRY glSampleCoverage (GLclampf value, GLboolean invert); -GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); -GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length); -GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const char** string, const GLint* length); -GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); -GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); -GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); -GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); -GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); -GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass); -GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels); -GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); -GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat* params); -GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); -GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint* params); -GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); -GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat x); -GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat* v); -GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint x); -GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint* v); -GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat x, GLfloat y); -GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat* v); -GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint x, GLint y); -GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint* v); -GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat x, GLfloat y, GLfloat z); -GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat* v); -GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint x, GLint y, GLint z); -GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint* v); -GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat* v); -GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint x, GLint y, GLint z, GLint w); -GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint* v); -GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -GL_APICALL void GL_APIENTRY glUseProgram (GLuint program); -GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program); -GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint indx, GLfloat x); -GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint indx, const GLfloat* values); -GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint indx, GLfloat x, GLfloat y); -GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint indx, const GLfloat* values); -GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint indx, GLfloat x, GLfloat y, GLfloat z); -GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint indx, const GLfloat* values); -GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint indx, const GLfloat* values); -GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr); -GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); - -#ifdef __cplusplus -} -#endif - -#endif /* __gl2_h_ */ - diff --git a/o3d/gpu/command_buffer/common/GLES2/gl2platform.h b/o3d/gpu/command_buffer/common/GLES2/gl2platform.h deleted file mode 100644 index 3e9036c..0000000 --- a/o3d/gpu/command_buffer/common/GLES2/gl2platform.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __gl2platform_h_ -#define __gl2platform_h_ - -/* $Revision: 7173 $ on $Date:: 2009-01-09 11:18:21 -0800 #$ */ - -/* - * This document is licensed under the SGI Free Software B License Version - * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . - */ - -/* Platform-specific types and definitions for OpenGL ES 2.X gl2.h - * Last modified on 2008/12/19 - * - * Adopters may modify khrplatform.h and this file to suit their platform. - * You are encouraged to submit all modifications to the Khronos group so that - * they can be included in future versions of this file. Please submit changes - * by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla) - * by filing a bug against product "OpenGL-ES" component "Registry". - */ - -#include - -#ifndef GL_APICALL -#define GL_APICALL KHRONOS_APICALL -#endif - -#define GL_APIENTRY KHRONOS_APIENTRY - -#endif /* __gl2platform_h_ */ diff --git a/o3d/gpu/command_buffer/common/KHR/khrplatform.h b/o3d/gpu/command_buffer/common/KHR/khrplatform.h deleted file mode 100644 index 8341f71b..0000000 --- a/o3d/gpu/command_buffer/common/KHR/khrplatform.h +++ /dev/null @@ -1,269 +0,0 @@ -#ifndef __khrplatform_h_ -#define __khrplatform_h_ - -/* -** Copyright (c) 2008-2009 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ - -/* Khronos platform-specific types and definitions. - * - * $Revision: 7820 $ on $Date: 2009-04-03 13:46:26 -0700 (Fri, 03 Apr 2009) $ - * - * Adopters may modify this file to suit their platform. Adopters are - * encouraged to submit platform specific modifications to the Khronos - * group so that they can be included in future versions of this file. - * Please submit changes by sending them to the public Khronos Bugzilla - * (http://khronos.org/bugzilla) by filing a bug against product - * "Khronos (general)" component "Registry". - * - * A predefined template which fills in some of the bug fields can be - * reached using http://tinyurl.com/khrplatform-h-bugreport, but you - * must create a Bugzilla login first. - * - * - * See the Implementer's Guidelines for information about where this file - * should be located on your system and for more details of its use: - * http://www.khronos.org/registry/implementers_guide.pdf - * - * This file should be included as - * #include - * by Khronos client API header files that use its types and defines. - * - * The types in khrplatform.h should only be used to define API-specific types. - * - * Types defined in khrplatform.h: - * khronos_int8_t signed 8 bit - * khronos_uint8_t unsigned 8 bit - * khronos_int16_t signed 16 bit - * khronos_uint16_t unsigned 16 bit - * khronos_int32_t signed 32 bit - * khronos_uint32_t unsigned 32 bit - * khronos_int64_t signed 64 bit - * khronos_uint64_t unsigned 64 bit - * khronos_intptr_t signed same number of bits as a pointer - * khronos_uintptr_t unsigned same number of bits as a pointer - * khronos_ssize_t signed size - * khronos_usize_t unsigned size - * khronos_float_t signed 32 bit floating point - * khronos_time_ns_t unsigned 64 bit time in nanoseconds - * khronos_utime_nanoseconds_t unsigned time interval or absolute time in - * nanoseconds - * khronos_stime_nanoseconds_t signed time interval in nanoseconds - * khronos_boolean_enum_t enumerated boolean type. This should - * only be used as a base type when a client API's boolean type is - * an enum. Client APIs which use an integer or other type for - * booleans cannot use this as the base type for their boolean. - * - * Tokens defined in khrplatform.h: - * - * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. - * - * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. - * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. - * - * Calling convention macros defined in this file: - * KHRONOS_APICALL - * KHRONOS_APIENTRY - * KHRONOS_APIATTRIBUTES - * - * These may be used in function prototypes as: - * - * KHRONOS_APICALL void KHRONOS_APIENTRY funcname( - * int arg1, - * int arg2) KHRONOS_APIATTRIBUTES; - */ - -/*------------------------------------------------------------------------- - * Definition of KHRONOS_APICALL - *------------------------------------------------------------------------- - * This precedes the return type of the function in the function prototype. - */ -#if defined(_WIN32) && !defined(__SCITECH_SNAP__) -# define KHRONOS_APICALL __declspec(dllimport) -#elif defined (__SYMBIAN32__) -# define KHRONOS_APICALL IMPORT_C -#else -# define KHRONOS_APICALL -#endif - -/*------------------------------------------------------------------------- - * Definition of KHRONOS_APIENTRY - *------------------------------------------------------------------------- - * This follows the return type of the function and precedes the function - * name in the function prototype. - */ -#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) - /* Win32 but not WinCE */ -# define KHRONOS_APIENTRY __stdcall -#else -# define KHRONOS_APIENTRY -#endif - -/*------------------------------------------------------------------------- - * Definition of KHRONOS_APIATTRIBUTES - *------------------------------------------------------------------------- - * This follows the closing parenthesis of the function prototype arguments. - */ -#if defined (__ARMCC_2__) -#define KHRONOS_APIATTRIBUTES __softfp -#else -#define KHRONOS_APIATTRIBUTES -#endif - -/*------------------------------------------------------------------------- - * basic type definitions - *-----------------------------------------------------------------------*/ -#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) - - -/* - * Using - */ -#include -typedef int32_t khronos_int32_t; -typedef uint32_t khronos_uint32_t; -typedef int64_t khronos_int64_t; -typedef uint64_t khronos_uint64_t; -#define KHRONOS_SUPPORT_INT64 1 -#define KHRONOS_SUPPORT_FLOAT 1 - -#elif defined(__VMS ) || defined(__sgi) - -/* - * Using - */ -#include -typedef int32_t khronos_int32_t; -typedef uint32_t khronos_uint32_t; -typedef int64_t khronos_int64_t; -typedef uint64_t khronos_uint64_t; -#define KHRONOS_SUPPORT_INT64 1 -#define KHRONOS_SUPPORT_FLOAT 1 - -#elif defined(_WIN32) && !defined(__SCITECH_SNAP__) - -/* - * Win32 - */ -typedef __int32 khronos_int32_t; -typedef unsigned __int32 khronos_uint32_t; -typedef __int64 khronos_int64_t; -typedef unsigned __int64 khronos_uint64_t; -#define KHRONOS_SUPPORT_INT64 1 -#define KHRONOS_SUPPORT_FLOAT 1 - -#elif defined(__sun__) || defined(__digital__) - -/* - * Sun or Digital - */ -typedef int khronos_int32_t; -typedef unsigned int khronos_uint32_t; -#if defined(__arch64__) || defined(_LP64) -typedef long int khronos_int64_t; -typedef unsigned long int khronos_uint64_t; -#else -typedef long long int khronos_int64_t; -typedef unsigned long long int khronos_uint64_t; -#endif /* __arch64__ */ -#define KHRONOS_SUPPORT_INT64 1 -#define KHRONOS_SUPPORT_FLOAT 1 - -#elif 0 - -/* - * Hypothetical platform with no float or int64 support - */ -typedef int khronos_int32_t; -typedef unsigned int khronos_uint32_t; -#define KHRONOS_SUPPORT_INT64 0 -#define KHRONOS_SUPPORT_FLOAT 0 - -#else - -/* - * Generic fallback - */ -#include -typedef int32_t khronos_int32_t; -typedef uint32_t khronos_uint32_t; -typedef int64_t khronos_int64_t; -typedef uint64_t khronos_uint64_t; -#define KHRONOS_SUPPORT_INT64 1 -#define KHRONOS_SUPPORT_FLOAT 1 - -#endif - - -/* - * Types that are (so far) the same on all platforms - */ -typedef signed char khronos_int8_t; -typedef unsigned char khronos_uint8_t; -typedef signed short int khronos_int16_t; -typedef unsigned short int khronos_uint16_t; -typedef signed long int khronos_intptr_t; -typedef unsigned long int khronos_uintptr_t; -typedef signed long int khronos_ssize_t; -typedef unsigned long int khronos_usize_t; - -#if KHRONOS_SUPPORT_FLOAT -/* - * Float type - */ -typedef float khronos_float_t; -#endif - -#if KHRONOS_SUPPORT_INT64 -/* Time types - * - * These types can be used to represent a time interval in nanoseconds or - * an absolute Unadjusted System Time. Unadjusted System Time is the number - * of nanoseconds since some arbitrary system event (e.g. since the last - * time the system booted). The Unadjusted System Time is an unsigned - * 64 bit value that wraps back to 0 every 584 years. Time intervals - * may be either signed or unsigned. - */ -typedef khronos_uint64_t khronos_utime_nanoseconds_t; -typedef khronos_int64_t khronos_stime_nanoseconds_t; -#endif - -/* - * Dummy value used to pad enum types to 32 bits. - */ -#ifndef KHRONOS_MAX_ENUM -#define KHRONOS_MAX_ENUM 0x7FFFFFFF -#endif - -/* - * Enumerated boolean type - * - * Values other than zero should be considered to be true. Therefore - * comparisons should not be made against KHRONOS_TRUE. - */ -typedef enum { - KHRONOS_FALSE = 0, - KHRONOS_TRUE = 1, - KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM -} khronos_boolean_enum_t; - -#endif /* __khrplatform_h_ */ diff --git a/o3d/gpu/command_buffer/common/bitfield_helpers.h b/o3d/gpu/command_buffer/common/bitfield_helpers.h deleted file mode 100644 index b74374d..0000000 --- a/o3d/gpu/command_buffer/common/bitfield_helpers.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains a helper template class used to access bit fields in -// unsigned int_ts. - -#ifndef GPU_COMMAND_BUFFER_COMMON_CROSS_BITFIELD_HELPERS_H_ -#define GPU_COMMAND_BUFFER_COMMON_CROSS_BITFIELD_HELPERS_H_ - -namespace command_buffer { - -// Bitfield template class, used to access bit fields in unsigned int_ts. -template class BitField { - public: - static const unsigned int kShift = shift; - static const unsigned int kLength = length; - // the following is really (1<> kShift) & kMask; - } - - // Makes a value that can be or-ed into this field. - static unsigned int MakeValue(unsigned int value) { - return (value & kMask) << kShift; - } - - // Changes the value of this field. - static void Set(unsigned int *container, unsigned int field_value) { - *container = (*container & ~(kMask << kShift)) | MakeValue(field_value); - } -}; - -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_COMMON_CROSS_BITFIELD_HELPERS_H_ diff --git a/o3d/gpu/command_buffer/common/bitfield_helpers_test.cc b/o3d/gpu/command_buffer/common/bitfield_helpers_test.cc deleted file mode 100644 index 60014d2..0000000 --- a/o3d/gpu/command_buffer/common/bitfield_helpers_test.cc +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// Tests for the bitfield helper class. - -#include "gtest/gtest.h" -#include "gpu/command_buffer/common/bitfield_helpers.h" - -namespace command_buffer { - -// Tests that BitField<>::Get returns the right bits. -TEST(BitFieldTest, TestGet) { - unsigned int value = 0x12345678u; - EXPECT_EQ(0x8u, (BitField<0, 4>::Get(value))); - EXPECT_EQ(0x45u, (BitField<12, 8>::Get(value))); - EXPECT_EQ(0x12345678u, (BitField<0, 32>::Get(value))); -} - -// Tests that BitField<>::MakeValue generates the right bits. -TEST(BitFieldTest, TestMakeValue) { - EXPECT_EQ(0x00000003u, (BitField<0, 4>::MakeValue(0x3))); - EXPECT_EQ(0x00023000u, (BitField<12, 8>::MakeValue(0x123))); - EXPECT_EQ(0x87654321u, (BitField<0, 32>::MakeValue(0x87654321))); -} - -// Tests that BitField<>::Set modifies the right bits. -TEST(BitFieldTest, TestSet) { - unsigned int value = 0x12345678u; - BitField<0, 4>::Set(&value, 0x9); - EXPECT_EQ(0x12345679u, value); - BitField<12, 8>::Set(&value, 0x123); - EXPECT_EQ(0x12323679u, value); - BitField<0, 32>::Set(&value, 0x87654321); - EXPECT_EQ(0x87654321u, value); -} - -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/common/cmd_buffer_common.cc b/o3d/gpu/command_buffer/common/cmd_buffer_common.cc deleted file mode 100644 index e9172eb..0000000 --- a/o3d/gpu/command_buffer/common/cmd_buffer_common.cc +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the binary format definition of the command buffer and -// command buffer commands. - -#include "gpu/command_buffer/common/cmd_buffer_common.h" - -namespace command_buffer { -namespace cmd { - -const char* GetCommandName(CommandId command_id) { - static const char* const names[] = { - #define COMMON_COMMAND_BUFFER_CMD_OP(name) # name, - - COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP) - - #undef COMMON_COMMAND_BUFFER_CMD_OP - }; - - int id = static_cast(command_id); - return (id >= 0 && id < kNumCommands) ? names[id] : "*unknown-command*"; -} - -} // namespace cmd -} // namespace command_buffer - - diff --git a/o3d/gpu/command_buffer/common/cmd_buffer_common.h b/o3d/gpu/command_buffer/common/cmd_buffer_common.h deleted file mode 100644 index 0e44f86..0000000 --- a/o3d/gpu/command_buffer/common/cmd_buffer_common.h +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the common parts of command buffer formats. - -#ifndef GPU_COMMAND_BUFFER_COMMON_CROSS_CMD_BUFFER_COMMON_H_ -#define GPU_COMMAND_BUFFER_COMMON_CROSS_CMD_BUFFER_COMMON_H_ - -#include "base/basictypes.h" -#include "gpu/command_buffer/common/types.h" -#include "gpu/command_buffer/common/bitfield_helpers.h" -#include "gpu/command_buffer/common/logging.h" - -namespace command_buffer { - -namespace cmd { - enum ArgFlags { - kFixed = 0x0, - kAtLeastN = 0x1, - }; -} // namespace cmd - -// Computes the number of command buffer entries needed for a certain size. In -// other words it rounds up to a multiple of entries. -inline uint32 ComputeNumEntries(size_t size_in_bytes) { - return static_cast( - (size_in_bytes + sizeof(uint32) - 1) / sizeof(uint32)); // NOLINT -} - -// Rounds up to a multiple of entries in bytes. -inline size_t RoundSizeToMultipleOfEntries(size_t size_in_bytes) { - return ComputeNumEntries(size_in_bytes) * sizeof(uint32); // NOLINT -} - -// Struct that defines the command header in the command buffer. -struct CommandHeader { - Uint32 size:8; - Uint32 command:24; - - void Init(uint32 _command, uint32 _size) { - DCHECK_LT(_size, 256u); - command = _command; - size = _size; - } - - // Sets the header based on the passed in command. Can not be used for - // variable sized commands like immediate commands or Noop. - template - void SetCmd() { - COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed); - Init(T::kCmdId, ComputeNumEntries(sizeof(T))); // NOLINT - } - - // Sets the header by a size in bytes. - template - void SetCmdBySize(uint32 size_in_bytes) { - COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); - Init(T::kCmdId, ComputeNumEntries(sizeof(T) + size_in_bytes)); // NOLINT - } -}; - -COMPILE_ASSERT(sizeof(CommandHeader) == 4, Sizeof_CommandHeader_is_not_4); - -// Union that defines possible command buffer entries. -union CommandBufferEntry { - CommandHeader value_header; - Uint32 value_uint32; - Int32 value_int32; - float value_float; -}; - -COMPILE_ASSERT(sizeof(CommandBufferEntry) == 4, - Sizeof_CommandBufferEntry_is_not_4); - - -// Make sure the compiler does not add extra padding to any of the command -// structures. -#pragma pack(push, 1) - -// Gets the address of memory just after a structure in a typesafe way. This is -// used for IMMEDIATE commands to get the address of the place to put the data. -// Immediate command put their data direclty in the command buffer. -// Parameters: -// cmd: Address of command. -template -void* ImmediateDataAddress(T* cmd) { - COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); - return reinterpret_cast(cmd) + sizeof(*cmd); -} - -// Gets the address of the place to put the next command in a typesafe way. -// This can only be used for fixed sized commands. -template -// Parameters: -// cmd: Address of command. -void* NextCmdAddress(void* cmd) { - COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed); - return reinterpret_cast(cmd) + sizeof(T); -} - -// Gets the address of the place to put the next command in a typesafe way. -// This can only be used for variable sized command like IMMEDIATE commands. -// Parameters: -// cmd: Address of command. -// size_of_data_in_bytes: Size of the data for the command. -template -void* NextImmediateCmdAddress(void* cmd, uint32 size_of_data_in_bytes) { - COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); - return reinterpret_cast(cmd) + sizeof(T) + // NOLINT - RoundSizeToMultipleOfEntries(size_of_data_in_bytes); -} - -struct SharedMemory { - void Init(uint32 _id, uint32 _offset) { - id = _id; - offset = _offset; - } - - uint32 id; - uint32 offset; -}; - -COMPILE_ASSERT(offsetof(SharedMemory, id) == 0, - Offsetof_SharedMemory_id_not_0); -COMPILE_ASSERT(offsetof(SharedMemory, offset) == 4, - Offsetof_SharedMemory_offset_not_4); - - -namespace cmd { - -// This macro is used to safely and convienently expand the list of commnad -// buffer commands in to various lists and never have them get out of sync. To -// add a new command, add it this list, create the corresponding structure below -// and then add a function in gapi_decoder.cc called Handle_COMMAND_NAME where -// COMMAND_NAME is the name of your command structure. -// -// NOTE: THE ORDER OF THESE MUST NOT CHANGE (their id is derived by order) -#define COMMON_COMMAND_BUFFER_CMDS(OP) \ - OP(Noop) /* 0 */ \ - OP(SetToken) /* 1 */ \ - -// Common commands. -enum CommandId { - #define COMMON_COMMAND_BUFFER_CMD_OP(name) k ## name, - - COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP) - - #undef COMMON_COMMAND_BUFFER_CMD_OP - - kNumCommands, - kLastCommonId = 1023, // reserve 1024 spaces for common commands. -}; - -COMPILE_ASSERT(kNumCommands - 1 <= kLastCommonId, Too_many_common_commands); - -const char* GetCommandName(CommandId id); - -struct Noop { - typedef Noop ValueType; - static const CommandId kCmdId = kNoop; - static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; - - void SetHeader(uint32 skip_count) { - header.Init(kCmdId, skip_count + 1); - } - - void Init(uint32 skip_count) { - SetHeader(skip_count); - } - - static void* Set(void* cmd, uint32 skip_count) { - static_cast(cmd)->Init(skip_count); - return NextImmediateCmdAddress( - cmd, skip_count * sizeof(CommandBufferEntry)); // NOLINT - } - - CommandHeader header; -}; - -COMPILE_ASSERT(sizeof(Noop) == 4, Sizeof_Noop_is_not_4); -COMPILE_ASSERT(offsetof(Noop, header) == 0, Offsetof_Noop_header_not_0); - -struct SetToken { - typedef SetToken ValueType; - static const CommandId kCmdId = kSetToken; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(uint32 _token) { - SetHeader(); - token = _token; - } - static void* Set(void* cmd, uint32 token) { - static_cast(cmd)->Init(token); - return NextCmdAddress(cmd); - } - - CommandHeader header; - uint32 token; -}; - -COMPILE_ASSERT(sizeof(SetToken) == 8, Sizeof_SetToken_is_not_8); -COMPILE_ASSERT(offsetof(SetToken, header) == 0, - Offsetof_SetToken_header_not_0); -COMPILE_ASSERT(offsetof(SetToken, token) == 4, - Offsetof_SetToken_token_not_4); - -} // namespace cmd - -#pragma pack(pop) - -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_COMMON_CROSS_CMD_BUFFER_COMMON_H_ - diff --git a/o3d/gpu/command_buffer/common/constants.h b/o3d/gpu/command_buffer/common/constants.h deleted file mode 100644 index ee874cd..0000000 --- a/o3d/gpu/command_buffer/common/constants.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -#ifndef O3D_COMMAND_BUFFER_COMMON_CROSS_CONSTANTS_H_ -#define O3D_COMMAND_BUFFER_COMMON_CROSS_CONSTANTS_H_ - -#include "base/basictypes.h" - -namespace command_buffer { - -typedef int32 CommandBufferOffset; -const CommandBufferOffset kInvalidCommandBufferOffset = -1; - -// Status of the command buffer service. It does not process commands -// (meaning: get will not change) unless in kParsing state. -namespace parser_status { - enum ParserStatus { - kNotConnected, // The service is not connected - initial state. - kNoBuffer, // The service is connected but no buffer was set. - kParsing, // The service is connected, and parsing commands from the - // buffer. - kParseError, // Parsing stopped because a parse error was found. - }; -} - -namespace parse_error { - enum ParseError { - kParseNoError, - kParseInvalidSize, - kParseOutOfBounds, - kParseUnknownCommand, - kParseInvalidArguments, - }; -} - -// Invalid shared memory Id, returned by RegisterSharedMemory in case of -// failure. -const int32 kInvalidSharedMemoryId = -1; - -} // namespace command_buffer - -#endif // O3D_COMMAND_BUFFER_COMMON_CROSS_CONSTANTS_H_ diff --git a/o3d/gpu/command_buffer/common/gapi_interface.h b/o3d/gpu/command_buffer/common/gapi_interface.h deleted file mode 100644 index a032f0e..0000000 --- a/o3d/gpu/command_buffer/common/gapi_interface.h +++ /dev/null @@ -1,833 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the interface class for the low-level graphics API -// (GAPI). - -#ifndef GPU_COMMAND_BUFFER_COMMON_CROSS_GAPI_INTERFACE_H_ -#define GPU_COMMAND_BUFFER_COMMON_CROSS_GAPI_INTERFACE_H_ - -#include "gpu/command_buffer/common/constants.h" -#include "gpu/command_buffer/common/resource.h" -#include "gpu/command_buffer/common/o3d_cmd_format.h" - -namespace command_buffer { -namespace o3d { - -// RBGA color definition. -struct RGBA { - float red; - float green; - float blue; - float alpha; -}; - -// This class defines the low-level graphics API, as a pure interface class. -class GAPIInterface { - public: - typedef parse_error::ParseError ParseError; - - GAPIInterface() {} - virtual ~GAPIInterface() {} - - // Initializes the graphics context. - // Returns: - // true if successful. - virtual bool Initialize() = 0; - - // Destroys the graphics context. - virtual void Destroy() = 0; - - // Starts a frame. Rendering should occur between BeginFrame and EndFrame. - virtual void BeginFrame() = 0; - - // Ends the frame, and bring the back buffer to front. Rendering should occur - // between BeginFrame and EndFrame. - virtual void EndFrame() = 0; - - // Clear buffers, filling them with a constant value. - // Parameters: - // buffers: which buffers to clear. Can be a combination (bitwise or) of - // values from ClearBuffer. - // color: the RGBA color to clear the color target with. - // depth: the depth to clear the depth buffer with. - // stencil: the stencil value to clear the stencil buffer with. - virtual void Clear(unsigned int buffers, - const RGBA &color, - float depth, - unsigned int stencil) = 0; - - // Creates a vertex buffer. - // Parameters: - // id: the resource ID for the new vertex buffer. - // size: the size of the vertex buffer, in bytes. - // flags: the vertex buffer flags, as a combination of vertex_buffer::Flags - // Returns: - // parse_error::kParseInvalidArguments if invalid arguments are - // passed, parse_error::kParseNoError otherwise. - virtual ParseError CreateVertexBuffer(ResourceId id, - unsigned int size, - unsigned int flags) = 0; - - // Destroys a vertex buffer. - // Parameters: - // id: the resource ID of the vertex buffer. - // Returns: - // parse_error::kParseInvalidArguments if an invalid vertex buffer - // ID was passed, parse_error::kParseNoError otherwise. - virtual ParseError DestroyVertexBuffer(ResourceId id) = 0; - - // Sets data into a vertex buffer. - // Parameters: - // id: the resource ID of the vertex buffer. - // offset: the offset into the vertex buffer where to place the data. - // size: the size of the data. - // data: the source data. - // Returns: - // parse_error::kParseInvalidArguments if invalid arguments were - // passed: invalid resource ID, or offset or size out of range. - // parse_error::kParseNoError otherwise. - virtual ParseError SetVertexBufferData(ResourceId id, - unsigned int offset, - unsigned int size, - const void *data) = 0; - - // Gets data from a vertex buffer. - // Parameters: - // id: the resource ID of the vertex buffer. - // offset: the offset into the vertex buffer where to get the data. - // size: the size of the data. - // data: the destination buffer. - // Returns: - // parse_error::kParseInvalidArguments if invalid arguments were - // passed: invalid resource ID, or offset or size out of range. - // parse_error::kParseNoError otherwise. - virtual ParseError GetVertexBufferData(ResourceId id, - unsigned int offset, - unsigned int size, - void *data) = 0; - - // Creates an index buffer. - // Parameters: - // id: the resource ID for the new index buffer. - // size: the size of the index buffer, in bytes. - // flags: the index buffer flags, as a combination of index_buffer::Flags. - // Note that indices are 16 bits unless the index_buffer::INDEX_32BIT - // flag is specified. - // Returns: - // parse_error::kParseInvalidArguments if invalid arguments are - // passed, parse_error::kParseNoError otherwise. - virtual ParseError CreateIndexBuffer(ResourceId id, - unsigned int size, - unsigned int flags) = 0; - - // Destroys an index buffer. - // Parameters: - // id: the resource ID of the index buffer. - // Returns: - // parse_error::kParseInvalidArguments if an invalid index buffer - // ID was passed, parse_error::kParseNoError otherwise. - virtual ParseError DestroyIndexBuffer(ResourceId id) = 0; - - // Sets data into an index buffer. - // Parameters: - // id: the resource ID of the index buffer. - // offset: the offset into the index buffer where to place the data. - // size: the size of the data. - // data: the source data. - // Returns: - // parse_error::kParseInvalidArguments if invalid arguments were - // passed: invalid resource ID, or offset or size out of range. - // parse_error::kParseNoError otherwise. - virtual ParseError SetIndexBufferData(ResourceId id, - unsigned int offset, - unsigned int size, - const void *data) = 0; - - // Gets data from an index buffer. - // Parameters: - // id: the resource ID of the index buffer. - // offset: the offset into the index buffer where to get the data. - // size: the size of the data. - // data: the destination buffer. - // Returns: - // parse_error::kParseInvalidArguments if invalid arguments were - // passed: invalid resource ID, or offset or size out of range. - // parse_error::kParseNoError otherwise. - virtual ParseError GetIndexBufferData(ResourceId id, - unsigned int offset, - unsigned int size, - void *data) = 0; - - // Creates a vertex struct. A vertex struct describes the input vertex - // attribute streams. - // Parameters: - // id: the resource ID of the vertex struct. - // input_count: the number of input vertex attributes. - // returns: - // parse_error::kParseInvalidArguments if invalid arguments are - // passed, parse_error::kParseNoError otherwise. - virtual ParseError CreateVertexStruct(ResourceId id, - unsigned int input_count) = 0; - - // Destroys a vertex struct. - // Parameters: - // id: the resource ID of the vertex struct. - // Returns: - // parse_error::kParseInvalidArguments if an invalid vertex struct - // ID was passed, parse_error::kParseNoError otherwise. - virtual ParseError DestroyVertexStruct(ResourceId id) = 0; - - // Sets an input into a vertex struct. - // Parameters: - // vertex_struct_id: the resource ID of the vertex struct. - // input_index: the index of the input being set. - // vertex_buffer_id: the resource ID of the vertex buffer containing the - // data. - // offset: the offset into the vertex buffer of the input data, in bytes. - // stride: the stride of the input data, in bytes. - // type: the type of the input data. - // semantic: the semantic of the input. - // semantic_index: the semantic index of the input. - // Returns: - // parse_error::kParseInvalidArguments if invalid arguments are - // passed, parse_error::kParseNoError otherwise. - virtual ParseError SetVertexInput(ResourceId vertex_struct_id, - unsigned int input_index, - ResourceId vertex_buffer_id, - unsigned int offset, - unsigned int stride, - vertex_struct::Type type, - vertex_struct::Semantic semantic, - unsigned int semantic_index) = 0; - - // Sets the current vertex struct for drawing. - // Parameters: - // id: the resource ID of the vertex struct. - // Returns: - // parse_error::kParseInvalidArguments if invalid arguments are - // passed (invalid vertex struct), parse_error::kParseNoError - // otherwise. - virtual ParseError SetVertexStruct(ResourceId id) = 0; - - // Draws primitives, using the current vertex struct and the current effect. - // Parameters: - // primitive_type: the type of primitive to draw. - // first: the index of the first vertex. - // count: the number of primitives to draw. - // Returns: - // parse_error::kParseInvalidArguments if invalid arguments are - // passed, parse_error::kParseNoError otherwise. - virtual ParseError Draw(PrimitiveType primitive_type, - unsigned int first, - unsigned int count) = 0; - - // Draws primitives, using the current vertex struct and the current effect, - // as well as an index buffer. - // Parameters: - // primitive_type: the type of primitive to draw. - // index_buffer_id: the resource ID of the index buffer. - // first: the index into the index buffer of the first index to draw. - // count: the number of primitives to draw. - // min_index: the lowest index being drawn. - // max_index: the highest index being drawn. - // Returns: - // parse_error::kParseInvalidArguments if invalid arguments are - // passed, parse_error::kParseNoError otherwise. - virtual ParseError DrawIndexed(PrimitiveType primitive_type, - ResourceId index_buffer_id, - unsigned int first, - unsigned int count, - unsigned int min_index, - unsigned int max_index) = 0; - - // Creates an effect, from source code. - // Parameters: - // id: the resource ID of the effect. - // size: the size of data. - // data: the source code for the effect. - // Returns: - // parse_error::kParseInvalidArguments if invalid arguments are - // passed or the effect failed to compile, - // parse_error::kParseNoError otherwise. - virtual ParseError CreateEffect(ResourceId id, - unsigned int size, - const void *data) = 0; - - // Destroys an effect. - // Parameters: - // id: the resource ID of the effect. - // Returns: - // parse_error::kParseInvalidArguments if an invalid effect ID - // was passed, parse_error::kParseNoError otherwise. - virtual ParseError DestroyEffect(ResourceId id) = 0; - - // Sets the active effect for drawing. - // Parameters: - // id: the resource ID of the effect. - // Returns: - // parse_error::kParseInvalidArguments if invalid arguments are - // passed, parse_error::kParseNoError otherwise. - virtual ParseError SetEffect(ResourceId id) = 0; - - // Gets the number of parameters in an effect, returning it in a memory - // buffer as a Uint32. - // Parameters: - // id: the resource ID of the effect. - // size: the size of the data buffer. Must be at least 4 (the size of the - // Uint32). - // data: the buffer receiving the data. - // Returns: - // parse_error::kParseInvalidArguments if invalid arguments are - // passed, parse_error::kParseNoError otherwise. - virtual ParseError GetParamCount(ResourceId id, - unsigned int size, - void *data) = 0; - - // Creates an effect parameter by index. - // Parameters: - // param_id: the resource ID of the parameter being created. - // effect_id: the resource ID of the effect containing the parameter. - // data_type: the data type for the parameter. Must match the data type in - // the effect source. - // index: the index of the parameter. - // Returns: - // parse_error::kParseInvalidArguments if invalid arguments are - // passed, such as invalid effect ID, unmatching data type or invalid - // index, parse_error::kParseNoError otherwise. - virtual ParseError CreateParam(ResourceId param_id, - ResourceId effect_id, - unsigned int index) = 0; - - // Creates an effect parameter by name. - // Parameters: - // param_id: the resource ID of the parameter being created. - // effect_id: the resource ID of the effect containing the parameter. - // data_type: the data type for the parameter. Must match the data type in - // the effect source. - // size: the size of the parameter name. - // name: the parameter name, as an array of char. Doesn't have to be - // nul-terminated (though nul will terminate the string). - // Returns: - // parse_error::kParseInvalidArguments if invalid arguments are - // passed, such as invalid effect ID, unmatching data type or no parameter - // was found with this name, parse_error::kParseNoError otherwise. - virtual ParseError CreateParamByName(ResourceId param_id, - ResourceId effect_id, - unsigned int size, - const void *name) = 0; - - // Destroys an effect parameter. - // Parameters: - // id: the resource ID of the parameter. - // Returns: - // parse_error::kParseInvalidArguments if an invalid parameter ID - // was passed, parse_error::kParseNoError otherwise. - virtual ParseError DestroyParam(ResourceId id) = 0; - - // Sets the effect parameter data. - // Parameters: - // id: the resource ID of the parameter. - // size: the size of the data. Must be at least the size of the parameter - // as described by its type. - // data: the parameter data. - // parse_error::kParseInvalidArguments if invalid arguments are - // passed, such as invalid parameter ID, or unmatching data size, - // parse_error::kParseNoError otherwise. - virtual ParseError SetParamData(ResourceId id, - unsigned int size, - const void *data) = 0; - - // Gets the parameter description, storing it into a memory buffer. The - // parameter is described by a effect_param::Desc structure. The size must be - // at least the size of that structure. The name and semantic fields are only - // filled if the character strings fit into the memory buffer. In any case, - // the size field (in the effect_param::Desc) is filled with the size needed - // to fill in the structure, the name and the semantic (if any). Thus to get - // the complete information, GetParamDesc can be called twice, once to get - // the size, and, after allocating a big enough buffer, again to fill in the - // complete information including the text strings. - // Parameters: - // id: the resource ID of the parameter. - // size: the size of the memory buffer that wil receive the parameter - // description. Must be at least sizeof(effect_param::Desc). - // data: the memory buffer. - // Returns: - // parse_error::kParseInvalidArguments if invalid arguments are - // passed, such as invalid parameter ID, or unsufficient data size, - // parse_error::kParseNoError otherwise. Note that - // parse_error::kParseNoError will be returned if the structure - // itself fits, not necessarily the names. To make sure all the information - // is available, the caller should compare the returned size member of the - // effect_param::Desc structure to the size parameter passed in. - virtual ParseError GetParamDesc(ResourceId id, - unsigned int size, - void *data) = 0; - - // Gets the number of input streams for an effect, returning it in a memory - // buffer as a Uint32. - // Parameters: - // id: the resource ID of the effect. - // size: the size of the data buffer. Must be at least 4 (the size of the - // Uint32). - // data: the buffer receiving the data. - // Returns: - // parse_error::kParseInvalidArguments if invalid arguments are - // passed, parse_error::kParseNoError otherwise. - virtual ParseError GetStreamCount(ResourceId id, - unsigned int size, - void *data) = 0; - - // Gets the stream semantics, storing them in the data buffer. The stream - // is described by an effect_stream::Desc structure which contains a - // semantic type and a semantic index. - // Parameters: - // id: the resource ID of the effect. - // index: which stream semantic to get - // size: the size of the data buffer. Must be at least 8 (the size of two - // Uint32). - // data: the buffer receiving the data. - virtual ParseError GetStreamDesc(ResourceId id, - unsigned int index, - unsigned int size, - void *data) = 0; - - // Creates a 2D texture resource. - // Parameters: - // id: the resource ID of the texture. - // width: the texture width. Must be positive. - // height: the texture height. Must be positive. - // levels: the number of mipmap levels in the texture, or 0 to use the - // maximum. - // format: the format of the texels in the texture. - // flags: the texture flags, as a combination of texture::Flags. - // enable_render_surfaces: bool for whether to enable render surfaces - // Returns: - // parse_error::kParseInvalidArguments if invalid arguments are - // passed, parse_error::kParseNoError otherwise. - virtual ParseError CreateTexture2D(ResourceId id, - unsigned int width, - unsigned int height, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces) = 0; - - // Creates a 3D texture resource. - // Parameters: - // id: the resource ID of the texture. - // width: the texture width. Must be positive. - // height: the texture height. Must be positive. - // depth: the texture depth. Must be positive. - // levels: the number of mipmap levels in the texture, or 0 to use the - // maximum. - // format: the format of the pixels in the texture. - // flags: the texture flags, as a combination of texture::Flags. - // enable_render_surfaces: bool for whether to enable render surfaces - // Returns: - // parse_error::kParseInvalidArguments if invalid arguments are - // passed, parse_error::kParseNoError otherwise. - virtual ParseError CreateTexture3D(ResourceId id, - unsigned int width, - unsigned int height, - unsigned int depth, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces) = 0; - - // Creates a cube map texture resource. - // Parameters: - // id: the resource ID of the texture. - // side: the texture side length. Must be positive. - // levels: the number of mipmap levels in the texture, or 0 to use the - // maximum. - // format: the format of the pixels in the texture. - // flags: the texture flags, as a combination of texture::Flags. - // enable_render_surfaces: bool for whether to enable render surfaces - // Returns: - // parse_error::kParseInvalidArguments if invalid arguments are - // passed, parse_error::kParseNoError otherwise. - virtual ParseError CreateTextureCube(ResourceId id, - unsigned int side, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces) = 0; - - // Sets texel data into a texture resource. This is a common function for - // each of the texture types, but some restrictions exist based on the - // texture type. The specified rectangle or volume of data, defined by x, y, - // width, height and possibly z and depth must fit into the selected mimmap - // level. Data is encoded by rows of 2D blocks, whose size depends on the - // texel format, usually 1x1 texel, but can be 4x4 for DXT* formats. See - // texture::GetBytesPerBlock, texture::GetBlockSizeX and - // texture::GetBlockSizeY. - // Parameters: - // id: the resource ID of the texture. - // x: the x position of the texel corresponding to the first byte of data. - // y: the y position of the texel corresponding to the first byte of data. - // z: the z position of the texel corresponding to the first byte of data. - // Must be 0 for non-3D textures. - // width: the width of the data rectangle/volume. - // height: the height of the data rectangle/volume. - // depth: the depth of the data volume. Must be 1 for non-3D textures. - // level: the mipmap level to put the data into. - // face: which face of the cube to put the data into. Is ignored for - // non-cube map textures. - // row_pitch: the number of bytes between two consecutive rows of blocks, - // in the source data. - // slice_pitch: the number of bytes between two consecutive slices of - // blocks, in the source data. Is ignored for non-3D textures. - // size: the size of the data. - // data: the texel data. - // Returns: - // parse_error::kParseInvalidArguments if invalid arguments are - // passed, for example invalid size, or out-of-bounds rectangle/volume, - // parse_error::kParseNoError otherwise. - virtual ParseError SetTextureData(ResourceId id, - unsigned int x, - unsigned int y, - unsigned int z, - unsigned int width, - unsigned int height, - unsigned int depth, - unsigned int level, - texture::Face face, - unsigned int pitch, - unsigned int slice_pitch, - unsigned int size, - const void *data) = 0; - - // Gets texel data from a texture resource. This is a common function for - // each of the texture types, but some restrictions exist based on the - // texture type. The specified rectangle or volume of data, defined by x, y, - // width, height and possibly z and depth must fit into the selected mimmap - // level. Data is encoded by rows of 2D blocks, whose size depends on the - // texel format, usually 1x1 texel, but can be 4x4 for DXT* formats. See - // texture::GetBytesPerBlock, texture::GetBlockSizeX and - // texture::GetBlockSizeY. - // Parameters: - // id: the resource ID of the texture. - // x: the x position of the texel corresponding to the first byte of data. - // y: the y position of the texel corresponding to the first byte of data. - // z: the z position of the texel corresponding to the first byte of data. - // Must be 0 for non-3D textures. - // width: the width of the data rectangle/volume. - // height: the height of the data rectangle/volume. - // depth: the depth of the data volume. Must be 1 for non-3D textures. - // level: the mipmap level to put the data into. - // face: which face of the cube to put the data into. Is ignored for - // non-cube map textures. - // row_pitch: the number of bytes between two consecutive rows of blocks, - // in the destination buffer. - // slice_pitch: the number of bytes between two consecutive slices of - // blocks, in the destination buffer. Is ignored for non-3D textures. - // size: the size of the data. - // data: the destination buffer. - // Returns: - // parse_error::kParseInvalidArguments if invalid arguments are - // passed, for example invalid size, or out-of-bounds rectangle/volume, - // parse_error::kParseNoError otherwise. - virtual ParseError GetTextureData(ResourceId id, - unsigned int x, - unsigned int y, - unsigned int z, - unsigned int width, - unsigned int height, - unsigned int depth, - unsigned int level, - texture::Face face, - unsigned int pitch, - unsigned int slice_pitch, - unsigned int size, - void *data) = 0; - - // Destroys a texture resource. - // Parameters: - // id: the resource ID of the texture. - // Returns: - // parse_error::kParseInvalidArguments if an invalid texture - // resource ID was passed, parse_error::kParseNoError otherwise. - virtual ParseError DestroyTexture(ResourceId id) = 0; - - // Creates a sampler resource. - // Parameters: - // id: the resource ID of the sampler. - // Returns: - // parse_error::kParseNoError. - virtual ParseError CreateSampler(ResourceId id) = 0; - - // Destroys a sampler resource. - // Parameters: - // id: the resource ID of the sampler. - // Returns: - // parse_error::kParseInvalidArguments if an invalid sampler - // resource ID was passed, parse_error::kParseNoError otherwise. - virtual ParseError DestroySampler(ResourceId id) = 0; - - // Sets the states in a sampler resource. - // Parameters: - // id: the resource ID of the sampler. - // addressing_u: the addressing mode for the U coordinate. - // addressing_v: the addressing mode for the V coordinate. - // addressing_w: the addressing mode for the W coordinate. - // mag_filter: the filtering mode when magnifying textures. - // min_filter: the filtering mode when minifying textures. - // mip_filter: the filtering mode for mip-map interpolation textures. - // max_anisotropy: the maximum anisotropy. - // Returns: - // parse_error::kParseInvalidArguments if an invalid sampler - // resource ID was passed, parse_error::kParseNoError otherwise. - virtual ParseError SetSamplerStates(ResourceId id, - sampler::AddressingMode addressing_u, - sampler::AddressingMode addressing_v, - sampler::AddressingMode addressing_w, - sampler::FilteringMode mag_filter, - sampler::FilteringMode min_filter, - sampler::FilteringMode mip_filter, - unsigned int max_anisotropy) = 0; - - // Sets the color of border pixels. - // Parameters: - // id: the resource ID of the sampler. - // color: the border color. - // Returns: - // parse_error::kParseInvalidArguments if an invalid sampler - // resource ID was passed, parse_error::kParseNoError otherwise. - virtual ParseError SetSamplerBorderColor(ResourceId id, - const RGBA &color) = 0; - - // Sets the texture resource used by a sampler resource. - // Parameters: - // id: the resource ID of the sampler. - // texture_id: the resource id of the texture. - // Returns: - // parse_error::kParseInvalidArguments if an invalid sampler - // resource ID was passed, parse_error::kParseNoError otherwise. - virtual ParseError SetSamplerTexture(ResourceId id, - ResourceId texture_id) = 0; - - // Sets the viewport, and depth range. - // Parameters: - // x, y: upper left corner of the viewport. - // width, height: dimensions of the viewport. - // z_min, z_max: depth range. - virtual void SetViewport(unsigned int x, - unsigned int y, - unsigned int width, - unsigned int height, - float z_min, - float z_max) = 0; - - // Sets the scissor test enable flag and rectangle. - // Parameters: - // enable: whether or not scissor test is enabled. - // x, y: upper left corner of the scissor rectangle. - // width, height: dimensions of the scissor rectangle. - virtual void SetScissor(bool enable, - unsigned int x, - unsigned int y, - unsigned int width, - unsigned int height) = 0; - - // Sets the point and line rasterization state. - // Parameters: - // line_smooth: Whether or not line anti-aliasing is enabled. - // point_sprite: Whether or not point sprites are enabled. - // point_size: The point size. - virtual void SetPointLineRaster(bool line_smooth, - bool point_sprite, - float point_size) = 0; - - // Sets the polygon rasterization state. - // Parameters: - // fill_mode: The polygon filling mode. - // cull_mode: The polygon face culling mode. - virtual void SetPolygonRaster(PolygonMode fill_mode, - FaceCullMode cull_mode) = 0; - - // Sets the polygon offset state. Polygon offset is enabled if slope_factor - // or units is not 0. - // The applied offset (in window coordinates) is: - // o = max_slope * slope_factor + r * units - // Where max_slope is the maximum slope of the polygon (in window - // coordinates again), and r is the minimum resolvable z unit. - // Parameters: - // slope_factor: slope factor for the offset. - // units: constant factor for the offset. - virtual void SetPolygonOffset(float slope_factor, float units) = 0; - - // Sets the alpha test states. - // Parameters: - // enable: alpha test enable state. - // reference: reference value for comparison. - // comp: alpha comparison function. - virtual void SetAlphaTest(bool enable, - float reference, - Comparison comp) = 0; - - // Sets the depth test states. - // Note: if the depth test is disabled, z values are not written to the z - // buffer (i.e enable/kAlways is different from disable/*). - // Parameters: - // enable: depth test enable state. - // write_enable: depth write enable state. - // comp: depth comparison function. - virtual void SetDepthTest(bool enable, - bool write_enable, - Comparison comp) = 0; - - // Sets the stencil test states. - // Parameters: - // enable: stencil test enable state. - // separate_ccw: whether or not counter-clockwise faces use separate - // functions/operations (2-sided stencil). - // write_mask: stencil write mask. - // compare_mask: stencil compare mask. - // ref: stencil reference value. - // func_ops: stencil test function and operations for both clockwise and - // counter-clockwise faces. This is a bitfield following the following - // description (little-endian addressing): - // bits 0 - 11: clockwise functions/operations - // bits 12 - 15: must be 0. - // bits 16 - 28: counter-clockwise functions/operations - // bits 29 - 32: must be 0. - virtual void SetStencilTest(bool enable, - bool separate_ccw, - unsigned int write_mask, - unsigned int compare_mask, - unsigned int ref, - Uint32 func_ops) = 0; - - // Sets the color write paramters. - // Parameters: - // red: enable red write. - // green: enable green write. - // blue: enable blue write. - // alpha: enable alpha write. - // dither: enable dithering. - virtual void SetColorWrite(bool red, - bool green, - bool blue, - bool alpha, - bool dither) = 0; - - // Sets the blending mode. - // Parameters: - // enable: whether or not to enable blending. - // separate_alpha: whether or not alpha uses separate Equation/Functions - // (if false, it uses the color ones). - // color_eq: the equation for blending of color values. - // color_src_func: the source function for blending of color values. - // color_dst_func: the destination function for blending of color values. - // alpha_eq: the equation for blending of alpha values. - // alpha_src_func: the source function for blending of alpha values. - // alpha_dst_func: the destination function for blending of alpha values. - virtual void SetBlending(bool enable, - bool separate_alpha, - BlendEq color_eq, - BlendFunc color_src_func, - BlendFunc color_dst_func, - BlendEq alpha_eq, - BlendFunc alpha_src_func, - BlendFunc alpha_dst_func) = 0; - - // Sets the blending color. - virtual void SetBlendingColor(const RGBA &color) = 0; - - // Creates a render surface resource. - // Parameters: - // id: the resource ID of the render surface. - // width: the texture width. Must be positive. - // height: the texture height. Must be positive. - // texture_id: the resource id of the texture. - // Returns: - // parse_error::kParseInvalidArguments if invalid arguments are - // passed, parse_error::kParseNoError otherwise. - virtual ParseError CreateRenderSurface(ResourceId id, - unsigned int width, - unsigned int height, - unsigned int mip_level, - unsigned int side, - ResourceId texture_id) = 0; - - // Destroys a render surface resource. - // Parameters: - // id: the resource ID of the render surface. - // Returns: - // parse_error::kParseInvalidArguments if an invalid render - // surface - // resource ID was passed, parse_error::kParseNoError otherwise. - virtual ParseError DestroyRenderSurface(ResourceId id) = 0; - - // Creates a depth stencil surface resource. - // Parameters: - // id: the resource ID of the depth stencil surface. - // width: the texture width. Must be positive. - // height: the texture height. Must be positive. - // Returns: - // parse_error::kParseInvalidArguments if invalid arguments are - // passed, parse_error::kParseNoError otherwise. - virtual ParseError CreateDepthSurface(ResourceId id, - unsigned int width, - unsigned int height) = 0; - - // Destroys a depth stencil surface resource. - // Parameters: - // id: the resource ID of the depth stencil surface. - // Returns: - // parse_error::kParseInvalidArguments if an invalid render - // surface - // resource ID was passed, parse_error::kParseNoError otherwise. - virtual ParseError DestroyDepthSurface(ResourceId id) = 0; - - // Switches the render surface and depth stencil surface to those - // corresponding to the passed in IDs. - // Parameters: - // render_surface_id: the resource ID of the render surface. - // depth_stencil_id: the resource ID of the render depth stencil surface. - // Returns: - // parse_error::kParseInvalidArguments if invalid arguments are - // passed, parse_error::kParseNoError otherwise. - virtual ParseError SetRenderSurface(ResourceId render_surface_id, - ResourceId depth_stencil_id) = 0; - - // Switch the render surface and depth stencil surface back to the main - // surfaces stored in the render - virtual void SetBackSurfaces() = 0; -}; - -} // namespace o3d -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_COMMON_CROSS_GAPI_INTERFACE_H_ diff --git a/o3d/gpu/command_buffer/common/logging.h b/o3d/gpu/command_buffer/common/logging.h deleted file mode 100644 index a9bbad8..0000000 --- a/o3d/gpu/command_buffer/common/logging.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file abstracts differences in logging between NaCl and host -// environment. - -#ifndef GPU_COMMAND_BUFFER_COMMON_CROSS_LOGGING_H_ -#define GPU_COMMAND_BUFFER_COMMON_CROSS_LOGGING_H_ - -#ifndef __native_client__ -#include "base/logging.h" -#else -#include - -// TODO: implement logging through nacl's debug service runtime if -// available. -#define CHECK(X) do {} while (0) -#define CHECK_EQ(X, Y) do {} while (0) -#define CHECK_NE(X, Y) do {} while (0) -#define CHECK_GT(X, Y) do {} while (0) -#define CHECK_GE(X, Y) do {} while (0) -#define CHECK_LT(X, Y) do {} while (0) -#define CHECK_LE(X, Y) do {} while (0) - -#define DCHECK(X) do {} while (0) -#define DCHECK_EQ(X, Y) do {} while (0) -#define DCHECK_NE(X, Y) do {} while (0) -#define DCHECK_GT(X, Y) do {} while (0) -#define DCHECK_GE(X, Y) do {} while (0) -#define DCHECK_LT(X, Y) do {} while (0) -#define DCHECK_LE(X, Y) do {} while (0) - -#define LOG(LEVEL) if (0) std::ostringstream() -#define DLOG(LEVEL) if (0) std::ostringstream() - -#endif - -#endif // GPU_COMMAND_BUFFER_COMMON_CROSS_LOGGING_H_ diff --git a/o3d/gpu/command_buffer/common/o3d_cmd_format.cc b/o3d/gpu/command_buffer/common/o3d_cmd_format.cc deleted file mode 100644 index c70dde7..0000000 --- a/o3d/gpu/command_buffer/common/o3d_cmd_format.cc +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the binary format definition of the command buffer and -// command buffer commands. - -#include "gpu/command_buffer/common/o3d_cmd_format.h" - -namespace command_buffer { -namespace o3d { - -const char* GetCommandName(CommandId command_id) { - static const char* const names[] = { - #define O3D_COMMAND_BUFFER_CMD_OP(name) # name, - - O3D_COMMAND_BUFFER_CMDS(O3D_COMMAND_BUFFER_CMD_OP) - - #undef O3D_COMMAND_BUFFER_CMD_OP - }; - - int id = static_cast(command_id); - return (id > kStartPoint && id < kNumCommands) ? - names[id - kStartPoint - 1] : "*unknown-command*"; -} - -} // namespace o3d -} // namespace command_buffer - diff --git a/o3d/gpu/command_buffer/common/o3d_cmd_format.h b/o3d/gpu/command_buffer/common/o3d_cmd_format.h deleted file mode 100644 index 86503f4..0000000 --- a/o3d/gpu/command_buffer/common/o3d_cmd_format.h +++ /dev/null @@ -1,3155 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the binary format definition of the command buffer and -// command buffer commands. -// It is recommended you use the CommandBufferHelper object to create commands -// but if you want to go lower level you can use the structures here to help. -// -// A few ways to use them: -// -// Fill out a structure in place: -// -// cmd::SetViewport::Set(ptrToSomeSharedMemory, -// left, right, width, height, z_min, z_max); -// -// Fill out consecutive commands: -// -// Note that each cmd::XXX::Set function returns a pointer to the place -// the next command should go. -// -// void* dest = ptrToSomeSharedMemory; -// dest = cmd::SetViewport::Set(dest, left, right, width, height, min, max); -// dest = cmd::Clear::Set(dest, buffers, r, g, b, a, depth, stencil); -// dest = cmd::Draw::Set(dest, primitive_type, first, count); -// -// NOTE: The types in this file must be POD types. That means they can not have -// constructors, destructors, virtual functions or inheritance and they can only -// use other POD types or intrinsics as members. - -#ifndef GPU_COMMAND_BUFFER_COMMON_CROSS_CMD_BUFFER_FORMAT_H_ -#define GPU_COMMAND_BUFFER_COMMON_CROSS_CMD_BUFFER_FORMAT_H_ - -#include "gpu/command_buffer/common/cmd_buffer_common.h" -#include "gpu/command_buffer/common/resource.h" - -namespace command_buffer { -namespace o3d { - -// This macro is used to safely and convienently expand the list of commnad -// buffer commands in to various lists and never have them get out of sync. To -// add a new command, add it this list, create the corresponding structure below -// and then add a function in gapi_decoder.cc called Handle_COMMAND_NAME where -// COMMAND_NAME is the name of your command structure. -// -// NOTE: THE ORDER OF THESE MUST NOT CHANGE (their id is derived by order) -#define O3D_COMMAND_BUFFER_CMDS(OP) \ - OP(BeginFrame) /* 1024 */ \ - OP(EndFrame) /* 1025 */ \ - OP(Clear) /* 1026 */ \ - OP(CreateVertexBuffer) /* 1027 */ \ - OP(DestroyVertexBuffer) /* 1028 */ \ - OP(SetVertexBufferData) /* 1029 */ \ - OP(SetVertexBufferDataImmediate) /* 1030 */ \ - OP(GetVertexBufferData) /* 1031 */ \ - OP(CreateIndexBuffer) /* 1032 */ \ - OP(DestroyIndexBuffer) /* 1033 */ \ - OP(SetIndexBufferData) /* 1034 */ \ - OP(SetIndexBufferDataImmediate) /* 1035 */ \ - OP(GetIndexBufferData) /* 1036 */ \ - OP(CreateVertexStruct) /* 1037 */ \ - OP(DestroyVertexStruct) /* 1038 */ \ - OP(SetVertexInput) /* 1039 */ \ - OP(SetVertexStruct) /* 1040 */ \ - OP(Draw) /* 1041 */ \ - OP(DrawIndexed) /* 1042 */ \ - OP(CreateEffect) /* 1043 */ \ - OP(CreateEffectImmediate) /* 1044 */ \ - OP(DestroyEffect) /* 1045 */ \ - OP(SetEffect) /* 1046 */ \ - OP(GetParamCount) /* 1047 */ \ - OP(CreateParam) /* 1048 */ \ - OP(CreateParamByName) /* 1049 */ \ - OP(CreateParamByNameImmediate) /* 1050 */ \ - OP(DestroyParam) /* 1051 */ \ - OP(SetParamData) /* 1052 */ \ - OP(SetParamDataImmediate) /* 1053 */ \ - OP(GetParamDesc) /* 1054 */ \ - OP(GetStreamCount) /* 1055 */ \ - OP(GetStreamDesc) /* 1056 */ \ - OP(DestroyTexture) /* 1057 */ \ - OP(CreateTexture2d) /* 1058 */ \ - OP(CreateTexture3d) /* 1059 */ \ - OP(CreateTextureCube) /* 1060 */ \ - OP(SetTextureData) /* 1061 */ \ - OP(SetTextureDataImmediate) /* 1062 */ \ - OP(GetTextureData) /* 1063 */ \ - OP(CreateSampler) /* 1064 */ \ - OP(DestroySampler) /* 1065 */ \ - OP(SetSamplerStates) /* 1066 */ \ - OP(SetSamplerBorderColor) /* 1067 */ \ - OP(SetSamplerTexture) /* 1068 */ \ - OP(SetViewport) /* 1069 */ \ - OP(SetScissor) /* 1070 */ \ - OP(SetPointLineRaster) /* 1071 */ \ - OP(SetPolygonRaster) /* 1072 */ \ - OP(SetPolygonOffset) /* 1073 */ \ - OP(SetAlphaTest) /* 1074 */ \ - OP(SetDepthTest) /* 1075 */ \ - OP(SetStencilTest) /* 1076 */ \ - OP(SetBlending) /* 1077 */ \ - OP(SetBlendingColor) /* 1078 */ \ - OP(SetColorWrite) /* 1079 */ \ - OP(CreateRenderSurface) /* 1080 */ \ - OP(DestroyRenderSurface) /* 1081 */ \ - OP(CreateDepthSurface) /* 1082 */ \ - OP(DestroyDepthSurface) /* 1083 */ \ - OP(SetRenderSurface) /* 1084 */ \ - OP(SetBackSurfaces) /* 1085 */ \ - - -// GAPI commands. -enum CommandId { - kStartPoint = cmd::kLastCommonId, // All O3D commands start after this. - #define GPU_COMMAND_BUFFER_CMD_OP(name) k ## name, - - O3D_COMMAND_BUFFER_CMDS(GPU_COMMAND_BUFFER_CMD_OP) - - #undef GPU_COMMAND_BUFFER_CMD_OP - - kNumCommands, -}; - -// Bit definitions for buffers to clear. -enum ClearBuffer { - kColor = 0x1, - kDepth = 0x2, - kStencil = 0x4, - kAllBuffers = kColor | kDepth | kStencil -}; - -// Polygon mode for SetPolygonRaster -enum PolygonMode { - kPolygonModePoints, - kPolygonModeLines, - kPolygonModeFill, - kNumPolygonMode -}; - -// Face culling mode for SetPolygonRaster -enum FaceCullMode { - kCullNone, - kCullCW, - kCullCCW, - kNumFaceCullMode -}; - -// Primitive type for Draw and DrawIndexed. -enum PrimitiveType { - kPoints, - kLines, - kLineStrips, - kTriangles, - kTriangleStrips, - kTriangleFans, - kMaxPrimitiveType -}; - -// Comparison function for alpha or depth test -enum Comparison { - kNever, - kLess, - kEqual, - kLEqual, - kGreater, - kNotEqual, - kGEqual, - kAlways, - kNumComparison -}; - -// Stencil operation -enum StencilOp { - kKeep, - kZero, - kReplace, - kIncNoWrap, - kDecNoWrap, - kInvert, - kIncWrap, - kDecWrap, - kNumStencilOp -}; - -// Blend Equation -enum BlendEq { - kBlendEqAdd, - kBlendEqSub, - kBlendEqRevSub, - kBlendEqMin, - kBlendEqMax, - kNumBlendEq -}; - -// Blend Funtion -enum BlendFunc { - kBlendFuncZero, - kBlendFuncOne, - kBlendFuncSrcColor, - kBlendFuncInvSrcColor, - kBlendFuncSrcAlpha, - kBlendFuncInvSrcAlpha, - kBlendFuncDstAlpha, - kBlendFuncInvDstAlpha, - kBlendFuncDstColor, - kBlendFuncInvDstColor, - kBlendFuncSrcAlphaSaturate, - kBlendFuncBlendColor, - kBlendFuncInvBlendColor, - kNumBlendFunc -}; - -const char* GetCommandName(CommandId id); - -// Make sure the compiler does not add extra padding to any of the command -// structures. -#pragma pack(push, 1) - -struct BeginFrame { - typedef BeginFrame ValueType; - static const CommandId kCmdId = kBeginFrame; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init() { - SetHeader(); - } - static void* Set(void* cmd) { - static_cast(cmd)->Init(); - return NextCmdAddress(cmd); - } - - CommandHeader header; -}; - -COMPILE_ASSERT(sizeof(BeginFrame) == 4, Sizeof_BeginFrame_is_not_4); -COMPILE_ASSERT(offsetof(BeginFrame, header) == 0, - OffsetOf_BeginFrame_header_not_0); - -struct EndFrame { - typedef EndFrame ValueType; - static const CommandId kCmdId = kEndFrame; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init() { - SetHeader(); - } - static void* Set(void* cmd) { - static_cast(cmd)->Init(); - return NextCmdAddress(cmd); - } - - CommandHeader header; -}; - -COMPILE_ASSERT(sizeof(EndFrame) == 4, Sizeof_EndFrame_is_not_4); -COMPILE_ASSERT(offsetof(EndFrame, header) == 0, - OffsetOf_EndFrame_header_not_0); - -struct Clear { - typedef Clear ValueType; - static const CommandId kCmdId = kClear; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(uint32 _buffers, float _red, float _green, float _blue, - float _alpha, float _depth, uint32 _stencil) { - SetHeader(); - buffers = _buffers; - red = _red; - green = _green; - blue = _blue; - alpha = _alpha; - depth = _depth; - stencil = _stencil; - } - - static void* Set(void* cmd, uint32 buffers, - float red, float green, float blue, float alpha, - float depth, - uint32 stencil) { - static_cast(cmd)->Init( - buffers, red, green, blue, alpha, depth, stencil); - return NextCmdAddress(cmd); - } - - CommandHeader header; - uint32 buffers; - float red; - float green; - float blue; - float alpha; - float depth; - uint32 stencil; -}; - -COMPILE_ASSERT(sizeof(Clear) == 32, Sizeof_Clear_is_not_32); -COMPILE_ASSERT(offsetof(Clear, header) == 0, - OffsetOf_Clear_header_not_0); -COMPILE_ASSERT(offsetof(Clear, buffers) == 4, - OffsetOf_Clear_buffers_not_4); -COMPILE_ASSERT(offsetof(Clear, red) == 8, - OffsetOf_Clear_red_not_8); -COMPILE_ASSERT(offsetof(Clear, green) == 12, - OffsetOf_Clear_green_not_12); -COMPILE_ASSERT(offsetof(Clear, blue) == 16, - OffsetOf_Clear_blue_not_16); -COMPILE_ASSERT(offsetof(Clear, alpha) == 20, - OffsetOf_Clear_alpha_not_20); -COMPILE_ASSERT(offsetof(Clear, depth) == 24, - OffsetOf_Clear_depth_not_24); -COMPILE_ASSERT(offsetof(Clear, stencil) == 28, - OffsetOf_Clear_stencil_not_28); - -struct SetViewport { - typedef SetViewport ValueType; - static const CommandId kCmdId = kSetViewport; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init( - uint32 _left, - uint32 _top, - uint32 _width, - uint32 _height, - float _z_min, - float _z_max) { - SetHeader(); - left = _left; - top = _top; - width = _width; - height = _height; - z_min = _z_min; - z_max = _z_max; - } - - static void* Set(void* cmd, - uint32 left, - uint32 top, - uint32 width, - uint32 height, - float z_min, - float z_max) { - static_cast(cmd)->Init( - left, - top, - width, - height, - z_min, - z_max); - return NextCmdAddress(cmd); - } - - CommandHeader header; - uint32 left; - uint32 top; - uint32 width; - uint32 height; - float z_min; - float z_max; -}; - -COMPILE_ASSERT(sizeof(SetViewport) == 28, Sizeof_SetViewport_is_not_28); -COMPILE_ASSERT(offsetof(SetViewport, header) == 0, - OffsetOf_SetViewport_header_not_0); -COMPILE_ASSERT(offsetof(SetViewport, left) == 4, - OffsetOf_SetViewport_left_not_4); -COMPILE_ASSERT(offsetof(SetViewport, top) == 8, - OffsetOf_SetViewport_top_not_8); -COMPILE_ASSERT(offsetof(SetViewport, width) == 12, - OffsetOf_SetViewport_width_not_12); -COMPILE_ASSERT(offsetof(SetViewport, height) == 16, - OffsetOf_SetViewport_height_not_16); -COMPILE_ASSERT(offsetof(SetViewport, z_min) == 20, - OffsetOf_SetViewport_z_min_not_20); -COMPILE_ASSERT(offsetof(SetViewport, z_max) == 24, - OffsetOf_SetViewport_z_max_not_24); - -struct CreateVertexBuffer { - typedef CreateVertexBuffer ValueType; - static const CommandId kCmdId = kCreateVertexBuffer; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _vertex_buffer_id, uint32 _size, - vertex_buffer::Flags _flags) { - SetHeader(); - vertex_buffer_id = _vertex_buffer_id; - size = _size; - flags = static_cast(_flags); - } - - static void* Set(void* cmd, ResourceId vertex_buffer_id, - uint32 size, vertex_buffer::Flags flags) { - static_cast(cmd)->Init(vertex_buffer_id, size, flags); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId vertex_buffer_id; - uint32 size; - uint32 flags; -}; - -COMPILE_ASSERT(sizeof(CreateVertexBuffer) == 16, - Sizeof_CreateVertexBuffer_is_not_16); -COMPILE_ASSERT(offsetof(CreateVertexBuffer, header) == 0, - OffsetOf_CreateVertexBuffer_header_not_0); -COMPILE_ASSERT(offsetof(CreateVertexBuffer, vertex_buffer_id) == 4, - OffsetOf_CreateVertexBuffer_vertex_buffer_id_not_4); -COMPILE_ASSERT(offsetof(CreateVertexBuffer, size) == 8, - OffsetOf_CreateVertexBuffer_size_not_8); -COMPILE_ASSERT(offsetof(CreateVertexBuffer, flags) == 12, - OffsetOf_CreateVertexBuffer_flags_not_12); - -struct DestroyVertexBuffer { - typedef DestroyVertexBuffer ValueType; - static const CommandId kCmdId = kDestroyVertexBuffer; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _vertex_buffer_id) { - SetHeader(); - vertex_buffer_id = _vertex_buffer_id; - } - - static void* Set(void* cmd, ResourceId vertex_buffer_id) { - static_cast(cmd)->Init(vertex_buffer_id); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId vertex_buffer_id; -}; - -COMPILE_ASSERT(sizeof(DestroyVertexBuffer) == 8, - Sizeof_DestroyVertexBuffer_is_not_8); -COMPILE_ASSERT(offsetof(DestroyVertexBuffer, header) == 0, - OffsetOf_DestroyVertexBuffer_header_not_0); -COMPILE_ASSERT(offsetof(DestroyVertexBuffer, vertex_buffer_id) == 4, - OffsetOf_DestroyVertexBuffer_vertex_buffer_id_not_4); - -struct SetVertexBufferDataImmediate { - typedef SetVertexBufferDataImmediate ValueType; - static const CommandId kCmdId = kSetVertexBufferDataImmediate; - static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; - - void SetHeader(uint32 size) { - header.SetCmdBySize(size); - } - - void Init(ResourceId _vertex_buffer_id, uint32 _offset, - const void* data, uint32 size) { - SetHeader(size); - vertex_buffer_id = _vertex_buffer_id; - offset = _offset; - memcpy(ImmediateDataAddress(this), data, size); - } - - static void* Set(void* cmd, ResourceId vertex_buffer_id, uint32 offset, - const void* data, uint32 size) { - static_cast(cmd)->Init(vertex_buffer_id, offset, data, size); - return NextImmediateCmdAddress(cmd, size); - } - - CommandHeader header; - ResourceId vertex_buffer_id; - uint32 offset; -}; - -COMPILE_ASSERT(sizeof(SetVertexBufferDataImmediate) == 12, - Sizeof_SetVertexBufferDataImmediate_is_not_12); -COMPILE_ASSERT(offsetof(SetVertexBufferDataImmediate, header) == 0, - OffsetOf_SetVertexBufferDataImmediate_header_not_0); -COMPILE_ASSERT(offsetof(SetVertexBufferDataImmediate, vertex_buffer_id) == 4, - OffsetOf_SetVertexBufferDataImmediate_vertex_buffer_id_not_4); -COMPILE_ASSERT(offsetof(SetVertexBufferDataImmediate, offset) == 8, - OffsetOf_SetVertexBufferDataImmediate_offset_not_8); - -struct SetVertexBufferData { - typedef SetVertexBufferData ValueType; - static const CommandId kCmdId = kSetVertexBufferData; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _vertex_buffer_id, uint32 _offset, uint32 _size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - SetHeader(); - vertex_buffer_id = _vertex_buffer_id; - offset = _offset; - size = _size; - shared_memory.Init(shared_memory_id, shared_memory_offset); - } - - static void* Set(void* cmd, ResourceId vertex_buffer_id, - uint32 offset, uint32 size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - static_cast(cmd)->Init(vertex_buffer_id, offset, size, - shared_memory_id, shared_memory_offset); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId vertex_buffer_id; - uint32 offset; - uint32 size; - SharedMemory shared_memory; -}; - -COMPILE_ASSERT(sizeof(SetVertexBufferData) == 24, - Sizeof_SetVertexBufferData_is_not_24); -COMPILE_ASSERT(offsetof(SetVertexBufferData, header) == 0, - OffsetOf_SetVertexBufferData_header_not_0); -COMPILE_ASSERT(offsetof(SetVertexBufferData, vertex_buffer_id) == 4, - OffsetOf_SetVertexBufferData_vertex_buffer_id_not_4); -COMPILE_ASSERT(offsetof(SetVertexBufferData, offset) == 8, - OffsetOf_SetVertexBufferData_offset_not_8); -COMPILE_ASSERT(offsetof(SetVertexBufferData, size) == 12, - OffsetOf_SetVertexBufferData_size_not_12); -COMPILE_ASSERT(offsetof(SetVertexBufferData, shared_memory) == 16, - OffsetOf_SetVertexBufferData_shared_memory_not_16); - -struct GetVertexBufferData { - typedef GetVertexBufferData ValueType; - static const CommandId kCmdId = kGetVertexBufferData; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _vertex_buffer_id, uint32 _offset, uint32 _size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - SetHeader(); - vertex_buffer_id = _vertex_buffer_id; - offset = _offset; - size = _size; - shared_memory.Init(shared_memory_id, shared_memory_offset); - } - - static void* Set(void* cmd, ResourceId vertex_buffer_id, - uint32 offset, uint32 size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - static_cast(cmd)->Init(vertex_buffer_id, offset, size, - shared_memory_id, shared_memory_offset); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId vertex_buffer_id; - uint32 offset; - uint32 size; - SharedMemory shared_memory; -}; - -COMPILE_ASSERT(sizeof(GetVertexBufferData) == 24, - Sizeof_GetVertexBufferData_is_not_24); -COMPILE_ASSERT(offsetof(GetVertexBufferData, header) == 0, - OffsetOf_GetVertexBufferData_header_not_0); -COMPILE_ASSERT(offsetof(GetVertexBufferData, vertex_buffer_id) == 4, - OffsetOf_GetVertexBufferData_vertex_buffer_id_not_4); -COMPILE_ASSERT(offsetof(GetVertexBufferData, offset) == 8, - OffsetOf_GetVertexBufferData_offset_not_8); -COMPILE_ASSERT(offsetof(GetVertexBufferData, size) == 12, - OffsetOf_GetVertexBufferData_size_not_12); -COMPILE_ASSERT(offsetof(GetVertexBufferData, shared_memory) == 16, - OffsetOf_GetVertexBufferData_shared_memory_not_16); - -struct CreateIndexBuffer { - typedef CreateIndexBuffer ValueType; - static const CommandId kCmdId = kCreateIndexBuffer; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _index_buffer_id, uint32 _size, - index_buffer::Flags _flags) { - SetHeader(); - index_buffer_id = _index_buffer_id; - size = _size; - flags = static_cast(_flags); - } - - static void* Set(void* cmd, ResourceId index_buffer_id, - uint32 size, index_buffer::Flags flags) { - static_cast(cmd)->Init(index_buffer_id, size, flags); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId index_buffer_id; - uint32 size; - uint32 flags; -}; - -COMPILE_ASSERT(sizeof(CreateIndexBuffer) == 16, - Sizeof_CreateIndexBuffer_is_not_16); -COMPILE_ASSERT(offsetof(CreateIndexBuffer, header) == 0, - OffsetOf_CreateIndexBuffer_header_not_0); -COMPILE_ASSERT(offsetof(CreateIndexBuffer, index_buffer_id) == 4, - OffsetOf_CreateIndexBuffer_index_buffer_id_not_4); -COMPILE_ASSERT(offsetof(CreateIndexBuffer, size) == 8, - OffsetOf_CreateIndexBuffer_size_not_8); -COMPILE_ASSERT(offsetof(CreateIndexBuffer, flags) == 12, - OffsetOf_CreateIndexBuffer_flags_not_12); - -struct DestroyIndexBuffer { - typedef DestroyIndexBuffer ValueType; - static const CommandId kCmdId = kDestroyIndexBuffer; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _index_buffer_id) { - SetHeader(); - index_buffer_id = _index_buffer_id; - } - - static void* Set(void* cmd, ResourceId index_buffer_id) { - static_cast(cmd)->Init(index_buffer_id); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId index_buffer_id; -}; - -COMPILE_ASSERT(sizeof(DestroyIndexBuffer) == 8, - Sizeof_DestroyIndexBuffer_is_not_8); -COMPILE_ASSERT(offsetof(DestroyIndexBuffer, header) == 0, - OffsetOf_DestroyIndexBuffer_header_not_0); -COMPILE_ASSERT(offsetof(DestroyIndexBuffer, index_buffer_id) == 4, - OffsetOf_DestroyIndexBuffer_index_buffer_id_not_4); - -struct SetIndexBufferDataImmediate { - typedef SetIndexBufferDataImmediate ValueType; - static const CommandId kCmdId = kSetIndexBufferDataImmediate; - static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; - - void SetHeader(uint32 size) { - header.SetCmdBySize(size); - } - - void Init(ResourceId _index_buffer_id, uint32 _offset, - const void* data, uint32 size) { - SetHeader(size); - index_buffer_id = _index_buffer_id; - offset = _offset; - memcpy(ImmediateDataAddress(this), data, size); - } - - static void* Set(void* cmd, ResourceId index_buffer_id, uint32 offset, - const void* data, uint32 size) { - static_cast(cmd)->Init(index_buffer_id, offset, data, size); - return NextImmediateCmdAddress(cmd, size); - } - - CommandHeader header; - ResourceId index_buffer_id; - uint32 offset; -}; - -COMPILE_ASSERT(sizeof(SetIndexBufferDataImmediate) == 12, - Sizeof_SetIndexBufferDataImmediate_is_not_12); -COMPILE_ASSERT(offsetof(SetIndexBufferDataImmediate, header) == 0, - OffsetOf_SetIndexBufferDataImmediate_header_not_0); -COMPILE_ASSERT(offsetof(SetIndexBufferDataImmediate, index_buffer_id) == 4, - OffsetOf_SetIndexBufferDataImmediate_index_buffer_id_not_4); -COMPILE_ASSERT(offsetof(SetIndexBufferDataImmediate, offset) == 8, - OffsetOf_SetIndexBufferDataImmediate_offset_not_8); - -struct SetIndexBufferData { - typedef SetIndexBufferData ValueType; - static const CommandId kCmdId = kSetIndexBufferData; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _index_buffer_id, uint32 _offset, uint32 _size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - SetHeader(); - index_buffer_id = _index_buffer_id; - offset = _offset; - size = _size; - shared_memory.Init(shared_memory_id, shared_memory_offset); - } - - static void* Set(void* cmd, - ResourceId index_buffer_id, uint32 offset, uint32 size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - static_cast(cmd)->Init(index_buffer_id, offset, size, - shared_memory_id, shared_memory_offset); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId index_buffer_id; - uint32 offset; - uint32 size; - SharedMemory shared_memory; -}; - -COMPILE_ASSERT(sizeof(SetIndexBufferData) == 24, - Sizeof_SetIndexBufferData_is_not_24); -COMPILE_ASSERT(offsetof(SetIndexBufferData, header) == 0, - OffsetOf_SetIndexBufferData_header_not_0); -COMPILE_ASSERT(offsetof(SetIndexBufferData, index_buffer_id) == 4, - OffsetOf_SetIndexBufferData_index_buffer_id_not_4); -COMPILE_ASSERT(offsetof(SetIndexBufferData, offset) == 8, - OffsetOf_SetIndexBufferData_offset_not_8); -COMPILE_ASSERT(offsetof(SetIndexBufferData, size) == 12, - OffsetOf_SetIndexBufferData_size_not_12); -COMPILE_ASSERT(offsetof(SetIndexBufferData, shared_memory) == 16, - OffsetOf_SetIndexBufferData_shared_memory_not_16); - -struct GetIndexBufferData { - typedef GetIndexBufferData ValueType; - static const CommandId kCmdId = kGetIndexBufferData; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _index_buffer_id, uint32 _offset, uint32 _size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - SetHeader(); - index_buffer_id = _index_buffer_id; - offset = _offset; - size = _size; - shared_memory.Init(shared_memory_id, shared_memory_offset); - } - - static void* Set(void* cmd, ResourceId index_buffer_id, - uint32 offset, uint32 size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - static_cast(cmd)->Init(index_buffer_id, offset, size, - shared_memory_id, shared_memory_offset); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId index_buffer_id; - uint32 offset; - uint32 size; - SharedMemory shared_memory; -}; - -COMPILE_ASSERT(sizeof(GetIndexBufferData) == 24, - Sizeof_GetIndexBufferData_is_not_24); -COMPILE_ASSERT(offsetof(GetIndexBufferData, header) == 0, - OffsetOf_GetIndexBufferData_header_not_0); -COMPILE_ASSERT(offsetof(GetIndexBufferData, index_buffer_id) == 4, - OffsetOf_GetIndexBufferData_index_buffer_id_not_4); -COMPILE_ASSERT(offsetof(GetIndexBufferData, offset) == 8, - OffsetOf_GetIndexBufferData_offset_not_8); -COMPILE_ASSERT(offsetof(GetIndexBufferData, size) == 12, - OffsetOf_GetIndexBufferData_size_not_12); -COMPILE_ASSERT(offsetof(GetIndexBufferData, shared_memory) == 16, - OffsetOf_GetIndexBufferData_shared_memory_not_16); - -struct CreateVertexStruct { - typedef CreateVertexStruct ValueType; - static const CommandId kCmdId = kCreateVertexStruct; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _vertex_struct_id, uint32 _input_count) { - SetHeader(); - vertex_struct_id = _vertex_struct_id; - input_count = _input_count; - } - - static void* Set(void* cmd, ResourceId vertex_struct_id, uint32 input_count) { - static_cast(cmd)->Init(vertex_struct_id, input_count); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId vertex_struct_id; - uint32 input_count; -}; - -COMPILE_ASSERT(sizeof(CreateVertexStruct) == 12, - Sizeof_CreateVertexStruct_is_not_12); -COMPILE_ASSERT(offsetof(CreateVertexStruct, header) == 0, - OffsetOf_CreateVertexStruct_header_not_0); -COMPILE_ASSERT(offsetof(CreateVertexStruct, vertex_struct_id) == 4, - OffsetOf_CreateVertexStruct_vertex_struct_id_not_4); -COMPILE_ASSERT(offsetof(CreateVertexStruct, input_count) == 8, - OffsetOf_CreateVertexStruct_input_count_not_8); - -struct DestroyVertexStruct { - typedef DestroyVertexStruct ValueType; - static const CommandId kCmdId = kDestroyVertexStruct; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _vertex_struct_id) { - SetHeader(); - vertex_struct_id = _vertex_struct_id; - } - - static void* Set(void* cmd, ResourceId vertex_struct_id) { - static_cast(cmd)->Init(vertex_struct_id); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId vertex_struct_id; -}; - -COMPILE_ASSERT(sizeof(DestroyVertexStruct) == 8, - Sizeof_DestroyVertexStruct_is_not_8); -COMPILE_ASSERT(offsetof(DestroyVertexStruct, header) == 0, - OffsetOf_DestroyVertexStruct_header_not_0); -COMPILE_ASSERT(offsetof(DestroyVertexStruct, vertex_struct_id) == 4, - OffsetOf_DestroyVertexStruct_vertex_struct_id_not_4); - -struct SetVertexInput { - typedef SetVertexInput ValueType; - static const CommandId kCmdId = kSetVertexInput; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - // type_stride_semantic field. - typedef BitField<0, 4> SemanticIndex; - typedef BitField<4, 4> Semantic; - typedef BitField<8, 8> Type; - typedef BitField<16, 16> Stride; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _vertex_struct_id, - uint32 _input_index, - ResourceId _vertex_buffer_id, - uint32 _offset, - vertex_struct::Semantic _semantic, - uint32 _semantic_index, - vertex_struct::Type _type, - uint32 _stride) { - SetHeader(); - vertex_struct_id = _vertex_struct_id; - input_index = _input_index; - vertex_buffer_id = _vertex_buffer_id; - offset = _offset; - type_stride_semantic = - Semantic::MakeValue(_semantic) | - SemanticIndex::MakeValue(_semantic_index) | - Type::MakeValue(_type) | - Stride::MakeValue(_stride); - } - - static void* Set( - void* cmd, - ResourceId vertex_struct_id, - uint32 input_index, - ResourceId vertex_buffer_id, - uint32 offset, - vertex_struct::Semantic semantic, - uint32 semantic_index, - vertex_struct::Type type, - uint32 stride) { - static_cast(cmd)->Init( - vertex_struct_id, - input_index, - vertex_buffer_id, - offset, - semantic, - semantic_index, - type, - stride); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId vertex_struct_id; - uint32 input_index; - ResourceId vertex_buffer_id; - uint32 offset; - uint32 type_stride_semantic; -}; - -COMPILE_ASSERT(sizeof(SetVertexInput) == 24, - Sizeof_SetVertexInput_is_not_24); -COMPILE_ASSERT(offsetof(SetVertexInput, header) == 0, - OffsetOf_SetVertexInput_header_not_0); -COMPILE_ASSERT(offsetof(SetVertexInput, vertex_struct_id) == 4, - OffsetOf_SetVertexInput_vertex_struct_id_not_4); -COMPILE_ASSERT(offsetof(SetVertexInput, input_index) == 8, - OffsetOf_SetVertexInput_input_index_not_8); -COMPILE_ASSERT(offsetof(SetVertexInput, vertex_buffer_id) == 12, - OffsetOf_SetVertexInput_vertex_buffer_id_not_12); -COMPILE_ASSERT(offsetof(SetVertexInput, offset) == 16, - OffsetOf_SetVertexInput_offset_not_16); -COMPILE_ASSERT(offsetof(SetVertexInput, type_stride_semantic) == 20, - OffsetOf_SetVertexInput_type_stride_semantic_not_20); - -struct SetVertexStruct { - typedef SetVertexStruct ValueType; - static const CommandId kCmdId = kSetVertexStruct; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _vertex_struct_id) { - SetHeader(); - vertex_struct_id = _vertex_struct_id; - } - - static void* Set(void* cmd, ResourceId vertex_struct_id) { - static_cast(cmd)->Init(vertex_struct_id); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId vertex_struct_id; -}; - -COMPILE_ASSERT(sizeof(SetVertexStruct) == 8, - Sizeof_SetVertexStruct_is_not_8); -COMPILE_ASSERT(offsetof(SetVertexStruct, header) == 0, - OffsetOf_SetVertexStruct_header_not_0); -COMPILE_ASSERT(offsetof(SetVertexStruct, vertex_struct_id) == 4, - OffsetOf_SetVertexStruct_vertex_struct_id_not_4); - -struct Draw { - typedef Draw ValueType; - static const CommandId kCmdId = kDraw; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(PrimitiveType _primitive_type, uint32 _first, uint32 _count) { - SetHeader(); - primitive_type = _primitive_type; - first = _first; - count = _count; - } - - static void* Set(void* cmd, PrimitiveType primitive_type, uint32 first, - uint32 count) { - static_cast(cmd)->Init(primitive_type, first, count); - return NextCmdAddress(cmd); - } - - CommandHeader header; - uint32 primitive_type; - uint32 first; - uint32 count; -}; - -COMPILE_ASSERT(sizeof(Draw) == 16, Sizeof_DRAW_is_not_16); -COMPILE_ASSERT(offsetof(Draw, header) == 0, - OffsetOf_Draw_header_not_0); -COMPILE_ASSERT(offsetof(Draw, primitive_type) == 4, - OffsetOf_Draw_primitive_type_not_4); -COMPILE_ASSERT(offsetof(Draw, first) == 8, - OffsetOf_Draw_first_not_8); -COMPILE_ASSERT(offsetof(Draw, count) == 12, - OffsetOf_Draw_count_not_12); - -struct DrawIndexed { - typedef DrawIndexed ValueType; - static const CommandId kCmdId = kDrawIndexed; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init( - PrimitiveType _primitive_type, - ResourceId _index_buffer_id, - uint32 _first, - uint32 _count, - uint32 _min_index, - uint32 _max_index) { - SetHeader(); - primitive_type = _primitive_type; - index_buffer_id = _index_buffer_id; - first = _first; - count = _count; - min_index = _min_index; - max_index = _max_index; - } - - static void* Set(void* cmd, - PrimitiveType primitive_type, - ResourceId index_buffer_id, - uint32 first, - uint32 count, - uint32 min_index, - uint32 max_index) { - static_cast(cmd)->Init( - primitive_type, - index_buffer_id, - first, - count, - min_index, - max_index); - return NextCmdAddress(cmd); - } - - CommandHeader header; - uint32 primitive_type; - ResourceId index_buffer_id; - uint32 first; - uint32 count; - uint32 min_index; - uint32 max_index; -}; - -COMPILE_ASSERT(sizeof(DrawIndexed) == 28, Sizeof_DrawIndexed_is_not_28); -COMPILE_ASSERT(offsetof(DrawIndexed, header) == 0, - OffsetOf_DrawIndexed_header_not_0); -COMPILE_ASSERT(offsetof(DrawIndexed, primitive_type) == 4, - OffsetOf_DrawIndexed_primitive_type_not_4); -COMPILE_ASSERT(offsetof(DrawIndexed, index_buffer_id) == 8, - OffsetOf_DrawIndexed_index_buffer_id_not_8); -COMPILE_ASSERT(offsetof(DrawIndexed, first) == 12, - OffsetOf_DrawIndexed_first_not_12); -COMPILE_ASSERT(offsetof(DrawIndexed, count) == 16, - OffsetOf_DrawIndexed_count_not_16); -COMPILE_ASSERT(offsetof(DrawIndexed, min_index) == 20, - OffsetOf_DrawIndexed_min_index_not_20); -COMPILE_ASSERT(offsetof(DrawIndexed, max_index) == 24, - OffsetOf_DrawIndexed_max_index_not_24); - -struct CreateEffect { - typedef CreateEffect ValueType; - static const CommandId kCmdId = kCreateEffect; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _effect_id, uint32 _size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - SetHeader(); - effect_id = _effect_id; - size = _size; - shared_memory.Init(shared_memory_id, shared_memory_offset); - } - - static void* Set(void* cmd, ResourceId effect_id, uint32 size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - static_cast(cmd)->Init(effect_id, size, - shared_memory_id, shared_memory_offset); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId effect_id; - uint32 size; - SharedMemory shared_memory; -}; - -COMPILE_ASSERT(sizeof(CreateEffect) == 20, Sizeof_CreateEffect_is_not_20); -COMPILE_ASSERT(offsetof(CreateEffect, header) == 0, - OffsetOf_CreateEffect_header_not_0); -COMPILE_ASSERT(offsetof(CreateEffect, effect_id) == 4, - OffsetOf_CreateEffect_effect_id_not_4); -COMPILE_ASSERT(offsetof(CreateEffect, size) == 8, - OffsetOf_CreateEffect_size_not_8); -COMPILE_ASSERT(offsetof(CreateEffect, shared_memory) == 12, - OffsetOf_CreateEffect_shared_memory_not_12); - -struct CreateEffectImmediate { - typedef CreateEffectImmediate ValueType; - static const CommandId kCmdId = kCreateEffectImmediate; - static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; - - void SetHeader(uint32 size) { - header.SetCmdBySize(size); - } - - void Init(ResourceId _effect_id, uint32 _size, const void* data) { - SetHeader(_size); - effect_id = _effect_id; - size = _size; - } - - static void* Set(void* cmd, - ResourceId effect_id, uint32 size, const void* data) { - static_cast(cmd)->Init(effect_id, size, data); - return NextImmediateCmdAddress(cmd, size); - } - - CommandHeader header; - ResourceId effect_id; - uint32 size; -}; - -COMPILE_ASSERT(sizeof(CreateEffectImmediate) == 12, - Sizeof_CreateEffectImmediate_is_not_12); -COMPILE_ASSERT(offsetof(CreateEffectImmediate, header) == 0, - OffsetOf_CreateEffectImmediate_header_not_0); -COMPILE_ASSERT(offsetof(CreateEffectImmediate, effect_id) == 4, - OffsetOf_CreateEffectImmediate_effect_id_not_4); -COMPILE_ASSERT(offsetof(CreateEffectImmediate, size) == 8, - OffsetOf_CreateEffectImmediate_size_not_8); - -struct DestroyEffect { - typedef DestroyEffect ValueType; - static const CommandId kCmdId = kDestroyEffect; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _effect_id) { - SetHeader(); - effect_id = _effect_id; - } - - static void* Set(void* cmd, ResourceId effect_id) { - static_cast(cmd)->Init(effect_id); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId effect_id; -}; - -COMPILE_ASSERT(sizeof(DestroyEffect) == 8, Sizeof_DestroyEffect_is_not_8); -COMPILE_ASSERT(offsetof(DestroyEffect, header) == 0, - OffsetOf_DestroyEffect_header_not_0); -COMPILE_ASSERT(offsetof(DestroyEffect, effect_id) == 4, - OffsetOf_DestroyEffect_effect_id_not_4); - -struct SetEffect { - typedef SetEffect ValueType; - static const CommandId kCmdId = kSetEffect; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _effect_id) { - SetHeader(); - effect_id = _effect_id; - } - - static void* Set(void* cmd, ResourceId effect_id) { - static_cast(cmd)->Init(effect_id); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId effect_id; -}; - -COMPILE_ASSERT(sizeof(SetEffect) == 8, Sizeof_SetEffect_is_not_8); -COMPILE_ASSERT(offsetof(SetEffect, header) == 0, - OffsetOf_SetEffect_header_not_0); -COMPILE_ASSERT(offsetof(SetEffect, effect_id) == 4, - OffsetOf_SetEffect_effect_id_not_4); - -struct GetParamCount { - typedef GetParamCount ValueType; - static const CommandId kCmdId = kGetParamCount; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _effect_id, uint32 _size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - SetHeader(); - effect_id = _effect_id; - size = _size; - shared_memory.Init(shared_memory_id, shared_memory_offset); - } - - static void* Set(void* cmd, ResourceId effect_id, uint32 size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - static_cast(cmd)->Init(effect_id, size, - shared_memory_id, shared_memory_offset); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId effect_id; - uint32 size; - SharedMemory shared_memory; -}; - -COMPILE_ASSERT(sizeof(GetParamCount) == 20, Sizeof_GetParamCount_is_not_20); -COMPILE_ASSERT(offsetof(GetParamCount, header) == 0, - OffsetOf_GetParamCount_header_not_0); -COMPILE_ASSERT(offsetof(GetParamCount, effect_id) == 4, - OffsetOf_GetParamCount_effect_id_not_4); -COMPILE_ASSERT(offsetof(GetParamCount, size) == 8, - OffsetOf_GetParamCount_size_not_8); -COMPILE_ASSERT(offsetof(GetParamCount, shared_memory) == 12, - OffsetOf_GetParamCount_shared_memory_not_12); - -struct CreateParam { - typedef CreateParam ValueType; - static const CommandId kCmdId = kCreateParam; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _param_id, ResourceId _effect_id, uint32 _index) { - SetHeader(); - param_id = _param_id; - effect_id = _effect_id; - index = _index; - } - - static void* Set(void* cmd, - ResourceId param_id, ResourceId effect_id, uint32 index) { - static_cast(cmd)->Init(param_id, effect_id, index); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId param_id; - ResourceId effect_id; - uint32 index; -}; - -COMPILE_ASSERT(sizeof(CreateParam) == 16, Sizeof_CreateParam_is_not_16); -COMPILE_ASSERT(offsetof(CreateParam, header) == 0, - OffsetOf_CreateParam_header_not_0); -COMPILE_ASSERT(offsetof(CreateParam, param_id) == 4, - OffsetOf_CreateParam_param_id_not_4); -COMPILE_ASSERT(offsetof(CreateParam, effect_id) == 8, - OffsetOf_CreateParam_effect_id_not_8); -COMPILE_ASSERT(offsetof(CreateParam, index) == 12, - OffsetOf_CreateParam_index_not_12); - -struct CreateParamByName { - typedef CreateParamByName ValueType; - static const CommandId kCmdId = kCreateParamByName; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _param_id, ResourceId _effect_id, uint32 _size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - SetHeader(); - param_id = _param_id; - effect_id = _effect_id; - size = _size; - shared_memory.Init(shared_memory_id, shared_memory_offset); - } - - static void* Set(void* cmd, ResourceId param_id, ResourceId effect_id, - uint32 size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - static_cast(cmd)->Init(param_id, effect_id, size, - shared_memory_id, shared_memory_offset); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId param_id; - ResourceId effect_id; - uint32 size; - SharedMemory shared_memory; -}; - -COMPILE_ASSERT(sizeof(CreateParamByName) == 24, - Sizeof_CreateParamByName_is_not_24); -COMPILE_ASSERT(offsetof(CreateParamByName, header) == 0, - OffsetOf_CreateParamByName_header_not_0); -COMPILE_ASSERT(offsetof(CreateParamByName, param_id) == 4, - OffsetOf_CreateParamByName_param_id_not_4); -COMPILE_ASSERT(offsetof(CreateParamByName, effect_id) == 8, - OffsetOf_CreateParamByName_effect_id_not_8); -COMPILE_ASSERT(offsetof(CreateParamByName, size) == 12, - OffsetOf_CreateParamByName_size_not_12); -COMPILE_ASSERT(offsetof(CreateParamByName, shared_memory) == 16, - OffsetOf_CreateParamByName_shared_memory_not_16); - -struct CreateParamByNameImmediate { - typedef CreateParamByNameImmediate ValueType; - static const CommandId kCmdId = kCreateParamByNameImmediate; - static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; - - void SetHeader(uint32 size) { - header.SetCmdBySize(size); - } - - void Init(ResourceId _param_id, ResourceId _effect_id, uint32 _size, - const void* data) { - SetHeader(_size); - param_id = _param_id; - effect_id = _effect_id; - size = _size; - memcpy(ImmediateDataAddress(this), data, _size); - } - - static void* Set(void* cmd, ResourceId param_id, ResourceId effect_id, - uint32 size, const void* data) { - static_cast(cmd)->Init(param_id, effect_id, size, data); - return NextImmediateCmdAddress(cmd, size); - } - - CommandHeader header; - ResourceId param_id; - ResourceId effect_id; - uint32 size; -}; - -COMPILE_ASSERT(sizeof(CreateParamByNameImmediate) == 16, - Sizeof_CreateParamByNameImmediate_is_not_16); -COMPILE_ASSERT(offsetof(CreateParamByNameImmediate, header) == 0, - OffsetOf_CreateParamByNameImmediate_header_not_0); -COMPILE_ASSERT(offsetof(CreateParamByNameImmediate, param_id) == 4, - OffsetOf_CreateParamByNameImmediate_param_id_not_4); -COMPILE_ASSERT(offsetof(CreateParamByNameImmediate, effect_id) == 8, - OffsetOf_CreateParamByNameImmediate_effect_id_not_8); -COMPILE_ASSERT(offsetof(CreateParamByNameImmediate, size) == 12, - OffsetOf_CreateParamByNameImmediate_size_not_12); - -struct DestroyParam { - typedef DestroyParam ValueType; - static const CommandId kCmdId = kDestroyParam; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _param_id) { - SetHeader(); - param_id = _param_id; - } - - static void* Set(void* cmd, ResourceId param_id) { - static_cast(cmd)->Init(param_id); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId param_id; -}; - -COMPILE_ASSERT(sizeof(DestroyParam) == 8, Sizeof_DestroyParam_is_not_8); -COMPILE_ASSERT(offsetof(DestroyParam, header) == 0, - OffsetOf_DestroyParam_header_not_0); -COMPILE_ASSERT(offsetof(DestroyParam, param_id) == 4, - OffsetOf_DestroyParam_param_id_not_4); - -struct SetParamData { - typedef SetParamData ValueType; - static const CommandId kCmdId = kSetParamData; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _param_id, uint32 _size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - SetHeader(); - param_id = _param_id; - size = _size; - shared_memory.Init(shared_memory_id, shared_memory_offset); - } - - static void* Set(void* cmd, ResourceId param_id, uint32 size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - static_cast(cmd)->Init(param_id, size, - shared_memory_id, shared_memory_offset); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId param_id; - uint32 size; - SharedMemory shared_memory; -}; - -COMPILE_ASSERT(sizeof(SetParamData) == 20, Sizeof_SetParamData_is_not_20); -COMPILE_ASSERT(offsetof(SetParamData, header) == 0, - OffsetOf_SetParamData_header_not_0); -COMPILE_ASSERT(offsetof(SetParamData, param_id) == 4, - OffsetOf_SetParamData_param_id_not_4); -COMPILE_ASSERT(offsetof(SetParamData, size) == 8, - OffsetOf_SetParamData_size_not_8); -COMPILE_ASSERT(offsetof(SetParamData, shared_memory) == 12, - OffsetOf_SetParamData_shared_memory_not_12); - -struct SetParamDataImmediate { - typedef SetParamDataImmediate ValueType; - static const CommandId kCmdId = kSetParamDataImmediate; - static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; - - void SetHeader(uint32 size) { - header.SetCmdBySize(size); - } - - void Init(ResourceId _param_id, uint32 _size, const void* data) { - SetHeader(_size); - param_id = _param_id; - size = _size; - memcpy(ImmediateDataAddress(this), data, _size); - } - - static void* Set(void* cmd, ResourceId param_id, - uint32 size, const void* data) { - static_cast(cmd)->Init(param_id, size, data); - return NextImmediateCmdAddress(cmd, size); - } - - CommandHeader header; - ResourceId param_id; - uint32 size; -}; - -COMPILE_ASSERT(sizeof(SetParamDataImmediate) == 12, - Sizeof_SetParamDataImmediate_is_not_12); -COMPILE_ASSERT(offsetof(SetParamDataImmediate, header) == 0, - OffsetOf_SetParamDataImmediate_header_not_0); -COMPILE_ASSERT(offsetof(SetParamDataImmediate, param_id) == 4, - OffsetOf_SetParamDataImmediate_param_id_not_4); -COMPILE_ASSERT(offsetof(SetParamDataImmediate, size) == 8, - OffsetOf_SetParamDataImmediate_size_not_8); - -struct GetParamDesc { - typedef GetParamDesc ValueType; - static const CommandId kCmdId = kGetParamDesc; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _param_id, uint32 _size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - SetHeader(); - param_id = _param_id; - size = _size; - shared_memory.Init(shared_memory_id, shared_memory_offset); - } - - static void* Set(void* cmd, ResourceId param_id, uint32 size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - static_cast(cmd)->Init(param_id, size, - shared_memory_id, shared_memory_offset); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId param_id; - uint32 size; - SharedMemory shared_memory; -}; - -COMPILE_ASSERT(sizeof(GetParamDesc) == 20, Sizeof_GetParamDesc_is_not_20); -COMPILE_ASSERT(offsetof(GetParamDesc, header) == 0, - OffsetOf_GetParamDesc_header_not_0); -COMPILE_ASSERT(offsetof(GetParamDesc, param_id) == 4, - OffsetOf_GetParamDesc_id_not_4); -COMPILE_ASSERT(offsetof(GetParamDesc, size) == 8, - OffsetOf_GetParamDesc_size_not_8); -COMPILE_ASSERT(offsetof(GetParamDesc, shared_memory) == 12, - OffsetOf_GetParamDesc_shared_memory_not_12); - -struct GetStreamCount { - typedef GetStreamCount ValueType; - static const CommandId kCmdId = kGetStreamCount; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _effect_id, uint32 _size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - SetHeader(); - effect_id = _effect_id; - size = _size; - shared_memory.Init(shared_memory_id, shared_memory_offset); - } - - static void* Set(void* cmd, ResourceId effect_id, uint32 size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - static_cast(cmd)->Init(effect_id, size, - shared_memory_id, shared_memory_offset); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId effect_id; - uint32 size; - SharedMemory shared_memory; -}; - -COMPILE_ASSERT(sizeof(GetStreamCount) == 20, - Sizeof_GetStreamCount_is_not_20); -COMPILE_ASSERT(offsetof(GetStreamCount, header) == 0, - OffsetOf_GetStreamCount_header_not_0); -COMPILE_ASSERT(offsetof(GetStreamCount, effect_id) == 4, - OffsetOf_GetStreamCount_effect_id_not_4); -COMPILE_ASSERT(offsetof(GetStreamCount, size) == 8, - OffsetOf_GetStreamCount_size_not_8); -COMPILE_ASSERT(offsetof(GetStreamCount, shared_memory) == 12, - OffsetOf_GetStreamCount_shared_memory_not_12); - -struct GetStreamDesc { - typedef GetStreamDesc ValueType; - static const CommandId kCmdId = kGetStreamDesc; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _effect_id, uint32 _index, uint32 _size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - SetHeader(); - effect_id = _effect_id; - index = _index; - size = _size; - shared_memory.Init(shared_memory_id, shared_memory_offset); - } - - static void* Set(void* cmd, ResourceId effect_id, uint32 index, uint32 size, - uint32 shared_memory_id, uint32 shared_memory_offset) { - static_cast(cmd)->Init(effect_id, index, size, - shared_memory_id, shared_memory_offset); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId effect_id; - uint32 index; - uint32 size; - SharedMemory shared_memory; -}; - -COMPILE_ASSERT(sizeof(GetStreamDesc) == 24, Sizeof_GetStreamDesc_is_not_24); -COMPILE_ASSERT(offsetof(GetStreamDesc, header) == 0, - OffsetOf_GetStreamDesc_header_not_0); -COMPILE_ASSERT(offsetof(GetStreamDesc, effect_id) ==4 , - OffsetOf_GetStreamDesc_effect_id_not_4); -COMPILE_ASSERT(offsetof(GetStreamDesc, index) == 8, - OffsetOf_GetStreamDesc_index_not_8); -COMPILE_ASSERT(offsetof(GetStreamDesc, size) == 12, - OffsetOf_GetStreamDesc_size_not_12); -COMPILE_ASSERT(offsetof(GetStreamDesc, shared_memory) == 16, - OffsetOf_GetStreamDesc_shared_memory_not_16); - -struct DestroyTexture { - typedef DestroyTexture ValueType; - static const CommandId kCmdId = kDestroyTexture; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _texture_id) { - SetHeader(); - texture_id = _texture_id; - } - - static void* Set(void* cmd, ResourceId texture_id) { - static_cast(cmd)->Init(texture_id); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId texture_id; -}; - -COMPILE_ASSERT(sizeof(DestroyTexture) == 8, Sizeof_DestroyTexture_is_not_8); -COMPILE_ASSERT(offsetof(DestroyTexture, header) == 0, - OffsetOf_DestroyTexture_header_not_0); -COMPILE_ASSERT(offsetof(DestroyTexture, texture_id) == 4, - OffsetOf_DestroyTexture_texture_id_not_4); - -struct CreateTexture2d { - typedef CreateTexture2d ValueType; - static const CommandId kCmdId = kCreateTexture2d; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - // argument 1 - typedef BitField<0, 16> Width; - typedef BitField<16, 16> Height; - // argument 2 - typedef BitField<0, 4> Levels; - typedef BitField<4, 4> Unused; - typedef BitField<8, 8> Format; - typedef BitField<16, 16> Flags; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _texture_id, - uint32 _width, uint32 _height, uint32 _levels, - texture::Format _format, - bool _enable_render_surfaces) { - SetHeader(); - texture_id = _texture_id; - width_height = Width::MakeValue(_width) | Height::MakeValue(_height); - levels_format_flags = - Levels::MakeValue(_levels) | - Format::MakeValue(_format) | - Flags::MakeValue(_enable_render_surfaces ? 1 : 0); - } - - static void* Set(void* cmd, ResourceId texture_id, - uint32 width, uint32 height, uint32 levels, - texture::Format format, - bool enable_render_surfaces) { - static_cast(cmd)->Init(texture_id, - width, height, levels, format, - enable_render_surfaces); - return NextCmdAddress(cmd); - } - - // TODO(gman): fix this to not use obfusticated fields. - CommandHeader header; - ResourceId texture_id; - uint32 width_height; - uint32 levels_format_flags; -}; - -COMPILE_ASSERT(sizeof(CreateTexture2d) == 16, - Sizeof_CreateTexture2d_is_not_16); -COMPILE_ASSERT(offsetof(CreateTexture2d, header) == 0, - OffsetOf_CreateTexture2d_header_not_0); -COMPILE_ASSERT(offsetof(CreateTexture2d, texture_id) == 4, - OffsetOf_CreateTexture2d_texture_id_not_4); -COMPILE_ASSERT(offsetof(CreateTexture2d, width_height) == 8, - OffsetOf_CreateTexture2d_width_height_not_8); -COMPILE_ASSERT(offsetof(CreateTexture2d, levels_format_flags) == 12, - OffsetOf_CreateTexture2d_levels_format_flags_not_12); - -struct CreateTexture3d { - typedef CreateTexture3d ValueType; - static const CommandId kCmdId = kCreateTexture3d; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - // argument 1 - typedef BitField<0, 16> Width; - typedef BitField<16, 16> Height; - // argument 2 - typedef BitField<0, 16> Depth; - typedef BitField<16, 16> Unused1; - // argument 3 - typedef BitField<0, 4> Levels; - typedef BitField<4, 4> Unused2; - typedef BitField<8, 8> Format; - typedef BitField<16, 16> Flags; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _texture_id, - uint32 _width, uint32 _height, uint32 _depth, - uint32 _levels, texture::Format _format, - bool _enable_render_surfaces) { - SetHeader(); - texture_id = _texture_id; - width_height = Width::MakeValue(_width) | Height::MakeValue(_height); - depth_unused = Depth::MakeValue(_depth); - levels_format_flags = - Levels::MakeValue(_levels) | - Format::MakeValue(_format) | - Flags::MakeValue(_enable_render_surfaces ? 1 : 0); - } - - static void* Set(void* cmd, ResourceId texture_id, - uint32 width, uint32 height, uint32 depth, - uint32 levels, texture::Format format, - bool enable_render_surfaces) { - static_cast(cmd)->Init(texture_id, - width, height, depth, - levels, format, - enable_render_surfaces); - return NextCmdAddress(cmd); - } - - // TODO(gman): fix this to not use obfusticated fields. - CommandHeader header; - ResourceId texture_id; - uint32 width_height; - uint32 depth_unused; - uint32 levels_format_flags; -}; - -COMPILE_ASSERT(sizeof(CreateTexture3d) == 20, - Sizeof_CreateTexture3d_is_not_20); -COMPILE_ASSERT(offsetof(CreateTexture3d, header) == 0, - OffsetOf_CreateTexture3d_header_not_0); -COMPILE_ASSERT(offsetof(CreateTexture3d, texture_id) == 4, - OffsetOf_CreateTexture3d_texture_id_not_4); -COMPILE_ASSERT(offsetof(CreateTexture3d, width_height) == 8, - OffsetOf_CreateTexture3d_width_height_not_8); -COMPILE_ASSERT(offsetof(CreateTexture3d, depth_unused) == 12, - OffsetOf_CreateTexture3d_depth_unused_not_12); -COMPILE_ASSERT(offsetof(CreateTexture3d, levels_format_flags) == 16, - OffsetOf_CreateTexture3d_levels_format_flags_not_16); - -struct CreateTextureCube { - typedef CreateTextureCube ValueType; - static const CommandId kCmdId = kCreateTextureCube; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - // argument 1 - typedef BitField<0, 16> Side; - typedef BitField<16, 16> Unused1; - // argument 2 - typedef BitField<0, 4> Levels; - typedef BitField<4, 4> Unused2; - typedef BitField<8, 8> Format; - typedef BitField<16, 16> Flags; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _texture_id, - uint32 _edge_length, uint32 _levels, texture::Format _format, - bool _enable_render_surfaces) { - SetHeader(); - texture_id = _texture_id; - edge_length = _edge_length; - levels_format_flags = - Levels::MakeValue(_levels) | - Format::MakeValue(_format) | - Flags::MakeValue(_enable_render_surfaces ? 1 : 0); - } - - static void* Set(void* cmd, ResourceId texture_id, - uint32 edge_length, uint32 levels, texture::Format format, - bool enable_render_surfaces) { - static_cast(cmd)->Init(texture_id, - edge_length, levels, format, - enable_render_surfaces); - return NextCmdAddress(cmd); - } - - // TODO(gman): fix this to not use obfusticated fields. - CommandHeader header; - ResourceId texture_id; - uint32 edge_length; - uint32 levels_format_flags; -}; - -COMPILE_ASSERT(sizeof(CreateTextureCube) == 16, - Sizeof_CreateTextureCube_is_not_16); -COMPILE_ASSERT(offsetof(CreateTextureCube, header) == 0, - OffsetOf_CreateTextureCube_header_not_0); -COMPILE_ASSERT(offsetof(CreateTextureCube, texture_id) == 4, - OffsetOf_CreateTextureCube_texture_id_not_4); -COMPILE_ASSERT(offsetof(CreateTextureCube, edge_length) == 8, - OffsetOf_CreateTextureCube_edge_length_not_8); -COMPILE_ASSERT(offsetof(CreateTextureCube, levels_format_flags) == 12, - OffsetOf_CreateTextureCube_levels_format_flags_not_12); - -struct SetTextureData { - typedef SetTextureData ValueType; - static const CommandId kCmdId = kSetTextureData; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - // argument 1 - typedef BitField<0, 16> X; - typedef BitField<16, 16> Y; - // argument 2 - typedef BitField<0, 16> Width; - typedef BitField<16, 16> Height; - // argument 3 - typedef BitField<0, 16> Z; - typedef BitField<16, 16> Depth; - // argument 4 - typedef BitField<0, 4> Level; - typedef BitField<4, 3> Face; - typedef BitField<7, 25> Unused; - - void SetHeader() { - header.SetCmd(); - } - - void Init( - ResourceId _texture_id, - uint32 _x, - uint32 _y, - uint32 _z, - uint32 _width, - uint32 _height, - uint32 _depth, - uint32 _level, - texture::Face _face, - uint32 _row_pitch, - uint32 _slice_pitch, - uint32 _size, - uint32 shared_memory_id, - uint32 shared_memory_offset) { - SetHeader(); - texture_id = _texture_id; - x_y = X::MakeValue(_x) | Y::MakeValue(_y); - width_height = Width::MakeValue(_width) | Height::MakeValue(_height); - z_depth = Z::MakeValue(_z) | Depth::MakeValue(_depth); - level_face = Level::MakeValue(_level) | Face::MakeValue(_face); - row_pitch = _row_pitch; - slice_pitch = _slice_pitch; - size = _size; - shared_memory.Init(shared_memory_id, shared_memory_offset); - } - - static void* Set( - void* cmd, - ResourceId texture_id, - uint32 x, - uint32 y, - uint32 z, - uint32 width, - uint32 height, - uint32 depth, - uint32 level, - texture::Face face, - uint32 row_pitch, - uint32 slice_pitch, - uint32 size, - uint32 shared_memory_id, - uint32 shared_memory_offset) { - static_cast(cmd)->Init( - texture_id, - x, - y, - z, - width, - height, - depth, - level, - face, - row_pitch, - slice_pitch, - size, - shared_memory_id, - shared_memory_offset); - return NextCmdAddress(cmd); - } - - // TODO(gman): fix this to not use obfusticated fields. - CommandHeader header; - ResourceId texture_id; - uint32 x_y; - uint32 width_height; - uint32 z_depth; - uint32 level_face; - uint32 row_pitch; - uint32 slice_pitch; - uint32 size; - SharedMemory shared_memory; -}; - -COMPILE_ASSERT(sizeof(SetTextureData) == 44, - Sizeof_SetTextureData_is_not_44); -COMPILE_ASSERT(offsetof(SetTextureData, header) == 0, - OffsetOf_SetTextureData_header_not_0); -COMPILE_ASSERT(offsetof(SetTextureData, texture_id) == 4, - OffsetOf_SetTextureData_texture_id_not_4); -COMPILE_ASSERT(offsetof(SetTextureData, x_y) == 8, - OffsetOf_SetTextureData_x_y_not_8); -COMPILE_ASSERT(offsetof(SetTextureData, width_height) == 12, - OffsetOf_SetTextureData_width_height_not_12); -COMPILE_ASSERT(offsetof(SetTextureData, z_depth) == 16, - OffsetOf_SetTextureData_z_depth_not_16); -COMPILE_ASSERT(offsetof(SetTextureData, level_face) == 20, - OffsetOf_SetTextureData_level_face_not_20); -COMPILE_ASSERT(offsetof(SetTextureData, row_pitch) == 24, - OffsetOf_SetTextureData_row_pitch_not_24); -COMPILE_ASSERT(offsetof(SetTextureData, slice_pitch) == 28, - OffsetOf_SetTextureData_slice_pitch_not_28); -COMPILE_ASSERT(offsetof(SetTextureData, size) == 32, - OffsetOf_SetTextureData_size_not_32); -COMPILE_ASSERT(offsetof(SetTextureData, shared_memory) == 36, - OffsetOf_SetTextureData_shared_memory_not_36); - -struct SetTextureDataImmediate { - typedef SetTextureDataImmediate ValueType; - static const CommandId kCmdId = kSetTextureDataImmediate; - static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; - - // argument 1 - typedef BitField<0, 16> X; - typedef BitField<16, 16> Y; - // argument 2 - typedef BitField<0, 16> Width; - typedef BitField<16, 16> Height; - // argument 3 - typedef BitField<0, 16> Z; - typedef BitField<16, 16> Depth; - // argument 4 - typedef BitField<0, 4> Level; - typedef BitField<4, 3> Face; - typedef BitField<7, 25> Unused; - - void SetHeader(uint32 size) { - header.SetCmdBySize(size); - } - - void Init( - ResourceId _texture_id, - uint32 _x, - uint32 _y, - uint32 _z, - uint32 _width, - uint32 _height, - uint32 _depth, - uint32 _level, - texture::Face _face, - uint32 _row_pitch, - uint32 _slice_pitch, - uint32 _size, - const void* data) { - SetHeader(_size); - texture_id = _texture_id; - x_y = X::MakeValue(_x) | Y::MakeValue(_y); - width_height = Width::MakeValue(_width) | Height::MakeValue(_height); - z_depth = Z::MakeValue(_z) | Depth::MakeValue(_depth); - level_face = Level::MakeValue(_level) | Face::MakeValue(_face); - row_pitch = _row_pitch; - slice_pitch = _slice_pitch; - size = _size; - memcpy(ImmediateDataAddress(this), data, _size); - } - - static void* Set( - void* cmd, - ResourceId texture_id, - uint32 x, - uint32 y, - uint32 z, - uint32 width, - uint32 height, - uint32 depth, - uint32 level, - texture::Face face, - uint32 row_pitch, - uint32 slice_pitch, - uint32 size, - const void* data) { - static_cast(cmd)->Init( - texture_id, - x, - y, - z, - width, - height, - depth, - level, - face, - row_pitch, - slice_pitch, - size, - data); - return NextImmediateCmdAddress(cmd, size); - } - - // TODO(gman): fix this to not use obfusticated fields. - CommandHeader header; - ResourceId texture_id; - uint32 x_y; - uint32 width_height; - uint32 z_depth; - uint32 level_face; - uint32 row_pitch; - uint32 slice_pitch; - uint32 size; -}; - -COMPILE_ASSERT(sizeof(SetTextureDataImmediate) == 36, - Sizeof_SetTextureDataImmediate_is_not_36); -COMPILE_ASSERT(offsetof(SetTextureDataImmediate, header) == 0, - OffsetOf_SetTextureDataImmediate_header_not_0); -COMPILE_ASSERT(offsetof(SetTextureDataImmediate, texture_id) == 4, - OffsetOf_SetTextureDataImmediate_texture_id_not_4); -COMPILE_ASSERT(offsetof(SetTextureDataImmediate, x_y) == 8, - OffsetOf_SetTextureDataImmediate_x_y_not_8); -COMPILE_ASSERT(offsetof(SetTextureDataImmediate, width_height) == 12, - OffsetOf_SetTextureDataImmediate_width_height_not_12); -COMPILE_ASSERT(offsetof(SetTextureDataImmediate, z_depth) == 16, - OffsetOf_SetTextureDataImmediate_z_depth_not_16); -COMPILE_ASSERT(offsetof(SetTextureDataImmediate, level_face) == 20, - OffsetOf_SetTextureDataImmediate_level_face_not_20); -COMPILE_ASSERT(offsetof(SetTextureDataImmediate, row_pitch) == 24, - OffsetOf_SetTextureDataImmediate_row_pitch_not_24); -COMPILE_ASSERT(offsetof(SetTextureDataImmediate, slice_pitch) == 28, - OffsetOf_SetTextureDataImmediate_slice_pitch_not_28); -COMPILE_ASSERT(offsetof(SetTextureDataImmediate, size) == 32, - OffsetOf_SetTextureDataImmediate_size_not_32); - -struct GetTextureData { - typedef GetTextureData ValueType; - static const CommandId kCmdId = kGetTextureData; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - // argument 1 - typedef BitField<0, 16> X; - typedef BitField<16, 16> Y; - // argument 2 - typedef BitField<0, 16> Width; - typedef BitField<16, 16> Height; - // argument 3 - typedef BitField<0, 16> Z; - typedef BitField<16, 16> Depth; - // argument 4 - typedef BitField<0, 4> Level; - typedef BitField<4, 3> Face; - typedef BitField<7, 25> Unused; - - void SetHeader() { - header.SetCmd(); - } - - void Init( - ResourceId _texture_id, - uint32 _x, - uint32 _y, - uint32 _z, - uint32 _width, - uint32 _height, - uint32 _depth, - uint32 _level, - texture::Face _face, - uint32 _row_pitch, - uint32 _slice_pitch, - uint32 _size, - uint32 shared_memory_id, - uint32 shared_memory_offset) { - SetHeader(); - texture_id = _texture_id; - x_y = X::MakeValue(_x) | Y::MakeValue(_y); - width_height = Width::MakeValue(_width) | Height::MakeValue(_height); - z_depth = Z::MakeValue(_z) | Depth::MakeValue(_depth); - level_face = Level::MakeValue(_level) | Face::MakeValue(_face); - row_pitch = _row_pitch; - slice_pitch = _slice_pitch; - size = _size; - shared_memory.Init(shared_memory_id, shared_memory_offset); - } - - static void* Set( - void* cmd, - ResourceId texture_id, - uint32 x, - uint32 y, - uint32 z, - uint32 width, - uint32 height, - uint32 depth, - uint32 level, - texture::Face face, - uint32 row_pitch, - uint32 slice_pitch, - uint32 size, - uint32 shared_memory_id, - uint32 shared_memory_offset) { - static_cast(cmd)->Init( - texture_id, - x, - y, - z, - width, - height, - depth, - level, - face, - row_pitch, - slice_pitch, - size, - shared_memory_id, - shared_memory_offset); - return NextCmdAddress(cmd); - } - - // TODO(gman): fix this to not use obfusticated fields. - CommandHeader header; - ResourceId texture_id; - uint32 x_y; - uint32 width_height; - uint32 z_depth; - uint32 level_face; - uint32 row_pitch; - uint32 slice_pitch; - uint32 size; - SharedMemory shared_memory; -}; - -COMPILE_ASSERT(sizeof(GetTextureData) == 44, - Sizeof_GetTextureData_is_not_44); -COMPILE_ASSERT(offsetof(GetTextureData, header) == 0, - OffsetOf_GetTextureData_header_not_0); -COMPILE_ASSERT(offsetof(GetTextureData, texture_id) == 4, - OffsetOf_GetTextureData_texture_id_not_4); -COMPILE_ASSERT(offsetof(GetTextureData, x_y) == 8, - OffsetOf_GetTextureData_x_y_not_8); -COMPILE_ASSERT(offsetof(GetTextureData, width_height) == 12, - OffsetOf_GetTextureData_width_height_not_12); -COMPILE_ASSERT(offsetof(GetTextureData, z_depth) == 16, - OffsetOf_GetTextureData_z_depth_not_16); -COMPILE_ASSERT(offsetof(GetTextureData, level_face) == 20, - OffsetOf_GetTextureData_level_face_not_20); -COMPILE_ASSERT(offsetof(GetTextureData, row_pitch) == 24, - OffsetOf_GetTextureData_row_pitch_not_24); -COMPILE_ASSERT(offsetof(GetTextureData, slice_pitch) == 28, - OffsetOf_GetTextureData_slice_pitch_not_28); -COMPILE_ASSERT(offsetof(GetTextureData, size) == 32, - OffsetOf_GetTextureData_size_not_32); -COMPILE_ASSERT(offsetof(GetTextureData, shared_memory) == 36, - OffsetOf_GetTextureData_shared_memory_not_36); - -struct CreateSampler { - typedef CreateSampler ValueType; - static const CommandId kCmdId = kCreateSampler; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _sampler_id) { - SetHeader(); - sampler_id = _sampler_id; - } - - static void* Set(void* cmd, ResourceId sampler_id) { - static_cast(cmd)->Init(sampler_id); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId sampler_id; -}; - -COMPILE_ASSERT(sizeof(CreateSampler) == 8, Sizeof_CreateSampler_is_not_8); -COMPILE_ASSERT(offsetof(CreateSampler, header) == 0, - OffsetOf_CreateSampler_header_not_0); -COMPILE_ASSERT(offsetof(CreateSampler, sampler_id) == 4, - OffsetOf_CreateSampler_sampler_id_not_4); - -struct DestroySampler { - typedef DestroySampler ValueType; - static const CommandId kCmdId = kDestroySampler; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _sampler_id) { - SetHeader(); - sampler_id = _sampler_id; - } - - static void* Set(void* cmd, ResourceId sampler_id) { - static_cast(cmd)->Init(sampler_id); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId sampler_id; -}; - -COMPILE_ASSERT(sizeof(DestroySampler) == 8, Sizeof_DestroySampler_is_not_8); -COMPILE_ASSERT(offsetof(DestroySampler, header) == 0, - OffsetOf_DestroySampler_header_not_0); -COMPILE_ASSERT(offsetof(DestroySampler, sampler_id) == 4, - OffsetOf_DestroySampler_sampler_id_not_4); - -struct SetSamplerStates { - typedef SetSamplerStates ValueType; - static const CommandId kCmdId = kSetSamplerStates; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - // argument 2 - typedef BitField<0, 3> AddressingU; - typedef BitField<3, 3> AddressingV; - typedef BitField<6, 3> AddressingW; - typedef BitField<9, 3> MagFilter; - typedef BitField<12, 3> MinFilter; - typedef BitField<15, 3> MipFilter; - typedef BitField<18, 6> Unused; - typedef BitField<24, 8> MaxAnisotropy; - - void SetHeader() { - header.SetCmd(); - } - - void Init( - ResourceId _sampler_id, - sampler::AddressingMode _address_u_value, - sampler::AddressingMode _address_v_value, - sampler::AddressingMode _address_w_value, - sampler::FilteringMode _mag_filter_value, - sampler::FilteringMode _min_filter_value, - sampler::FilteringMode _mip_filter_value, - uint8 _max_anisotropy) { - SetHeader(); - sampler_id = _sampler_id; - sampler_states = - AddressingU::MakeValue(_address_u_value) | - AddressingV::MakeValue(_address_v_value) | - AddressingW::MakeValue(_address_w_value) | - MagFilter::MakeValue(_mag_filter_value) | - MinFilter::MakeValue(_min_filter_value) | - MipFilter::MakeValue(_mip_filter_value) | - MaxAnisotropy::MakeValue(_max_anisotropy); - } - - static void* Set(void* cmd, - ResourceId sampler_id, - sampler::AddressingMode address_u_value, - sampler::AddressingMode address_v_value, - sampler::AddressingMode address_w_value, - sampler::FilteringMode mag_filter_value, - sampler::FilteringMode min_filter_value, - sampler::FilteringMode mip_filter_value, - uint8 max_anisotropy) { - static_cast(cmd)->Init( - sampler_id, - address_u_value, - address_v_value, - address_w_value, - mag_filter_value, - min_filter_value, - mip_filter_value, - max_anisotropy); - return NextCmdAddress(cmd); - } - - // TODO(gman): fix this to not use obfusticated fields. - CommandHeader header; - ResourceId sampler_id; - uint32 sampler_states; -}; - -COMPILE_ASSERT(sizeof(SetSamplerStates) == 12, - Sizeof_SetSamplerStates_is_not_12); -COMPILE_ASSERT(offsetof(SetSamplerStates, header) == 0, - OffsetOf_SetSamplerStates_header_not_0); -COMPILE_ASSERT(offsetof(SetSamplerStates, sampler_id) == 4, - OffsetOf_SetSamplerStates_sampler_id_not_4); -COMPILE_ASSERT(offsetof(SetSamplerStates, sampler_states) == 8, - OffsetOf_SetSamplerStates_sampler_states_not_8); - -struct SetSamplerBorderColor { - typedef SetSamplerBorderColor ValueType; - static const CommandId kCmdId = kSetSamplerBorderColor; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _sampler_id, - float _red, float _green, float _blue, float _alpha) { - SetHeader(); - sampler_id = _sampler_id; - red = _red; - green = _green; - blue = _blue; - alpha = _alpha; - } - - static void* Set(void* cmd, ResourceId sampler_id, - float red, float green, float blue, float alpha) { - static_cast(cmd)->Init(sampler_id, red, green, blue, alpha); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId sampler_id; - float red; - float blue; - float green; - float alpha; -}; - -COMPILE_ASSERT(sizeof(SetSamplerBorderColor) == 24, - Sizeof_SetSamplerBorderColor_is_not_24); -COMPILE_ASSERT(offsetof(SetSamplerBorderColor, header) == 0, - OffsetOf_SetSamplerBorderColor_header_not_0); -COMPILE_ASSERT(offsetof(SetSamplerBorderColor, sampler_id) == 4, - OffsetOf_SetSamplerBorderColor_sampler_id_not_4); -COMPILE_ASSERT(offsetof(SetSamplerBorderColor, red) == 8, - OffsetOf_SetSamplerBorderColor_red_not_8); -COMPILE_ASSERT(offsetof(SetSamplerBorderColor, blue) == 12, - OffsetOf_SetSamplerBorderColor_blue_not_12); -COMPILE_ASSERT(offsetof(SetSamplerBorderColor, green) == 16, - OffsetOf_SetSamplerBorderColor_green_not_16); -COMPILE_ASSERT(offsetof(SetSamplerBorderColor, alpha) == 20, - OffsetOf_SetSamplerBorderColor_alpha_not_20); - -struct SetSamplerTexture { - typedef SetSamplerTexture ValueType; - static const CommandId kCmdId = kSetSamplerTexture; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _sampler_id, ResourceId _texture_id) { - SetHeader(); - sampler_id = _sampler_id; - texture_id = _texture_id; - } - - static void* Set(void* cmd, ResourceId sampler_id, ResourceId texture_id) { - static_cast(cmd)->Init(sampler_id, texture_id); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId sampler_id; - ResourceId texture_id; -}; - -COMPILE_ASSERT(sizeof(SetSamplerTexture) == 12, - Sizeof_SetSamplerTexture_is_not_12); -COMPILE_ASSERT(offsetof(SetSamplerTexture, header) == 0, - OffsetOf_SetSamplerTexture_header_not_0); -COMPILE_ASSERT(offsetof(SetSamplerTexture, sampler_id) == 4, - OffsetOf_SetSamplerTexture_sampler_id_not_4); -COMPILE_ASSERT(offsetof(SetSamplerTexture, texture_id) == 8, - OffsetOf_SetSamplerTexture_texture_id_not_8); - -struct SetScissor { - typedef SetScissor ValueType; - static const CommandId kCmdId = kSetScissor; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - // argument 0 - typedef BitField<0, 15> X; - typedef BitField<15, 1> Unused; - typedef BitField<16, 15> Y; - typedef BitField<31, 1> Enable; - // argument 1 - typedef BitField<0, 16> Width; - typedef BitField<16, 16> Height; - - void SetHeader() { - header.SetCmd(); - } - - void Init(uint32 _x, - uint32 _y, - uint32 _width, - uint32 _height, - bool _enable) { - SetHeader(); - x_y_enable = - X::MakeValue(_x) | - Y::MakeValue(_y) | - Enable::MakeValue(_enable ? 1 : 0); - width_height = Width::MakeValue(_width) | Height::MakeValue(_height); - } - - static void* Set( - void* cmd, - uint32 x, - uint32 y, - uint32 width, - uint32 height, - bool enable) { - static_cast(cmd)->Init( - x, - y, - width, - height, - enable); - return NextCmdAddress(cmd); - } - - // TODO(gman): fix this to not use obfusticated fields. - CommandHeader header; - uint32 x_y_enable; - uint32 width_height; -}; - -COMPILE_ASSERT(sizeof(SetScissor) == 12, Sizeof_SetScissor_is_not_12); -COMPILE_ASSERT(offsetof(SetScissor, header) == 0, - OffsetOf_SetScissor_header_not_0); -COMPILE_ASSERT(offsetof(SetScissor, x_y_enable) == 4, - OffsetOf_SetScissor_x_y_enable_not_4); -COMPILE_ASSERT(offsetof(SetScissor, width_height) == 8, - OffsetOf_SetScissor_width_height_not_8); - -struct SetPolygonOffset { - typedef SetPolygonOffset ValueType; - static const CommandId kCmdId = kSetPolygonOffset; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(float _slope_factor, float _units) { - SetHeader(); - slope_factor = _slope_factor; - units = _units; - } - - static void* Set(void* cmd, float slope_factor, float units) { - static_cast(cmd)->Init(slope_factor, units); - return NextCmdAddress(cmd); - } - - CommandHeader header; - float slope_factor; - float units; -}; - -COMPILE_ASSERT(sizeof(SetPolygonOffset) == 12, - Sizeof_SetPolygonOffset_is_not_12); -COMPILE_ASSERT(offsetof(SetPolygonOffset, header) == 0, - OffsetOf_SetPolygonOffset_header_not_0); -COMPILE_ASSERT(offsetof(SetPolygonOffset, slope_factor) == 4, - OffsetOf_SetPolygonOffset_slope_factor_not_4); -COMPILE_ASSERT(offsetof(SetPolygonOffset, units) == 8, - OffsetOf_SetPolygonOffset_units_not_8); - -struct SetPointLineRaster { - typedef SetPointLineRaster ValueType; - static const CommandId kCmdId = kSetPointLineRaster; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - // argument 0 - typedef BitField<0, 1> LineSmoothEnable; - typedef BitField<1, 1> PointSpriteEnable; - typedef BitField<2, 30> Unused; - - void SetHeader() { - header.SetCmd(); - } - - void Init(bool _line_smooth_enable, bool _point_sprite_enable, - float _point_size) { - SetHeader(); - enables = - LineSmoothEnable::MakeValue(_line_smooth_enable ? 1 : 0) | - PointSpriteEnable::MakeValue(_point_sprite_enable ? 1 : 0); - point_size = _point_size; - } - - static void* Set(void* cmd, bool line_smooth_enable, bool point_sprite_enable, - float point_size) { - static_cast(cmd)->Init(line_smooth_enable, point_sprite_enable, - point_size); - return NextCmdAddress(cmd); - } - - // TODO(gman): fix this to not use obfusticated fields. - CommandHeader header; - uint32 enables; - float point_size; -}; - -COMPILE_ASSERT(sizeof(SetPointLineRaster) == 12, - Sizeof_SetPointLineRaster_is_not_12); -COMPILE_ASSERT(offsetof(SetPointLineRaster, header) == 0, - OffsetOf_SetPointLineRaster_header_not_0); -COMPILE_ASSERT(offsetof(SetPointLineRaster, enables) == 4, - OffsetOf_SetPointLineRaster_enables_not_4); -COMPILE_ASSERT(offsetof(SetPointLineRaster, point_size) == 8, - OffsetOf_SetPointLineRaster_point_size_not_8); - -struct SetPolygonRaster { - typedef SetPolygonRaster ValueType; - static const CommandId kCmdId = kSetPolygonRaster; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - // argument 0 - typedef BitField<0, 2> FillMode; - typedef BitField<2, 2> CullMode; - typedef BitField<4, 28> Unused; - - void SetHeader() { - header.SetCmd(); - } - - void Init(PolygonMode _fill_mode, FaceCullMode _cull_mode) { - SetHeader(); - fill_cull = FillMode::MakeValue(_fill_mode) | - CullMode::MakeValue(_cull_mode); - } - - static void* Set(void* cmd, PolygonMode fill_mode, FaceCullMode cull_mode) { - static_cast(cmd)->Init(fill_mode, cull_mode); - return NextCmdAddress(cmd); - } - - // TODO(gman): fix this to not use obfusticated fields. - CommandHeader header; - uint32 fill_cull; -}; - -COMPILE_ASSERT(sizeof(SetPolygonRaster) == 8, - Sizeof_SetPolygonRaster_is_not_8); -COMPILE_ASSERT(offsetof(SetPolygonRaster, header) == 0, - OffsetOf_SetPolygonRaster_header_not_0); -COMPILE_ASSERT(offsetof(SetPolygonRaster, fill_cull) == 4, - OffsetOf_SetPolygonRaster_fill_cull_not_4); - -struct SetAlphaTest { - typedef SetAlphaTest ValueType; - static const CommandId kCmdId = kSetAlphaTest; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - // argument 0 - typedef BitField<0, 3> Func; - typedef BitField<3, 28> Unused; - typedef BitField<31, 1> Enable; - - void SetHeader() { - header.SetCmd(); - } - - void Init(Comparison _func, bool _enable, float _value) { - SetHeader(); - func_enable = Func::MakeValue(_func) | Enable::MakeValue(_enable ? 1 : 0); - value = _value; - } - - static void* Set(void* cmd, Comparison func, bool enable, float value) { - static_cast(cmd)->Init(func, enable, value); - return NextCmdAddress(cmd); - } - - // TODO(gman): fix this to not use obfusticated fields. - CommandHeader header; - uint32 func_enable; - float value; -}; - -COMPILE_ASSERT(sizeof(SetAlphaTest) == 12, Sizeof_SetAlphaTest_is_not_12); -COMPILE_ASSERT(offsetof(SetAlphaTest, header) == 0, - OffsetOf_SetAlphaTest_header_not_0); -COMPILE_ASSERT(offsetof(SetAlphaTest, func_enable) == 4, - OffsetOf_SetAlphaTest_func_enable_not_4); -COMPILE_ASSERT(offsetof(SetAlphaTest, value) == 8, - OffsetOf_SetAlphaTest_value_not_8); - -struct SetDepthTest { - typedef SetDepthTest ValueType; - static const CommandId kCmdId = kSetDepthTest; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - // argument 0 - typedef BitField<0, 3> Func; - typedef BitField<3, 27> Unused; - typedef BitField<30, 1> WriteEnable; - typedef BitField<31, 1> Enable; - - void SetHeader() { - header.SetCmd(); - } - - void Init(Comparison _func, bool _write_enable, bool _enable) { - SetHeader(); - func_enable = - Func::MakeValue(_func) | - WriteEnable::MakeValue(_write_enable ? 1 : 0) | - Enable::MakeValue(_enable ? 1 : 0); - } - - static void* Set(void* cmd, - Comparison func, bool write_enable, bool enable) { - static_cast(cmd)->Init(func, write_enable, enable); - return NextCmdAddress(cmd); - } - - // TODO(gman): fix this to not use obfusticated fields. - CommandHeader header; - uint32 func_enable; -}; - -COMPILE_ASSERT(sizeof(SetDepthTest) == 8, Sizeof_SetDepthTest_is_not_8); -COMPILE_ASSERT(offsetof(SetDepthTest, header) == 0, - OffsetOf_SetDepthTest_header_not_0); -COMPILE_ASSERT(offsetof(SetDepthTest, func_enable) == 4, - OffsetOf_SetDepthTest_func_enable_not_4); - -struct SetStencilTest { - typedef SetStencilTest ValueType; - static const CommandId kCmdId = kSetStencilTest; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - // argument 0 - typedef BitField<0, 8> WriteMask; - typedef BitField<8, 8> CompareMask; - typedef BitField<16, 8> ReferenceValue; - typedef BitField<24, 6> Unused0; - typedef BitField<30, 1> SeparateCCW; - typedef BitField<31, 1> Enable; - // argument 1 - typedef BitField<0, 3> CWFunc; - typedef BitField<3, 3> CWPassOp; - typedef BitField<6, 3> CWFailOp; - typedef BitField<9, 3> CWZFailOp; - typedef BitField<12, 4> Unused1; - typedef BitField<16, 3> CCWFunc; - typedef BitField<19, 3> CCWPassOp; - typedef BitField<22, 3> CCWFailOp; - typedef BitField<25, 3> CCWZFailOp; - typedef BitField<28, 4> Unused2; - - void SetHeader() { - header.SetCmd(); - } - - void Init(uint8 _write_mask, - uint8 _compare_mask, - uint8 _reference_value, - bool _separate_ccw, - bool _enable, - Comparison _cw_func, - StencilOp _cw_pass_op, - StencilOp _cw_fail_op, - StencilOp _cw_z_fail_op, - Comparison _ccw_func, - StencilOp _ccw_pass_op, - StencilOp _ccw_fail_op, - StencilOp _ccw_z_fail_op) { - SetHeader(); - stencil_args0 = - WriteMask::MakeValue(_write_mask) | - CompareMask::MakeValue(_compare_mask) | - ReferenceValue::MakeValue(_reference_value) | - SeparateCCW::MakeValue(_separate_ccw ? 1 : 0) | - Enable::MakeValue(_enable ? 1 : 0); - stencil_args1 = - CWFunc::MakeValue(_cw_func) | - CWPassOp::MakeValue(_cw_pass_op) | - CWFailOp::MakeValue(_cw_fail_op) | - CWZFailOp::MakeValue(_cw_z_fail_op) | - CCWFunc::MakeValue(_ccw_func) | - CCWPassOp::MakeValue(_ccw_pass_op) | - CCWFailOp::MakeValue(_ccw_fail_op) | - CCWZFailOp::MakeValue(_ccw_z_fail_op); - } - - static void* Set( - void* cmd, - uint8 write_mask, - uint8 compare_mask, - uint8 reference_value, - bool separate_ccw, - bool enable, - Comparison cw_func, - StencilOp cw_pass_op, - StencilOp cw_fail_op, - StencilOp cw_z_fail_op, - Comparison ccw_func, - StencilOp ccw_pass_op, - StencilOp ccw_fail_op, - StencilOp ccw_z_fail_op) { - static_cast(cmd)->Init( - write_mask, - compare_mask, - reference_value, - separate_ccw, - enable, - cw_func, - cw_pass_op, - cw_fail_op, - cw_z_fail_op, - ccw_func, - ccw_pass_op, - ccw_fail_op, - ccw_z_fail_op); - return NextCmdAddress(cmd); - } - - // TODO(gman): fix this to not use obfusticated fields. - CommandHeader header; - uint32 stencil_args0; - uint32 stencil_args1; -}; - -COMPILE_ASSERT(sizeof(SetStencilTest) == 12, - Sizeof_SetStencilTest_is_not_12); -COMPILE_ASSERT(offsetof(SetStencilTest, header) == 0, - OffsetOf_SetStencilTest_header_not_0); -COMPILE_ASSERT(offsetof(SetStencilTest, stencil_args0) == 4, - OffsetOf_SetStencilTest_stencil_args0_not_4); -COMPILE_ASSERT(offsetof(SetStencilTest, stencil_args1) == 8, - OffsetOf_SetStencilTest_stencil_args1_not_8); - -struct SetColorWrite { - typedef SetColorWrite ValueType; - static const CommandId kCmdId = kSetColorWrite; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - // argument 0 - typedef BitField<0, 1> RedMask; - typedef BitField<1, 1> GreenMask; - typedef BitField<2, 1> BlueMask; - typedef BitField<3, 1> AlphaMask; - typedef BitField<0, 4> AllColorsMask; // alias for RGBA - typedef BitField<4, 27> Unused; - typedef BitField<31, 1> DitherEnable; - - void SetHeader() { - header.SetCmd(); - } - - void Init(uint8 _mask, bool _dither_enable) { - SetHeader(); - flags = - RedMask::MakeValue((_mask | 0x01) != 0 ? 1 : 0) | - GreenMask::MakeValue((_mask | 0x02) != 0 ? 1 : 0) | - BlueMask::MakeValue((_mask | 0x02) != 0 ? 1 : 0) | - AlphaMask::MakeValue((_mask | 0x02) != 0 ? 1 : 0) | - DitherEnable::MakeValue(_dither_enable ? 1 : 0); - } - - static void* Set(void* cmd, uint8 mask, bool dither_enable) { - static_cast(cmd)->Init(mask, dither_enable); - return NextCmdAddress(cmd); - } - - CommandHeader header; - uint32 flags; -}; - -COMPILE_ASSERT(sizeof(SetColorWrite) == 8, Sizeof_SetColorWrite_is_not_8); -COMPILE_ASSERT(offsetof(SetColorWrite, header) == 0, - OffsetOf_SetColorWrite_header_not_0); -COMPILE_ASSERT(offsetof(SetColorWrite, flags) == 4, - OffsetOf_SetColorWrite_flags_not_4); - -struct SetBlending { - typedef SetBlending ValueType; - static const CommandId kCmdId = kSetBlending; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - // argument 0 - typedef BitField<0, 4> ColorSrcFunc; - typedef BitField<4, 4> ColorDstFunc; - typedef BitField<8, 3> ColorEq; - typedef BitField<11, 5> Unused0; - typedef BitField<16, 4> AlphaSrcFunc; - typedef BitField<20, 4> AlphaDstFunc; - typedef BitField<24, 3> AlphaEq; - typedef BitField<27, 3> Unused1; - typedef BitField<30, 1> SeparateAlpha; - typedef BitField<31, 1> Enable; - - void SetHeader() { - header.SetCmd(); - } - - void Init( - BlendFunc _color_src_func, - BlendFunc _color_dst_func, - BlendEq _color_eq, - BlendFunc _alpha_src_func, - BlendFunc _alpha_dst_func, - BlendEq _alpha_eq, - bool _separate_alpha, - bool _enable) { - SetHeader(); - blend_settings = - ColorSrcFunc::MakeValue(_color_src_func) | - ColorDstFunc::MakeValue(_color_dst_func) | - ColorEq::MakeValue(_color_eq) | - AlphaSrcFunc::MakeValue(_alpha_src_func) | - AlphaDstFunc::MakeValue(_alpha_dst_func) | - AlphaEq::MakeValue(_alpha_eq) | - SeparateAlpha::MakeValue(_separate_alpha ? 1 : 0) | - Enable::MakeValue(_enable ? 1 : 0); - } - - static void* Set( - void* cmd, - BlendFunc color_src_func, - BlendFunc color_dst_func, - BlendEq color_eq, - BlendFunc alpha_src_func, - BlendFunc alpha_dst_func, - BlendEq alpha_eq, - bool separate_alpha, - bool enable) { - static_cast(cmd)->Init( - color_src_func, - color_dst_func, - color_eq, - alpha_src_func, - alpha_dst_func, - alpha_eq, - separate_alpha, - enable); - return NextCmdAddress(cmd); - } - - // TODO(gman): fix this to not use obfusticated fields. - CommandHeader header; - uint32 blend_settings; -}; - -COMPILE_ASSERT(sizeof(SetBlending) == 8, Sizeof_SetBlending_is_not_8); -COMPILE_ASSERT(offsetof(SetBlending, header) == 0, - OffsetOf_SetBlending_header_not_0); -COMPILE_ASSERT(offsetof(SetBlending, blend_settings) == 4, - OffsetOf_SetBlending_blend_settings_not_4); - -struct SetBlendingColor { - typedef SetBlendingColor ValueType; - static const CommandId kCmdId = kSetBlendingColor; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(float _red, float _green, float _blue, float _alpha) { - SetHeader(); - red = _red; - green = _green; - blue = _blue; - alpha = _alpha; - } - - static void* Set(void* cmd, - float red, float green, float blue, float alpha) { - static_cast(cmd)->Init(red, green, blue, alpha); - return NextCmdAddress(cmd); - } - - CommandHeader header; - float red; - float blue; - float green; - float alpha; -}; - -COMPILE_ASSERT(sizeof(SetBlendingColor) == 20, - Sizeof_SetBlendingColor_is_not_20); -COMPILE_ASSERT(offsetof(SetBlendingColor, header) == 0, - OffsetOf_SetBlendingColor_header_not_0); -COMPILE_ASSERT(offsetof(SetBlendingColor, red) == 4, - OffsetOf_SetBlendingColor_red_not_4); -COMPILE_ASSERT(offsetof(SetBlendingColor, blue) == 8, - OffsetOf_SetBlendingColor_blue_not_8); -COMPILE_ASSERT(offsetof(SetBlendingColor, green) == 12, - OffsetOf_SetBlendingColor_green_not_12); -COMPILE_ASSERT(offsetof(SetBlendingColor, alpha) == 16, - OffsetOf_SetBlendingColor_alpha_not_16); - -struct CreateRenderSurface { - typedef CreateRenderSurface ValueType; - static const CommandId kCmdId = kCreateRenderSurface; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - // argument 1 - typedef BitField<0, 16> Width; - typedef BitField<16, 16> Height; - // argument 2 may refer to side or depth - typedef BitField<0, 16> Levels; - typedef BitField<16, 16> Side; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _render_surface_id, - ResourceId _texture_id, uint32 _width, uint32 _height, - uint32 _level, uint32 _side) { - SetHeader(); - render_surface_id = _render_surface_id; - // TODO(gman): Why does this need a width and height. It's inherited from - // the texture isn't it? - width_height = Width::MakeValue(_width) | Height::MakeValue(_height); - levels_side = Levels::MakeValue(_level) | Side::MakeValue(_side); - texture_id = _texture_id; - } - - static void* Set(void* cmd, - ResourceId render_surface_id, ResourceId texture_id, - uint32 width, uint32 height, - uint32 level, uint32 side) { - static_cast(cmd)->Init(render_surface_id, texture_id, - width, height, - level, side); - return NextCmdAddress(cmd); - } - - // TODO(gman): fix this to not use obfusticated fields. - CommandHeader header; - ResourceId render_surface_id; - uint32 width_height; - uint32 levels_side; - ResourceId texture_id; -}; - -COMPILE_ASSERT(sizeof(CreateRenderSurface) == 20, - Sizeof_CreateRenderSurface_is_not_20); -COMPILE_ASSERT(offsetof(CreateRenderSurface, header) == 0, - OffsetOf_CreateRenderSurface_header_not_0); -COMPILE_ASSERT(offsetof(CreateRenderSurface, render_surface_id) == 4, - OffsetOf_CreateRenderSurface_render_surface_id_not_4); -COMPILE_ASSERT(offsetof(CreateRenderSurface, width_height) == 8, - OffsetOf_CreateRenderSurface_width_height_not_8); -COMPILE_ASSERT(offsetof(CreateRenderSurface, levels_side) == 12, - OffsetOf_CreateRenderSurface_levels_side_not_12); -COMPILE_ASSERT(offsetof(CreateRenderSurface, texture_id) == 16, - OffsetOf_CreateRenderSurface_texture_id_not_16); - -struct DestroyRenderSurface { - typedef DestroyRenderSurface ValueType; - static const CommandId kCmdId = kDestroyRenderSurface; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _render_surface_id) { - SetHeader(); - render_surface_id = _render_surface_id; - } - - static void* Set(void* cmd, ResourceId render_surface_id) { - static_cast(cmd)->Init(render_surface_id); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId render_surface_id; -}; - -COMPILE_ASSERT(sizeof(DestroyRenderSurface) == 8, - Sizeof_DestroyRenderSurface_is_not_8); -COMPILE_ASSERT(offsetof(DestroyRenderSurface, header) == 0, - OffsetOf_DestroyRenderSurface_header_not_0); -COMPILE_ASSERT(offsetof(DestroyRenderSurface, render_surface_id) == 4, - OffsetOf_DestroyRenderSurface_render_surface_id_not_4); - -struct CreateDepthSurface { - typedef CreateDepthSurface ValueType; - static const CommandId kCmdId = kCreateDepthSurface; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - // argument 1 - typedef BitField<0, 16> Width; - typedef BitField<16, 16> Height; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _depth_surface_id, uint32 _width, uint32 _height) { - SetHeader(); - depth_surface_id = _depth_surface_id; - width_height = Width::MakeValue(_width) | Height::MakeValue(_height); - } - - static void* Set(void* cmd, ResourceId depth_surface_id, - uint32 width, uint32 height) { - static_cast(cmd)->Init(depth_surface_id, width, height); - return NextCmdAddress(cmd); - } - - // TODO(gman): fix this to not use obfusticated fields. - CommandHeader header; - ResourceId depth_surface_id; - uint32 width_height; -}; - -COMPILE_ASSERT(sizeof(CreateDepthSurface) == 12, - Sizeof_CreateDepthSurface_is_not_12); -COMPILE_ASSERT(offsetof(CreateDepthSurface, header) == 0, - OffsetOf_CreateDepthSurface_header_not_0); -COMPILE_ASSERT(offsetof(CreateDepthSurface, depth_surface_id) == 4, - OffsetOf_CreateDepthSurface_depth_surface_id_not_4); -COMPILE_ASSERT(offsetof(CreateDepthSurface, width_height) == 8, - OffsetOf_CreateDepthSurface_width_height_not_8); - -struct DestroyDepthSurface { - typedef DestroyDepthSurface ValueType; - static const CommandId kCmdId = kDestroyDepthSurface; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _depth_surface_id) { - SetHeader(); - depth_surface_id = _depth_surface_id; - } - - static void* Set(void* cmd, ResourceId depth_surface_id) { - static_cast(cmd)->Init(depth_surface_id); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId depth_surface_id; -}; - -COMPILE_ASSERT(sizeof(DestroyDepthSurface) == 8, - Sizeof_DestroyDepthSurface_is_not_8); -COMPILE_ASSERT(offsetof(DestroyDepthSurface, header) == 0, - OffsetOf_DestroyDepthSurface_header_not_0); -COMPILE_ASSERT(offsetof(DestroyDepthSurface, depth_surface_id) == 4, - OffsetOf_DestroyDepthdepth_surface_id_not_4); - -struct SetRenderSurface { - typedef SetRenderSurface ValueType; - static const CommandId kCmdId = kSetRenderSurface; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init(ResourceId _render_surface_id, ResourceId _depth_surface_id) { - SetHeader(); - render_surface_id = _render_surface_id; - depth_surface_id = _depth_surface_id; - } - - static void* Set(void* cmd, - ResourceId render_surface_id, ResourceId depth_surface_id) { - static_cast(cmd)->Init(render_surface_id, depth_surface_id); - return NextCmdAddress(cmd); - } - - CommandHeader header; - ResourceId render_surface_id; - ResourceId depth_surface_id; -}; - -COMPILE_ASSERT(sizeof(SetRenderSurface) == 12, - Sizeof_SetRenderSurface_is_not_12); -COMPILE_ASSERT(offsetof(SetRenderSurface, header) == 0, - OffsetOf_SetRenderSurface_header_not_0); -COMPILE_ASSERT(offsetof(SetRenderSurface, render_surface_id) == 4, - OffsetOf_SetRenderSurface_render_surface_id_not_4); -COMPILE_ASSERT(offsetof(SetRenderSurface, depth_surface_id) == 8, - OffsetOf_SetRenderSurface_depth_surface_id_not_8); - -struct SetBackSurfaces { - typedef SetBackSurfaces ValueType; - static const CommandId kCmdId = kSetBackSurfaces; - static const cmd::ArgFlags kArgFlags = cmd::kFixed; - - void SetHeader() { - header.SetCmd(); - } - - void Init() { - SetHeader(); - } - - static void* Set(void* cmd) { - static_cast(cmd)->Init(); - return NextCmdAddress(cmd); - } - - CommandHeader header; -}; - -COMPILE_ASSERT(sizeof(SetBackSurfaces) == 4, - Sizeof_SetBackSurfaces_is_not_4); -COMPILE_ASSERT(offsetof(SetBackSurfaces, header) == 0, - OffsetOf_SetBackSurfaces_header_not_0); - -#pragma pack(pop) - -} // namespace o3d -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_COMMON_CROSS_CMD_BUFFER_FORMAT_H_ diff --git a/o3d/gpu/command_buffer/common/resource.cc b/o3d/gpu/command_buffer/common/resource.cc deleted file mode 100644 index f3b75ec..0000000 --- a/o3d/gpu/command_buffer/common/resource.cc +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the implementation of the helper functions for resources. - -#include "gpu/command_buffer/common/resource.h" - -namespace command_buffer { - -namespace texture { - -// Gets the number of bytes per block for a given format. -unsigned int GetBytesPerBlock(Format format) { - switch (format) { - case kXRGB8: - case kARGB8: - case kR32F: - return 4; - case kABGR16F: - return 8; - case kABGR32F: - return 16; - case kDXT1: - return 8; - default: - // TODO(petersont): Add DXT3/5 support. - LOG(FATAL) << "Invalid format"; - return 1; - } -} - -// Gets the width of a block for a given format. -unsigned int GetBlockSizeX(Format format) { - switch (format) { - case kXRGB8: - case kARGB8: - case kABGR16F: - case kR32F: - case kABGR32F: - return 1; - case kDXT1: - return 4; - default: - // TODO(petersont): Add DXT3/5 support. - LOG(FATAL) << "Invalid format"; - return 1; - } -} - -// Gets the height of a block for a given format. -unsigned int GetBlockSizeY(Format format) { - // NOTE: currently only supported formats use square blocks. - return GetBlockSizeX(format); -} - -} // namespace texture - -namespace effect_param { - -// Gets the size of the data of a given parameter type. -unsigned int GetDataSize(DataType type) { - switch (type) { - case kUnknown: - return 0; - case kFloat1: - return sizeof(float); // NOLINT - case kFloat2: - return sizeof(float) * 2; // NOLINT - case kFloat3: - return sizeof(float) * 3; // NOLINT - case kFloat4: - return sizeof(float) * 4; // NOLINT - case kMatrix4: - return sizeof(float) * 16; // NOLINT - case kInt: - return sizeof(int); // NOLINT - case kBool: - return sizeof(bool); // NOLINT - case kSampler: - return sizeof(ResourceId); // NOLINT - case kTexture: - return sizeof(ResourceId); // NOLINT - default: - LOG(FATAL) << "Invalid type."; - return 0; - } -} - -} // namespace effect_param - -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/common/resource.h b/o3d/gpu/command_buffer/common/resource.h deleted file mode 100644 index 01de6a1..0000000 --- a/o3d/gpu/command_buffer/common/resource.h +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains definitions for resource flags, enums, and helper -// functions. - -#ifndef GPU_COMMAND_BUFFER_COMMON_CROSS_RESOURCE_H_ -#define GPU_COMMAND_BUFFER_COMMON_CROSS_RESOURCE_H_ - -#include -#include "base/basictypes.h" -#include "base/scoped_ptr.h" -#include "gpu/command_buffer/common/types.h" -#include "gpu/command_buffer/common/logging.h" - -namespace command_buffer { - -// A resource ID, key to the resource maps. -typedef uint32 ResourceId; -// Invalid resource ID. -static const ResourceId kInvalidResource = 0xffffffffU; - -namespace vertex_buffer { -// Vertex buffer flags. -enum Flags { - kNone = 0x00, - kDynamic = 0x01, // This vertex buffer is dynamic and is expected to have - // its data updated often. -}; -} // namespace vertex_buffer - -namespace index_buffer { -// Index buffer flags. -enum Flags { - kNone = 0x00, - kDynamic = 0x01, // This index buffer is dynamic and is expected to have - // its data updated often. - kIndex32Bit = 0x02, // Indices contained in this index buffer are 32 bits - // (unsigned int) instead of 16 bit (unsigned short). -}; -} // namespace index_buffer - -namespace vertex_struct { -// Semantics for input data. -enum Semantic { - kUnknownSemantic = -1, - kPosition = 0, - kNormal, - kColor, - kTexCoord, - kNumSemantics -}; - -// Input data types. -enum Type { - kFloat1, - kFloat2, - kFloat3, - kFloat4, - kUChar4N, - kNumTypes -}; -} // namespace vertex_struct - -namespace effect_param { -enum DataType { - kUnknown, // A parameter exists in the effect, but the type is not - // representable (e.g. MATRIX3x4). - kFloat1, - kFloat2, - kFloat3, - kFloat4, - kMatrix4, - kInt, - kBool, - kSampler, - kTexture, - kNumTypes, - kMake32Bit = 0x7fffffff, -}; -COMPILE_ASSERT(sizeof(DataType) == 4, DataType_should_be_32_bits); - -// Gets the size of the data of a particular type. -unsigned int GetDataSize(DataType type); - -// Structure describing a parameter, filled in by the -// GAPIInterface::GetParamDesc call. -struct Desc { - Uint32 size; // the total memory size needed for the complete - // description. - Uint32 name_offset; // the offset of the parameter name, relative to - // the beginning of the structure. May be 0 if the - // name doesn't fit into the memory buffer. - Uint32 name_size; // the size of the parameter name, including the - // terminating nul character. Will always be set - // even if the name doesn't fit into the buffer. - Uint32 semantic_offset; // the offset of the parameter semantic, relative - // to the beginning of the structure. May be 0 if - // the semantic doesn't fit into the memory - // buffer. - Uint32 semantic_size; // the size of the parameter semantic, including - // the terminating nul character. Will always be - // set even if the semantic doesn't fit into the - // buffer. - Uint32 num_elements; // the number of entries if the parameter is an array - // 0 otherwise. - DataType data_type; // the data type of the parameter. - Uint32 data_size; // the size of the parameter data, in bytes. -}; -} // namespace effect_param - -namespace effect_stream { -struct Desc { - Desc() - : semantic(vertex_struct::kUnknownSemantic), - semantic_index(0) {} - Desc(Uint32 semantic, Uint32 semantic_index) - : semantic(semantic), - semantic_index(semantic_index) {} - Uint32 semantic; // the semantic type - Uint32 semantic_index; -}; -} // namespace effect_stream - -namespace texture { -// Texture flags. -enum Flags { - kNone = 0x00, - kDynamic = 0x01, // This texture is dynamic and is expected to have - // its data updated often. -}; - -// Texel formats. -enum Format { - kUnknown, - kXRGB8, - kARGB8, - kABGR16F, - kR32F, - kABGR32F, - kDXT1 -}; - -// Texture type. -enum Type { - kTexture2d, - kTexture3d, - kTextureCube, -}; - -// Cube map face. -enum Face { - kFacePositiveX, - kFaceNegativeX, - kFacePositiveY, - kFaceNegativeY, - kFacePositiveZ, - kFaceNegativeZ, - kFaceNone = kFacePositiveX, // For non-cube maps. -}; - -// Gets the number of bytes per block for a given texture format. For most -// texture formats, a block is 1x1 texels, but DXT* formats have 4x4 blocks. -unsigned int GetBytesPerBlock(Format format); -// Gets the x dimension of a texel block for a given texture format. For most -// texture formats, a block is 1x1 texels, but DXT* formats have 4x4 blocks. -unsigned int GetBlockSizeX(Format format); -// Gets the y dimension of a texel block for a given texture format. For most -// texture formats, a block is 1x1 texels, but DXT* formats have 4x4 blocks. -unsigned int GetBlockSizeY(Format format); -// Gets the dimension of a mipmap level given the dimension of the base -// level. Every mipmap level is half the size of the previous level, rounding -// down. -inline unsigned int GetMipMapDimension(unsigned int base, - unsigned int level) { - DCHECK_GT(base, 0U); - return std::max(1U, base >> level); -} -} // namespace texture - -namespace sampler { -enum AddressingMode { - kWrap, - kMirrorRepeat, - kClampToEdge, - kClampToBorder, - kNumAddressingMode -}; - -enum FilteringMode { - kNone, - kPoint, - kLinear, - kNumFilteringMode -}; -} // namespace sampler - -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_COMMON_CROSS_RESOURCE_H_ diff --git a/o3d/gpu/command_buffer/common/types.h b/o3d/gpu/command_buffer/common/types.h deleted file mode 100644 index daa01cb..0000000 --- a/o3d/gpu/command_buffer/common/types.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains cross-platform basic type definitions - -#ifndef GPU_COMMAND_BUFFER_COMMON_CROSS_TYPES_H_ -#define GPU_COMMAND_BUFFER_COMMON_CROSS_TYPES_H_ - -#include -#if !defined(COMPILER_MSVC) -#include -#endif -#include - -namespace command_buffer { -#if defined(COMPILER_MSVC) -typedef short Int16; -typedef unsigned short Uint16; -typedef int Int32; -typedef unsigned int Uint32; -#else -typedef int16_t Int16; -typedef uint16_t Uint16; -typedef int32_t Int32; -typedef uint32_t Uint32; -#endif - -typedef std::string String; -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_COMMON_CROSS_TYPES_H_ diff --git a/o3d/gpu/command_buffer/service/big_test_main.cc b/o3d/gpu/command_buffer/service/big_test_main.cc deleted file mode 100644 index cda7d0e..0000000 --- a/o3d/gpu/command_buffer/service/big_test_main.cc +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the entry to the big test program, for linux. - -#include "gpu/command_buffer/service/precompile.h" -#include "gpu/command_buffer/service/cross/big_test_helpers.h" -#include "gpu/command_buffer/service/cross/gl/gapi_gl.h" -#include "gpu/command_buffer/service/linux/x_utils.h" - -namespace command_buffer { - -String *g_program_path = NULL; -GAPIInterface *g_gapi = NULL; - -bool ProcessSystemMessages() { - return true; -} - -} // namespace command_buffer - -using o3d::String; -using o3d::command_buffer::g_program_path; -using o3d::command_buffer::g_gapi; -using o3d::command_buffer::GAPIGL; -using o3d::command_buffer::XWindowWrapper; - - -// Creates a GL-compatible window of specified dimensions. -Window CreateWindow(Display *display, unsigned int width, unsigned int height) { - int attribs[] = { - GLX_RGBA, - GLX_DOUBLEBUFFER, - GLX_RED_SIZE, 1, - GLX_GREEN_SIZE, 1, - GLX_BLUE_SIZE, 1, - None - }; - XVisualInfo *visualInfo = glXChooseVisual(display, - DefaultScreen(display), - attribs); - Window root_window = RootWindow(display, visualInfo->screen); - Colormap colorMap = XCreateColormap(display, root_window, visualInfo->visual, - AllocNone); - - XSetWindowAttributes windowAttributes; - windowAttributes.colormap = colorMap; - windowAttributes.border_pixel = 0; - windowAttributes.event_mask = StructureNotifyMask; - Window window = XCreateWindow(display, root_window, - 0, 0, width, height, 0, visualInfo->depth, - InputOutput, visualInfo->visual, - CWBorderPixel|CWColormap|CWEventMask, - &windowAttributes); - if (!window) return 0; - XMapWindow(display, window); - XSync(display, True); - return window; -} - -// Creates a window, initializes the GAPI instance. -int main(int argc, char *argv[]) { - String program_path = argv[0]; - - // Remove all characters starting with last '/'. - size_t backslash_pos = program_path.rfind('/'); - if (backslash_pos != String::npos) { - program_path.erase(backslash_pos); - } - g_program_path = &program_path; - - GAPIGL gl_gapi; - g_gapi = &gl_gapi; - - Display *display = XOpenDisplay(0); - if (!display) { - LOG(FATAL) << "Could not open the display."; - return 1; - } - - Window window = CreateWindow(display, 300, 300); - if (!window) { - LOG(FATAL) << "Could not create a window."; - return 1; - } - - XWindowWrapper wrapper(display, window); - gl_gapi.set_window_wrapper(&wrapper); - - int ret = big_test_main(argc, argv); - - g_gapi = NULL; - g_program_path = NULL; - return ret; -} diff --git a/o3d/gpu/command_buffer/service/cmd_buffer_engine.h b/o3d/gpu/command_buffer/service/cmd_buffer_engine.h deleted file mode 100644 index 74ad649..0000000 --- a/o3d/gpu/command_buffer/service/cmd_buffer_engine.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file defines the CommandBufferEngine class, providing the main loop for -// the service, exposing the RPC API, managing the command parser. - -#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_CMD_BUFFER_ENGINE_H_ -#define GPU_COMMAND_BUFFER_SERVICE_CROSS_CMD_BUFFER_ENGINE_H_ - -#include "base/basictypes.h" - -namespace command_buffer { - -class CommandBufferEngine { - public: - CommandBufferEngine() { - } - - virtual ~CommandBufferEngine() { - } - - // Gets the base address of a registered shared memory buffer. - // Parameters: - // shm_id: the identifier for the shared memory buffer. - virtual void *GetSharedMemoryAddress(int32 shm_id) = 0; - - // Gets the size of a registered shared memory buffer. - // Parameters: - // shm_id: the identifier for the shared memory buffer. - virtual size_t GetSharedMemorySize(int32 shm_id) = 0; - - // Sets the token value. - virtual void set_token(int32 token) = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(CommandBufferEngine); -}; - -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_CMD_BUFFER_ENGINE_H_ diff --git a/o3d/gpu/command_buffer/service/cmd_parser.cc b/o3d/gpu/command_buffer/service/cmd_parser.cc deleted file mode 100644 index b3486ec..0000000 --- a/o3d/gpu/command_buffer/service/cmd_parser.cc +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the implementation of the command parser. - -#include "gpu/command_buffer/service/precompile.h" -#include "gpu/command_buffer/service/cmd_parser.h" -// TODO(gman): remove this so we can use this code for different formats. -#include "gpu/command_buffer/common/o3d_cmd_format.h" - -namespace command_buffer { - -CommandParser::CommandParser(void *shm_address, - size_t shm_size, - ptrdiff_t offset, - size_t size, - CommandBufferOffset start_get, - AsyncAPIInterface *handler) - : get_(start_get), - put_(start_get), - handler_(handler) { - // check proper alignments. - DCHECK_EQ(0, (reinterpret_cast(shm_address)) % 4); - DCHECK_EQ(0, offset % 4); - DCHECK_EQ(0u, size % 4); - // check that the command buffer fits into the memory buffer. - DCHECK_GE(shm_size, offset + size); - char * buffer_begin = static_cast(shm_address) + offset; - buffer_ = reinterpret_cast(buffer_begin); - entry_count_ = size / 4; -} - -// Process one command, reading the header from the command buffer, and -// forwarding the command index and the arguments to the handler. -// Note that: -// - validation needs to happen on a copy of the data (to avoid race -// conditions). This function only validates the header, leaving the arguments -// validation to the handler, so it can pass a reference to them. -// - get_ is modified *after* the command has been executed. -parse_error::ParseError CommandParser::ProcessCommand() { - CommandBufferOffset get = get_; - if (get == put_) return parse_error::kParseNoError; - - CommandHeader header = buffer_[get].value_header; - if (header.size == 0) { - DLOG(INFO) << "Error: zero sized command in command buffer"; - return parse_error::kParseInvalidSize; - } - - if (header.size + get > entry_count_) { - DLOG(INFO) << "Error: get offset out of bounds"; - return parse_error::kParseOutOfBounds; - } - - parse_error::ParseError result = handler_->DoCommand( - header.command, header.size - 1, buffer_ + get); - // TODO(gman): If you want to log errors this is the best place to catch them. - // It seems like we need an official way to turn on a debug mode and - // get these errors. - if (result != parse_error::kParseNoError) { - ReportError(header.command, result); - } - get_ = (get + header.size) % entry_count_; - return result; -} - -void CommandParser::ReportError(unsigned int command_id, - parse_error::ParseError result) { - DLOG(INFO) << "Error: " << result << " for Command " - << handler_->GetCommandName(command_id); -} - -// Processes all the commands, while the buffer is not empty. Stop if an error -// is encountered. -parse_error::ParseError CommandParser::ProcessAllCommands() { - while (!IsEmpty()) { - parse_error::ParseError error = ProcessCommand(); - if (error) return error; - } - return parse_error::kParseNoError; -} - -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/service/cmd_parser.h b/o3d/gpu/command_buffer/service/cmd_parser.h deleted file mode 100644 index 2209cf8..0000000 --- a/o3d/gpu/command_buffer/service/cmd_parser.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the command parser class. - -#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_CMD_PARSER_H_ -#define GPU_COMMAND_BUFFER_SERVICE_CROSS_CMD_PARSER_H_ - -#include "gpu/command_buffer/common/constants.h" -#include "gpu/command_buffer/common/cmd_buffer_common.h" - -namespace command_buffer { - -class AsyncAPIInterface; - -// Command parser class. This class parses commands from a shared memory -// buffer, to implement some asynchronous RPC mechanism. -class CommandParser { - public: - CommandParser(void *shm_address, - size_t shm_size, - ptrdiff_t offset, - size_t size, - CommandBufferOffset start_get, - AsyncAPIInterface *handler); - - // Gets the "get" pointer. The get pointer is an index into the command - // buffer considered as an array of CommandBufferEntry. - CommandBufferOffset get() const { return get_; } - - // Sets the "put" pointer. The put pointer is an index into the command - // buffer considered as an array of CommandBufferEntry. - void set_put(CommandBufferOffset put) { put_ = put; } - - // Gets the "put" pointer. The put pointer is an index into the command - // buffer considered as an array of CommandBufferEntry. - CommandBufferOffset put() const { return put_; } - - // Checks whether there are commands to process. - bool IsEmpty() const { return put_ == get_; } - - // Processes one command, updating the get pointer. This will return an error - // if there are no commands in the buffer. - parse_error::ParseError ProcessCommand(); - - // Processes all commands until get == put. - parse_error::ParseError ProcessAllCommands(); - - // Reports an error. - void ReportError(unsigned int command_id, parse_error::ParseError result); - - private: - CommandBufferOffset get_; - CommandBufferOffset put_; - CommandBufferEntry *buffer_; - size_t entry_count_; - AsyncAPIInterface *handler_; -}; - -// This class defines the interface for an asynchronous API handler, that -// is responsible for de-multiplexing commands and their arguments. -class AsyncAPIInterface { - public: - AsyncAPIInterface() {} - virtual ~AsyncAPIInterface() {} - - // Executes a command. - // Parameters: - // command: the command index. - // arg_count: the number of CommandBufferEntry arguments. - // cmd_data: the command data. - // Returns: - // parse_error::NO_ERROR if no error was found, one of - // parse_error::ParseError otherwise. - virtual parse_error::ParseError DoCommand( - unsigned int command, - unsigned int arg_count, - const void* cmd_data) = 0; - - // Returns a name for a command. Useful for logging / debuging. - virtual const char* GetCommandName(unsigned int command_id) const = 0; -}; - -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_CMD_PARSER_H_ diff --git a/o3d/gpu/command_buffer/service/cmd_parser_test.cc b/o3d/gpu/command_buffer/service/cmd_parser_test.cc deleted file mode 100644 index 3c9871e..0000000 --- a/o3d/gpu/command_buffer/service/cmd_parser_test.cc +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// Tests for the command parser. - -#include "gpu/command_buffer/service/precompile.h" - -#include "tests/common/win/testing_common.h" -#include "gpu/command_buffer/service/cmd_parser.h" -#include "gpu/command_buffer/service/mocks.h" -#include "base/scoped_ptr.h" - -namespace command_buffer { - -using testing::Return; -using testing::Mock; -using testing::Truly; -using testing::Sequence; -using testing::_; - -// Test fixture for CommandParser test - Creates a mock AsyncAPIInterface, and -// a fixed size memory buffer. Also provides a simple API to create a -// CommandParser. -class CommandParserTest : public testing::Test { - protected: - virtual void SetUp() { - api_mock_.reset(new AsyncAPIMock); - buffer_entry_count_ = 20; - buffer_.reset(new CommandBufferEntry[buffer_entry_count_]); - } - virtual void TearDown() {} - - // Adds a DoCommand expectation in the mock. - void AddDoCommandExpect(parse_error::ParseError _return, - unsigned int command, - unsigned int arg_count, - CommandBufferEntry *args) { - EXPECT_CALL(*api_mock(), DoCommand(command, arg_count, - Truly(AsyncAPIMock::IsArgs(arg_count, args)))) - .InSequence(sequence_) - .WillOnce(Return(_return)); - } - - // Creates a parser, with a buffer of the specified size (in entries). - CommandParser *MakeParser(unsigned int entry_count) { - size_t shm_size = buffer_entry_count_ * - sizeof(CommandBufferEntry); // NOLINT - size_t command_buffer_size = entry_count * - sizeof(CommandBufferEntry); // NOLINT - DCHECK_LE(command_buffer_size, shm_size); - return new CommandParser(buffer(), - shm_size, - 0, - command_buffer_size, - 0, - api_mock()); - } - - unsigned int buffer_entry_count() { return 20; } - AsyncAPIMock *api_mock() { return api_mock_.get(); } - CommandBufferEntry *buffer() { return buffer_.get(); } - private: - unsigned int buffer_entry_count_; - scoped_ptr api_mock_; - scoped_array buffer_; - Sequence sequence_; -}; - -// Tests initialization conditions. -TEST_F(CommandParserTest, TestInit) { - scoped_ptr parser(MakeParser(10)); - EXPECT_EQ(0u, parser->get()); - EXPECT_EQ(0u, parser->put()); - EXPECT_TRUE(parser->IsEmpty()); -} - -// Tests simple commands. -TEST_F(CommandParserTest, TestSimple) { - scoped_ptr parser(MakeParser(10)); - CommandBufferOffset put = parser->put(); - CommandHeader header; - - // add a single command, no args - header.size = 1; - header.command = 123; - buffer()[put++].value_header = header; - - parser->set_put(put); - EXPECT_EQ(put, parser->put()); - - AddDoCommandExpect(parse_error::kParseNoError, 123, 0, NULL); - EXPECT_EQ(parse_error::kParseNoError, parser->ProcessCommand()); - EXPECT_EQ(put, parser->get()); - Mock::VerifyAndClearExpectations(api_mock()); - - // add a single command, 2 args - header.size = 3; - header.command = 456; - buffer()[put++].value_header = header; - buffer()[put++].value_int32 = 2134; - buffer()[put++].value_float = 1.f; - - parser->set_put(put); - EXPECT_EQ(put, parser->put()); - - CommandBufferEntry param_array[2]; - param_array[0].value_int32 = 2134; - param_array[1].value_float = 1.f; - AddDoCommandExpect(parse_error::kParseNoError, 456, 2, param_array); - EXPECT_EQ(parse_error::kParseNoError, parser->ProcessCommand()); - EXPECT_EQ(put, parser->get()); - Mock::VerifyAndClearExpectations(api_mock()); -} - -// Tests having multiple commands in the buffer. -TEST_F(CommandParserTest, TestMultipleCommands) { - scoped_ptr parser(MakeParser(10)); - CommandBufferOffset put = parser->put(); - CommandHeader header; - - // add 2 commands, test with single ProcessCommand() - header.size = 2; - header.command = 789; - buffer()[put++].value_header = header; - buffer()[put++].value_int32 = 5151; - - CommandBufferOffset put_cmd2 = put; - header.size = 2; - header.command = 2121; - buffer()[put++].value_header = header; - buffer()[put++].value_int32 = 3434; - - parser->set_put(put); - EXPECT_EQ(put, parser->put()); - - CommandBufferEntry param_array[2]; - param_array[0].value_int32 = 5151; - AddDoCommandExpect(parse_error::kParseNoError, 789, 1, param_array); - param_array[1].value_int32 = 3434; - AddDoCommandExpect(parse_error::kParseNoError, 2121, 1, - param_array+1); - - EXPECT_EQ(parse_error::kParseNoError, parser->ProcessCommand()); - EXPECT_EQ(put_cmd2, parser->get()); - EXPECT_EQ(parse_error::kParseNoError, parser->ProcessCommand()); - EXPECT_EQ(put, parser->get()); - Mock::VerifyAndClearExpectations(api_mock()); - - // add 2 commands again, test with ProcessAllCommands() - header.size = 2; - header.command = 4545; - buffer()[put++].value_header = header; - buffer()[put++].value_int32 = 5656; - - header.size = 2; - header.command = 6767; - buffer()[put++].value_header = header; - buffer()[put++].value_int32 = 7878; - - parser->set_put(put); - EXPECT_EQ(put, parser->put()); - - param_array[0].value_int32 = 5656; - AddDoCommandExpect(parse_error::kParseNoError, 4545, 1, param_array); - param_array[1].value_int32 = 7878; - AddDoCommandExpect(parse_error::kParseNoError, 6767, 1, - param_array+1); - - EXPECT_EQ(parse_error::kParseNoError, parser->ProcessAllCommands()); - EXPECT_EQ(put, parser->get()); - Mock::VerifyAndClearExpectations(api_mock()); -} - -// Tests that the parser will wrap correctly at the end of the buffer. -TEST_F(CommandParserTest, TestWrap) { - scoped_ptr parser(MakeParser(5)); - CommandBufferOffset put = parser->put(); - CommandHeader header; - - // add 3 commands with no args (1 word each) - for (unsigned int i = 0; i < 3; ++i) { - header.size = 1; - header.command = i; - buffer()[put++].value_header = header; - AddDoCommandExpect(parse_error::kParseNoError, i, 0, NULL); - } - parser->set_put(put); - EXPECT_EQ(put, parser->put()); - EXPECT_EQ(parse_error::kParseNoError, parser->ProcessAllCommands()); - EXPECT_EQ(put, parser->get()); - Mock::VerifyAndClearExpectations(api_mock()); - - // add 1 command with 1 arg (2 words). That should put us at the end of the - // buffer. - header.size = 2; - header.command = 3; - buffer()[put++].value_header = header; - buffer()[put++].value_int32 = 5; - CommandBufferEntry param; - param.value_int32 = 5; - AddDoCommandExpect(parse_error::kParseNoError, 3, 1, ¶m); - - DCHECK_EQ(5u, put); - put = 0; - parser->set_put(put); - EXPECT_EQ(put, parser->put()); - EXPECT_EQ(parse_error::kParseNoError, parser->ProcessAllCommands()); - EXPECT_EQ(put, parser->get()); - Mock::VerifyAndClearExpectations(api_mock()); - - // add 1 command with 1 arg (2 words). - header.size = 2; - header.command = 4; - buffer()[put++].value_header = header; - buffer()[put++].value_int32 = 6; - param.value_int32 = 6; - AddDoCommandExpect(parse_error::kParseNoError, 4, 1, ¶m); - parser->set_put(put); - EXPECT_EQ(put, parser->put()); - EXPECT_EQ(parse_error::kParseNoError, parser->ProcessAllCommands()); - EXPECT_EQ(put, parser->get()); - Mock::VerifyAndClearExpectations(api_mock()); -} - -// Tests error conditions. -TEST_F(CommandParserTest, TestError) { - scoped_ptr parser(MakeParser(5)); - CommandBufferOffset put = parser->put(); - CommandHeader header; - - // Generate a command with size 0. - header.size = 0; - header.command = 3; - buffer()[put++].value_header = header; - - parser->set_put(put); - EXPECT_EQ(put, parser->put()); - EXPECT_EQ(parse_error::kParseInvalidSize, - parser->ProcessAllCommands()); - // check that no DoCommand call was made. - Mock::VerifyAndClearExpectations(api_mock()); - - parser.reset(MakeParser(5)); - put = parser->put(); - - // Generate a command with size 6, extends beyond the end of the buffer. - header.size = 6; - header.command = 3; - buffer()[put++].value_header = header; - - parser->set_put(put); - EXPECT_EQ(put, parser->put()); - EXPECT_EQ(parse_error::kParseOutOfBounds, - parser->ProcessAllCommands()); - // check that no DoCommand call was made. - Mock::VerifyAndClearExpectations(api_mock()); - - parser.reset(MakeParser(5)); - put = parser->put(); - - // Generates 2 commands. - header.size = 1; - header.command = 3; - buffer()[put++].value_header = header; - CommandBufferOffset put_post_fail = put; - header.size = 1; - header.command = 4; - buffer()[put++].value_header = header; - - parser->set_put(put); - EXPECT_EQ(put, parser->put()); - // have the first command fail to parse. - AddDoCommandExpect(parse_error::kParseUnknownCommand, 3, 0, NULL); - EXPECT_EQ(parse_error::kParseUnknownCommand, - parser->ProcessAllCommands()); - // check that only one command was executed, and that get reflects that - // correctly. - EXPECT_EQ(put_post_fail, parser->get()); - Mock::VerifyAndClearExpectations(api_mock()); - // make the second one succeed, and check that the parser recovered fine. - AddDoCommandExpect(parse_error::kParseNoError, 4, 0, NULL); - EXPECT_EQ(parse_error::kParseNoError, parser->ProcessAllCommands()); - EXPECT_EQ(put, parser->get()); - Mock::VerifyAndClearExpectations(api_mock()); -} - -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/service/common_decoder.cc b/o3d/gpu/command_buffer/service/common_decoder.cc deleted file mode 100644 index 22bf445..0000000 --- a/o3d/gpu/command_buffer/service/common_decoder.cc +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "gpu/command_buffer/service/precompile.h" -#include "gpu/command_buffer/service/common_decoder.h" -#include "gpu/command_buffer/service/cmd_buffer_engine.h" - -namespace command_buffer { - -void* CommonDecoder::GetAddressAndCheckSize(unsigned int shm_id, - unsigned int offset, - unsigned int size) { - void* shm_addr = engine_->GetSharedMemoryAddress(shm_id); - if (!shm_addr) return NULL; - size_t shm_size = engine_->GetSharedMemorySize(shm_id); - unsigned int end = offset + size; - if (end > shm_size || end < offset) { - return NULL; - } - return static_cast(shm_addr) + offset; -} - -const char* CommonDecoder::GetCommonCommandName( - cmd::CommandId command_id) const { - return cmd::GetCommandName(command_id); -} - -namespace { - -// A struct to hold info about each command. -struct CommandInfo { - int arg_flags; // How to handle the arguments for this command - int arg_count; // How many arguments are expected for this command. -}; - -// A table of CommandInfo for all the commands. -const CommandInfo g_command_info[] = { - #define COMMON_COMMAND_BUFFER_CMD_OP(name) { \ - cmd::name::kArgFlags, \ - sizeof(cmd::name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ \ - - COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP) - - #undef COMMON_COMMAND_BUFFER_CMD_OP -}; - -} // anonymous namespace. - -// Decode command with its arguments, and call the corresponding method. -// Note: args is a pointer to the command buffer. As such, it could be changed -// by a (malicious) client at any time, so if validation has to happen, it -// should operate on a copy of them. -parse_error::ParseError CommonDecoder::DoCommonCommand( - unsigned int command, - unsigned int arg_count, - const void* cmd_data) { - if (command < arraysize(g_command_info)) { - const CommandInfo& info = g_command_info[command]; - unsigned int info_arg_count = static_cast(info.arg_count); - if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) || - (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) { - switch (command) { - #define COMMON_COMMAND_BUFFER_CMD_OP(name) \ - case cmd::name::kCmdId: \ - return Handle ## name( \ - arg_count, \ - *static_cast(cmd_data)); \ - - COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP) - - #undef COMMON_COMMAND_BUFFER_CMD_OP - } - } else { - return parse_error::kParseInvalidArguments; - } - } - return DoCommonCommand(command, arg_count, cmd_data); - return parse_error::kParseUnknownCommand; -} - -parse_error::ParseError CommonDecoder::HandleNoop( - uint32 arg_count, - const cmd::Noop& args) { - return parse_error::kParseNoError; -} - -parse_error::ParseError CommonDecoder::HandleSetToken( - uint32 arg_count, - const cmd::SetToken& args) { - engine_->set_token(args.token); - return parse_error::kParseNoError; -} - -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/service/common_decoder.h b/o3d/gpu/command_buffer/service/common_decoder.h deleted file mode 100644 index 25d1dbe..0000000 --- a/o3d/gpu/command_buffer/service/common_decoder.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_COMMON_DECODER_H_ -#define GPU_COMMAND_BUFFER_SERVICE_CROSS_COMMON_DECODER_H_ - -#include "gpu/command_buffer/service/cmd_parser.h" - -namespace command_buffer { - -class CommandBufferEngine; - -// This class is a helper base class for implementing the common parts of the -// o3d/gl2 command buffer decoder. -class CommonDecoder : public AsyncAPIInterface { - public: - typedef parse_error::ParseError ParseError; - - CommonDecoder() : engine_(NULL) { - } - virtual ~CommonDecoder() { - } - - // Sets the engine, to get shared memory buffers from, and to set the token - // to. - void set_engine(CommandBufferEngine* engine) { - engine_ = engine; - } - - protected: - // Executes a common command. - // Parameters: - // command: the command index. - // arg_count: the number of CommandBufferEntry arguments. - // cmd_data: the command data. - // Returns: - // parse_error::NO_ERROR if no error was found, one of - // parse_error::ParseError otherwise. - parse_error::ParseError DoCommonCommand( - unsigned int command, - unsigned int arg_count, - const void* cmd_data); - - // Gets the address of shared memory data, given a shared memory ID and an - // offset. Also checks that the size is consistent with the shared memory - // size. - // Parameters: - // shm_id: the id of the shared memory buffer. - // offset: the offset of the data in the shared memory buffer. - // size: the size of the data. - // Returns: - // NULL if shm_id isn't a valid shared memory buffer ID or if the size - // check fails. Return a pointer to the data otherwise. - void* GetAddressAndCheckSize(unsigned int shm_id, - unsigned int offset, - unsigned int size); - - // Gets an name for a common command. - const char* GetCommonCommandName(cmd::CommandId command_id) const; - - private: - // Generate a member function prototype for each command in an automated and - // typesafe way. - #define COMMON_COMMAND_BUFFER_CMD_OP(name) \ - parse_error::ParseError Handle ## name( \ - unsigned int arg_count, \ - const cmd::name& args); \ - - COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP) - - #undef COMMON_COMMAND_BUFFER_CMD_OP - - CommandBufferEngine* engine_; -}; - -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_COMMON_DECODER_H_ - diff --git a/o3d/gpu/command_buffer/service/d3d9_utils.h b/o3d/gpu/command_buffer/service/d3d9_utils.h deleted file mode 100644 index 5938ac0..0000000 --- a/o3d/gpu/command_buffer/service/d3d9_utils.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file defines a few utilities for Direct3D. - -#ifndef GPU_COMMAND_BUFFER_SERVICE_D3D9_UTILS_H_ -#define GPU_COMMAND_BUFFER_SERVICE_D3D9_UTILS_H_ - -#ifndef NOMINMAX -// windows.h defines min() and max() as macros, conflicting with std::min and -// std::max unless NOMINMAX is defined. -#define NOMINMAX -#endif -#include -#include -#include -#include -#include -#include "gpu/command_buffer/common/gapi_interface.h" - -#if defined (_DEBUG) - -#ifndef HR -#define HR(x) { \ - HRESULT hr = x; \ - if (FAILED(hr)) { \ - LOG(ERROR) << "DirectX error at " << __FILE__ << ":" << __LINE__ \ - << " when calling " << #x << ": " << DXGetErrorStringA(hr); \ - } \ - } -#endif - -#else // _DEBUG - -#ifndef HR -#define HR(x) x; -#endif - -#endif // _DEBUG - -namespace command_buffer { - -union FloatAndDWORD { - float float_value; - DWORD dword_value; -}; - -// Bit casts a float into a DWORD. That's what D3D expects for some values. -inline DWORD FloatAsDWORD(float value) { - volatile FloatAndDWORD float_and_dword; - float_and_dword.float_value = value; - return float_and_dword.dword_value; -} - -// Clamps a float to [0 .. 1] and maps it to [0 .. 255] -inline unsigned int FloatToClampedByte(float value) { - value = std::min(1.f, std::max(0.f, value)); - return static_cast(value * 255); -} - -// Converts a RGBA color into a D3DCOLOR -inline D3DCOLOR RGBAToD3DCOLOR(const o3d::RGBA &color) { - return D3DCOLOR_RGBA(FloatToClampedByte(color.red), - FloatToClampedByte(color.green), - FloatToClampedByte(color.blue), - FloatToClampedByte(color.alpha)); -} - -static bool D3DSemanticToCBSemantic( - D3DDECLUSAGE semantic, - unsigned int semantic_index, - vertex_struct::Semantic *out_semantic, - unsigned int *out_semantic_index) { - // TODO: what meaning do we really want to put to our semantics ? How - // do they match the semantics that are set in the effect ? What combination - // of (semantic, index) are supposed to work ? - // TODO(gman): This is just plain wrong! Fix it. Converting binormal to - // texcoord 7 means there will be conflicts if I have both a Binormal and a - // texcoord 7 or 2 binormals both of which we have examples of already in O3D! - switch (semantic) { - case D3DDECLUSAGE_POSITION: - if (semantic_index != 0) return false; - *out_semantic = vertex_struct::kPosition; - *out_semantic_index = 0; - return true; - case D3DDECLUSAGE_NORMAL: - if (semantic_index != 0) return false; - *out_semantic = vertex_struct::kNormal; - *out_semantic_index = 0; - return true; - case D3DDECLUSAGE_TANGENT: - if (semantic_index != 0) return false; - *out_semantic = vertex_struct::kTexCoord; - *out_semantic_index = 6; - return true; - case D3DDECLUSAGE_BINORMAL: - if (semantic_index != 0) return false; - *out_semantic = vertex_struct::kTexCoord; - *out_semantic_index = 7; - return true; - case D3DDECLUSAGE_COLOR: - if (semantic_index > 1) return false; - *out_semantic = vertex_struct::kColor; - *out_semantic_index = semantic_index; - return true; - case D3DDECLUSAGE_TEXCOORD: - *out_semantic = vertex_struct::kTexCoord; - *out_semantic_index = semantic_index; - return true; - default: - return false; - } -} -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_SERVICE_D3D9_UTILS_H_ diff --git a/o3d/gpu/command_buffer/service/effect_d3d9.cc b/o3d/gpu/command_buffer/service/effect_d3d9.cc deleted file mode 100644 index 4bfae53..0000000 --- a/o3d/gpu/command_buffer/service/effect_d3d9.cc +++ /dev/null @@ -1,679 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the implementation of the D3D9 versions of the -// Effect resource. -// This file also contains the related GAPID3D9 function implementations. - -#include "gpu/command_buffer/service/precompile.h" - -#include -#include "gpu/command_buffer/service/d3d9_utils.h" -#include "gpu/command_buffer/service/geometry_d3d9.h" -#include "gpu/command_buffer/service/gapi_d3d9.h" -#include "gpu/command_buffer/service/effect_d3d9.h" -#include "gpu/command_buffer/service/sampler_d3d9.h" -#include "gpu/command_buffer/service/effect_utils.h" - -// TODO: remove link-dependency on D3DX. - -namespace command_buffer { -namespace o3d { - -// Logs the D3D effect error, from either the buffer, or GetLastError(). -static void LogFXError(LPD3DXBUFFER error_buffer) { - if (error_buffer) { - LPVOID compile_errors = error_buffer->GetBufferPointer(); - LOG(ERROR) << "Failed to compile effect: " - << static_cast(compile_errors); - } else { - HLOCAL hLocal = NULL; - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER, - NULL, - GetLastError(), - 0, - reinterpret_cast(&hLocal), - 0, - NULL); - wchar_t* msg = reinterpret_cast(LocalLock(hLocal)); - LOG(ERROR) << "Failed to compile effect: " << msg; - LocalFree(hLocal); - } -} - -EffectD3D9::EffectD3D9(GAPID3D9 *gapi, - ID3DXEffect *d3d_effect, - ID3DXConstantTable *fs_constant_table, - IDirect3DVertexShader9 *d3d_vertex_shader) - : gapi_(gapi), - d3d_effect_(d3d_effect), - fs_constant_table_(fs_constant_table), - d3d_vertex_shader_(d3d_vertex_shader), - sync_parameters_(false) { - for (unsigned int i = 0; i < kMaxSamplerUnits; ++i) { - samplers_[i] = kInvalidResource; - } - SetStreams(); -} -// Releases the D3D effect. -EffectD3D9::~EffectD3D9() { - for (ParamList::iterator it = params_.begin(); it != params_.end(); ++it) { - (*it)->ResetEffect(); - } - DCHECK(d3d_effect_); - d3d_effect_->Release(); - DCHECK(fs_constant_table_); - fs_constant_table_->Release(); - DCHECK(d3d_vertex_shader_); - d3d_vertex_shader_->Release(); -} - -// Compiles the effect, and checks that the effect conforms to what we expect -// (no extra technique or pass in the effect code, since one is implicitly added -// using the program entry points) and that it validates. If successful, wrap -// the D3D effect into a new EffectD3D9. -EffectD3D9 *EffectD3D9::Create(GAPID3D9 *gapi, - const String& effect_code, - const String& vertex_program_entry, - const String& fragment_program_entry) { - String prepared_effect = effect_code + - "technique Shaders { " - " pass p0 { " - " VertexShader = compile vs_2_0 " + vertex_program_entry + "();" - " PixelShader = compile ps_2_0 " + fragment_program_entry + "();" - " }" - "};"; - ID3DXEffect *d3d_effect = NULL; - LPD3DXBUFFER error_buffer; - IDirect3DDevice9 *device = gapi->d3d_device(); - if (gapi->D3DXCreateEffect(device, - prepared_effect.c_str(), - prepared_effect.size(), - NULL, - NULL, - 0, - NULL, - &d3d_effect, - &error_buffer) != D3D_OK) { - LogFXError(error_buffer); - return NULL; - } - // check that . - D3DXEFFECT_DESC effect_desc; - HR(d3d_effect->GetDesc(&effect_desc)); - if (effect_desc.Techniques != 1) { - LOG(ERROR) << "Only 1 technique is allowed in an effect."; - d3d_effect->Release(); - return NULL; - } - D3DXHANDLE technique = d3d_effect->GetTechnique(0); - DCHECK(technique); - if (d3d_effect->ValidateTechnique(technique) != D3D_OK) { - LOG(ERROR) << "Technique doesn't validate."; - d3d_effect->Release(); - return NULL; - } - D3DXTECHNIQUE_DESC technique_desc; - HR(d3d_effect->GetTechniqueDesc(technique, &technique_desc)); - if (technique_desc.Passes != 1) { - LOG(ERROR) << "Only 1 pass is allowed in an effect."; - d3d_effect->Release(); - return NULL; - } - d3d_effect->SetTechnique(technique); - D3DXHANDLE pass = d3d_effect->GetPass(technique, 0); - D3DXPASS_DESC pass_desc; - HR(d3d_effect->GetPassDesc(pass, &pass_desc)); - ID3DXConstantTable *table = NULL; - HR(gapi->D3DXGetShaderConstantTable(pass_desc.pPixelShaderFunction, - &table)); - if (!table) { - LOG(ERROR) << "Could not get the constant table."; - d3d_effect->Release(); - return NULL; - } - IDirect3DVertexShader9 *d3d_vertex_shader = NULL; - HR(device->CreateVertexShader(pass_desc.pVertexShaderFunction, - &d3d_vertex_shader)); - if (!d3d_vertex_shader) { - d3d_effect->Release(); - table->Release(); - DLOG(ERROR) << "Failed to create vertex shader"; - return NULL; - } - - return new EffectD3D9(gapi, d3d_effect, table, d3d_vertex_shader); -} - -// Begins rendering with the effect, setting all the appropriate states. -bool EffectD3D9::Begin() { - UINT numpasses; - HR(d3d_effect_->Begin(&numpasses, 0)); - HR(d3d_effect_->BeginPass(0)); - sync_parameters_ = false; - return SetSamplers(); -} - -// Terminates rendering with the effect, resetting all the appropriate states. -void EffectD3D9::End() { - HR(d3d_effect_->EndPass()); - HR(d3d_effect_->End()); -} - -// Gets the parameter count from the D3D effect description. -unsigned int EffectD3D9::GetParamCount() { - D3DXEFFECT_DESC effect_desc; - HR(d3d_effect_->GetDesc(&effect_desc)); - return effect_desc.Parameters; -} - -// Gets the number of input streams from the shader. -unsigned int EffectD3D9::GetStreamCount() { - return streams_.size(); -} - -// Retrieves the matching DataType from a D3D parameter description. -static effect_param::DataType GetDataTypeFromD3D( - const D3DXPARAMETER_DESC &desc) { - switch (desc.Type) { - case D3DXPT_FLOAT: - switch (desc.Class) { - case D3DXPC_SCALAR: - return effect_param::kFloat1; - case D3DXPC_VECTOR: - switch (desc.Columns) { - case 2: - return effect_param::kFloat2; - case 3: - return effect_param::kFloat3; - case 4: - return effect_param::kFloat4; - default: - return effect_param::kUnknown; - } - case D3DXPC_MATRIX_ROWS: - case D3DXPC_MATRIX_COLUMNS: - if (desc.Columns == 4 && desc.Rows == 4) { - return effect_param::kMatrix4; - } else { - return effect_param::kUnknown; - } - default: - return effect_param::kUnknown; - } - case D3DXPT_INT: - if (desc.Class == D3DXPC_SCALAR) { - return effect_param::kInt; - } else { - return effect_param::kUnknown; - } - case D3DXPT_BOOL: - if (desc.Class == D3DXPC_SCALAR) { - return effect_param::kBool; - } else { - return effect_param::kUnknown; - } - case D3DXPT_SAMPLER: - case D3DXPT_SAMPLER2D: - case D3DXPT_SAMPLER3D: - case D3DXPT_SAMPLERCUBE: - if (desc.Class == D3DXPC_OBJECT) { - return effect_param::kSampler; - } else { - return effect_param::kUnknown; - } - case D3DXPT_TEXTURE: - case D3DXPT_TEXTURE1D: - case D3DXPT_TEXTURE2D: - case D3DXPT_TEXTURE3D: - case D3DXPT_TEXTURECUBE: - if (desc.Class == D3DXPC_OBJECT) { - return effect_param::kTexture; - } else { - return effect_param::kUnknown; - } - default: - return effect_param::kUnknown; - } -} - -// Gets a handle to the selected parameter, and wraps it into an -// EffectParamD3D9 if successful. -EffectParamD3D9 *EffectD3D9::CreateParam(unsigned int index) { - D3DXHANDLE handle = d3d_effect_->GetParameter(NULL, index); - if (!handle) return NULL; - return EffectParamD3D9::Create(this, handle); -} - -// Gets a handle to the selected parameter, and wraps it into an -// EffectParamD3D9 if successful. -EffectParamD3D9 *EffectD3D9::CreateParamByName(const char *name) { - D3DXHANDLE handle = d3d_effect_->GetParameterByName(NULL, name); - if (!handle) return NULL; - return EffectParamD3D9::Create(this, handle); -} - -bool EffectD3D9::CommitParameters() { - if (sync_parameters_) { - sync_parameters_ = false; - d3d_effect_->CommitChanges(); - return SetSamplers(); - } else { - return true; - } -} - -bool EffectD3D9::SetSamplers() { - IDirect3DDevice9 *d3d_device = gapi_->d3d_device(); - bool result = true; - for (unsigned int i = 0; i < kMaxSamplerUnits; ++i) { - SamplerD3D9 *sampler = gapi_->GetSampler(samplers_[i]); - if (sampler) { - result &= sampler->ApplyStates(gapi_, i); - } else { - HR(d3d_device->SetTexture(i, NULL)); - } - } - return result; -} - -bool EffectD3D9::SetStreams() { - if (!d3d_vertex_shader_) { - return false; - } - UINT size; - d3d_vertex_shader_->GetFunction(NULL, &size); - scoped_array function(new DWORD[size]); - d3d_vertex_shader_->GetFunction(function.get(), &size); - - UINT num_semantics; - HR(gapi_->D3DXGetShaderInputSemantics(function.get(), - NULL, - &num_semantics)); - scoped_array semantics(new D3DXSEMANTIC[num_semantics]); - HR(gapi_->D3DXGetShaderInputSemantics(function.get(), - semantics.get(), - &num_semantics)); - - streams_.resize(num_semantics); - for (UINT i = 0; i < num_semantics; ++i) { - vertex_struct::Semantic semantic; - unsigned int semantic_index; - if (D3DSemanticToCBSemantic(static_cast(semantics[i].Usage), - static_cast(semantics[i].UsageIndex), - &semantic, &semantic_index)) { - streams_[i].semantic = semantic; - streams_[i].semantic_index = semantic_index; - } - } - return true; -} - -void EffectD3D9::LinkParam(EffectParamD3D9 *param) { - params_.push_back(param); -} - -void EffectD3D9::UnlinkParam(EffectParamD3D9 *param) { - std::remove(params_.begin(), params_.end(), param); -} - -// Fills the Desc structure, appending name and semantic if any, and if enough -// room is available in the buffer. -bool EffectD3D9::GetStreamDesc(unsigned int index, - unsigned int size, - void *data) { - using effect_stream::Desc; - if (size < sizeof(Desc)) // NOLINT - return false; - - Desc *desc = static_cast(data); - *desc = streams_[index]; - return true; -} - -EffectParamD3D9::EffectParamD3D9(effect_param::DataType data_type, - EffectD3D9 *effect, - D3DXHANDLE handle) - : EffectParam(data_type), - effect_(effect), - handle_(handle), - sampler_units_(NULL), - sampler_unit_count_(0) { - DCHECK(effect_); - effect_->LinkParam(this); -} - -EffectParamD3D9::~EffectParamD3D9() { - if (effect_) effect_->UnlinkParam(this); -} - -EffectParamD3D9 *EffectParamD3D9::Create(EffectD3D9 *effect, - D3DXHANDLE handle) { - DCHECK(effect); - D3DXPARAMETER_DESC desc; - HR(effect->d3d_effect_->GetParameterDesc(handle, &desc)); - effect_param::DataType data_type = GetDataTypeFromD3D(desc); - EffectParamD3D9 *param = new EffectParamD3D9(data_type, effect, handle); - if (data_type == effect_param::kSampler) { - ID3DXConstantTable *table = effect->fs_constant_table_; - DCHECK(table); - D3DXHANDLE sampler_handle = table->GetConstantByName(NULL, desc.Name); - if (sampler_handle) { - D3DXCONSTANT_DESC desc_array[kMaxSamplerUnits]; - unsigned int num_desc = kMaxSamplerUnits; - table->GetConstantDesc(sampler_handle, desc_array, &num_desc); - // We have no good way of querying how many descriptions would really be - // returned as we're capping the number to kMaxSamplerUnits (which should - // be more than sufficient). If however we do end up with the max number - // there's a chance that there were actually more so let's log it. - if (num_desc == kMaxSamplerUnits) { - DLOG(WARNING) << "Number of constant descriptions might have exceeded " - << "the maximum of " << kMaxSamplerUnits; - } - param->sampler_unit_count_ = 0; - if (num_desc > 0) { - param->sampler_units_.reset(new unsigned int[num_desc]); - for (unsigned int desc_index = 0; desc_index < num_desc; desc_index++) { - D3DXCONSTANT_DESC constant_desc = desc_array[desc_index]; - if (constant_desc.Class == D3DXPC_OBJECT && - (constant_desc.Type == D3DXPT_SAMPLER || - constant_desc.Type == D3DXPT_SAMPLER2D || - constant_desc.Type == D3DXPT_SAMPLER3D || - constant_desc.Type == D3DXPT_SAMPLERCUBE)) { - param->sampler_units_[param->sampler_unit_count_++] = - constant_desc.RegisterIndex; - } - } - } - } - // if the sampler hasn't been found in the constant table, that means it - // isn't referenced, hence it doesn't use any sampler unit. - } - return param; -} - -// Fills the Desc structure, appending name and semantic if any, and if enough -// room is available in the buffer. -bool EffectParamD3D9::GetDesc(unsigned int size, void *data) { - using effect_param::Desc; - if (size < sizeof(Desc)) // NOLINT - return false; - if (!effect_) - return false; - ID3DXEffect *d3d_effect = effect_->d3d_effect_; - D3DXPARAMETER_DESC d3d_desc; - HR(d3d_effect->GetParameterDesc(handle_, &d3d_desc)); - unsigned int name_size = - d3d_desc.Name ? static_cast(strlen(d3d_desc.Name)) + 1 : 0; - unsigned int semantic_size = d3d_desc.Semantic ? - static_cast(strlen(d3d_desc.Semantic)) + 1 : 0; - unsigned int total_size = sizeof(Desc) + name_size + semantic_size; // NOLINT - - Desc *desc = static_cast(data); - memset(desc, 0, sizeof(*desc)); - desc->size = total_size; - desc->data_type = data_type(); - desc->data_size = GetDataSize(data_type()); - desc->name_offset = 0; - desc->name_size = name_size; - desc->num_elements = d3d_desc.Elements; - desc->semantic_offset = 0; - desc->semantic_size = semantic_size; - unsigned int current_offset = sizeof(Desc); - if (d3d_desc.Name && current_offset + name_size <= size) { - desc->name_offset = current_offset; - memcpy(static_cast(data) + current_offset, - d3d_desc.Name, name_size); - current_offset += name_size; - } - if (d3d_desc.Semantic && current_offset + semantic_size <= size) { - desc->semantic_offset = current_offset; - memcpy(static_cast(data) + current_offset, - d3d_desc.Semantic, semantic_size); - current_offset += semantic_size; - } - return true; -} - -// Sets the data into the D3D effect parameter, using the appropriate D3D call. -bool EffectParamD3D9::SetData(GAPID3D9 *gapi, - unsigned int size, - const void * data) { - if (!effect_) - return false; - ID3DXEffect *d3d_effect = effect_->d3d_effect_; - effect_param::DataType type = data_type(); - if (size < effect_param::GetDataSize(type)) return false; - switch (type) { - case effect_param::kFloat1: - HR(d3d_effect->SetFloat(handle_, *static_cast(data))); - break; - case effect_param::kFloat2: - HR(d3d_effect->SetFloatArray(handle_, static_cast(data), - 2)); - break; - case effect_param::kFloat3: - HR(d3d_effect->SetFloatArray(handle_, static_cast(data), - 3)); - break; - case effect_param::kFloat4: - HR(d3d_effect->SetFloatArray(handle_, static_cast(data), - 4)); - break; - case effect_param::kMatrix4: - HR(d3d_effect->SetMatrix(handle_, - reinterpret_cast(data))); - break; - case effect_param::kInt: - HR(d3d_effect->SetInt(handle_, *static_cast(data))); - break; - case effect_param::kBool: - HR(d3d_effect->SetBool(handle_, *static_cast(data)?1:0)); - break; - case effect_param::kSampler: { - ResourceId id = *static_cast(data); - for (unsigned int i = 0; i < sampler_unit_count_; ++i) { - effect_->samplers_[sampler_units_[i]] = id; - } - break; - } - case effect_param::kTexture: { - // TODO(rlp): finish - break; - } - default: - DLOG(ERROR) << "Invalid parameter type."; - return false; - } - if (effect_ == gapi->current_effect()) { - effect_->sync_parameters_ = true; - } - return true; -} - -// Calls EffectD3D9::Create, and assign the result to the resource ID. -// If changing the current effect, dirty it. -parse_error::ParseError GAPID3D9::CreateEffect( - ResourceId id, - unsigned int size, - const void *data) { - if (id == current_effect_id_) DirtyEffect(); - // Even though Assign would Destroy the effect at id, we do it explicitly in - // case the creation fails. - effects_.Destroy(id); - // Data is vp_main \0 fp_main \0 effect_text. - String vertex_program_entry; - String fragment_program_entry; - String effect_code; - if (!ParseEffectData(size, data, - &vertex_program_entry, - &fragment_program_entry, - &effect_code)) { - return parse_error::kParseInvalidArguments; - } - EffectD3D9 * effect = EffectD3D9::Create(this, effect_code, - vertex_program_entry, - fragment_program_entry); - if (!effect) return parse_error::kParseInvalidArguments; - effects_.Assign(id, effect); - return parse_error::kParseNoError; -} - -// Destroys the Effect resource. -// If destroying the current effect, dirty it. -parse_error::ParseError GAPID3D9::DestroyEffect(ResourceId id) { - if (id == current_effect_id_) DirtyEffect(); - return effects_.Destroy(id) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -// Sets the current effect ID, dirtying the current effect. -parse_error::ParseError GAPID3D9::SetEffect(ResourceId id) { - DirtyEffect(); - current_effect_id_ = id; - return parse_error::kParseNoError; -} - -// Gets the param count from the effect and store it in the memory buffer. -parse_error::ParseError GAPID3D9::GetParamCount( - ResourceId id, - unsigned int size, - void *data) { - EffectD3D9 *effect = effects_.Get(id); - if (!effect || size < sizeof(Uint32)) // NOLINT - return parse_error::kParseInvalidArguments; - *static_cast(data) = effect->GetParamCount(); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPID3D9::CreateParam( - ResourceId param_id, - ResourceId effect_id, - unsigned int index) { - EffectD3D9 *effect = effects_.Get(effect_id); - if (!effect) return parse_error::kParseInvalidArguments; - EffectParamD3D9 *param = effect->CreateParam(index); - if (!param) return parse_error::kParseInvalidArguments; - effect_params_.Assign(param_id, param); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPID3D9::CreateParamByName( - ResourceId param_id, - ResourceId effect_id, - unsigned int size, - const void *name) { - EffectD3D9 *effect = effects_.Get(effect_id); - if (!effect) return parse_error::kParseInvalidArguments; - std::string string_name(static_cast(name), size); - EffectParamD3D9 *param = effect->CreateParamByName(string_name.c_str()); - if (!param) return parse_error::kParseInvalidArguments; - effect_params_.Assign(param_id, param); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPID3D9::DestroyParam(ResourceId id) { - return effect_params_.Destroy(id) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -parse_error::ParseError GAPID3D9::SetParamData( - ResourceId id, - unsigned int size, - const void *data) { - EffectParamD3D9 *param = effect_params_.Get(id); - if (!param) return parse_error::kParseInvalidArguments; - return param->SetData(this, size, data) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -parse_error::ParseError GAPID3D9::GetParamDesc( - ResourceId id, - unsigned int size, - void *data) { - EffectParamD3D9 *param = effect_params_.Get(id); - if (!param) return parse_error::kParseInvalidArguments; - return param->GetDesc(size, data) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -// Gets the stream count from the effect and stores it in the memory buffer. -parse_error::ParseError GAPID3D9::GetStreamCount( - ResourceId id, - unsigned int size, - void *data) { - EffectD3D9 *effect = effects_.Get(id); - if (!effect || size < sizeof(Uint32)) // NOLINT - return parse_error::kParseInvalidArguments; - *static_cast(data) = effect->GetStreamCount(); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPID3D9::GetStreamDesc( - ResourceId id, - unsigned int index, - unsigned int size, - void *data) { - EffectD3D9 *effect = effects_.Get(id); - if (!effect) return parse_error::kParseInvalidArguments; - return effect->GetStreamDesc(index, size, data) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - - -// If the current effect is valid, call End on it, and tag for revalidation. -void GAPID3D9::DirtyEffect() { - if (validate_effect_) return; - DCHECK(current_effect_); - current_effect_->End(); - current_effect_ = NULL; - validate_effect_ = true; -} - -// Gets the current effect, and calls Begin on it (if successful). -// Should only be called if the current effect is not valid. -bool GAPID3D9::ValidateEffect() { - DCHECK(validate_effect_); - DCHECK(!current_effect_); - current_effect_ = effects_.Get(current_effect_id_); - if (!current_effect_) return false; - validate_effect_ = false; - return current_effect_->Begin(); -} - -} // namespace o3d -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/service/effect_d3d9.h b/o3d/gpu/command_buffer/service/effect_d3d9.h deleted file mode 100644 index db2df41..0000000 --- a/o3d/gpu/command_buffer/service/effect_d3d9.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the definition of the D3D9 versions of effect-related -// resource classes. - -#ifndef GPU_COMMAND_BUFFER_SERVICE_EFFECT_D3D9_H_ -#define GPU_COMMAND_BUFFER_SERVICE_EFFECT_D3D9_H_ - -#include -#include "gpu/command_buffer/common/gapi_interface.h" -#include "gpu/command_buffer/service/d3d9_utils.h" -#include "gpu/command_buffer/service/resource.h" - -namespace command_buffer { -namespace o3d { - -class GAPID3D9; -class EffectD3D9; - -// ps_2_0 limit -static const unsigned int kMaxSamplerUnits = 16; - -// D3D version of EffectParam. This class keeps a reference to the D3D effect. -class EffectParamD3D9: public EffectParam { - public: - EffectParamD3D9(effect_param::DataType data_type, - EffectD3D9 *effect, - D3DXHANDLE handle); - virtual ~EffectParamD3D9(); - - // Sets the data into the D3D effect parameter. - bool SetData(GAPID3D9 *gapi, unsigned int size, const void * data); - - // Gets the description of the parameter. - bool GetDesc(unsigned int size, void *data); - - // Resets the effect back-pointer. This is called when the effect gets - // destroyed, to invalidate the parameter. - void ResetEffect() { effect_ = NULL; } - - static EffectParamD3D9 *Create(EffectD3D9 *effect, D3DXHANDLE handle); - private: - EffectD3D9 *effect_; - D3DXHANDLE handle_; - unsigned int sampler_unit_count_; - scoped_array sampler_units_; -}; - -// D3D9 version of Effect. -class EffectD3D9 : public Effect { - public: - EffectD3D9(GAPID3D9 *gapi, - ID3DXEffect *d3d_effect, - ID3DXConstantTable *fs_constant_table, - IDirect3DVertexShader9 *d3d_vertex_shader); - virtual ~EffectD3D9(); - // Compiles and creates an effect from source code. - static EffectD3D9 *Create(GAPID3D9 *gapi, - const String &effect_code, - const String &vertex_program_entry, - const String &fragment_program_entry); - // Applies the effect states (vertex shader, pixel shader) to D3D. - bool Begin(); - // Resets the effect states (vertex shader, pixel shader) to D3D. - void End(); - // Commits parameters to D3D, if they were modified while the effect is - // active. - bool CommitParameters(); - - // Gets the number of parameters in the effect. - unsigned int GetParamCount(); - // Creates an effect parameter with the specified index. - EffectParamD3D9 *CreateParam(unsigned int index); - // Creates an effect parameter of the specified name. - EffectParamD3D9 *CreateParamByName(const char *name); - // Gets the number of stream inputs for the effect. - unsigned int GetStreamCount(); - // Gets the stream data with the specified index. - bool GetStreamDesc(unsigned int index, unsigned int size, void *data); - private: - typedef std::vector ParamList; - typedef std::vector StreamList; - - // Links a param into this effect. - void LinkParam(EffectParamD3D9 *param); - // Unlinks a param into this effect. - void UnlinkParam(EffectParamD3D9 *param); - // Sets sampler states. - bool SetSamplers(); - // Sets streams vector. - bool SetStreams(); - - GAPID3D9* gapi_; - ID3DXEffect *d3d_effect_; - IDirect3DVertexShader9 *d3d_vertex_shader_; - ID3DXConstantTable *fs_constant_table_; - ParamList params_; - StreamList streams_; - bool sync_parameters_; - ResourceId samplers_[kMaxSamplerUnits]; - - friend class EffectParamD3D9; - DISALLOW_COPY_AND_ASSIGN(EffectD3D9); -}; - -} // namespace o3d -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_SERVICE_EFFECT_D3D9_H_ diff --git a/o3d/gpu/command_buffer/service/effect_gl.cc b/o3d/gpu/command_buffer/service/effect_gl.cc deleted file mode 100644 index b8f9601..0000000 --- a/o3d/gpu/command_buffer/service/effect_gl.cc +++ /dev/null @@ -1,852 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the implementation of the EffectParamGL and EffectGL -// classes, as well as the effect-related GAPI functions on GL. - -#include "gpu/command_buffer/service/precompile.h" - -#include - -#include "base/cross/std_functional.h" -#include "gpu/command_buffer/service/effect_gl.h" -#include "gpu/command_buffer/service/gapi_gl.h" -#include "gpu/command_buffer/service/effect_utils.h" - -namespace command_buffer { -namespace o3d { - -EffectParamGL::EffectParamGL(effect_param::DataType data_type, - EffectGL *effect, - unsigned int param_index) - : EffectParam(data_type), - effect_(effect), - low_level_param_index_(param_index) { - DCHECK(effect_); - effect_->LinkParam(this); -} - -EffectParamGL::~EffectParamGL() { - if (effect_) - effect_->UnlinkParam(this); -} - -static effect_param::DataType CgTypeToCBType(CGtype cg_type) { - switch (cg_type) { - case CG_FLOAT: - case CG_FLOAT1: - return effect_param::kFloat1; - case CG_FLOAT2: - return effect_param::kFloat2; - case CG_FLOAT3: - return effect_param::kFloat3; - case CG_FLOAT4: - return effect_param::kFloat4; - case CG_INT: - case CG_INT1: - return effect_param::kInt; - case CG_BOOL: - case CG_BOOL1: - return effect_param::kBool; - case CG_FLOAT4x4: - return effect_param::kMatrix4; - case CG_SAMPLER: - case CG_SAMPLER1D: - case CG_SAMPLER2D: - case CG_SAMPLER3D: - case CG_SAMPLERCUBE: - return effect_param::kSampler; - case CG_TEXTURE: - return effect_param::kTexture; - default : { - DLOG(INFO) << "Cannot convert CGtype " - << cgGetTypeString(cg_type) - << " to a Param type."; - return effect_param::kUnknown; - } - } -} - -EffectParamGL *EffectParamGL::Create(EffectGL *effect, - unsigned int index) { - DCHECK(effect); - const EffectGL::LowLevelParam &low_level_param = - effect->low_level_params_[index]; - CGparameter cg_param = EffectGL::GetEitherCgParameter(low_level_param); - CGtype cg_type = cgGetParameterType(cg_param); - if (cg_type == CG_ARRAY) { - cg_type = cgGetParameterType(cgGetArrayParameter(cg_param, 0)); - } - effect_param::DataType type = CgTypeToCBType(cg_type); - - if (type == effect_param::kUnknown) - return NULL; - return new EffectParamGL(type, effect, index); -} - -// Fills the Desc structure, appending name and semantic if any, and if enough -// room is available in the buffer. -bool EffectParamGL::GetDesc(unsigned int size, void *data) { - using effect_param::Desc; - if (size < sizeof(Desc)) // NOLINT - return false; - if (!effect_) - return false; - const EffectGL::LowLevelParam &low_level_param = - effect_->low_level_params_[low_level_param_index_]; - CGparameter cg_param = EffectGL::GetEitherCgParameter(low_level_param); - const char *name = low_level_param.name; - const char* semantic = cgGetParameterSemantic(cg_param); - int num_elements = cgGetArraySize(cg_param, 0); - unsigned int name_size = - name ? static_cast(strlen(name)) + 1 : 0; - unsigned int semantic_size = semantic ? - static_cast(strlen(semantic)) + 1 : 0; - unsigned int total_size = sizeof(Desc) + name_size + semantic_size; // NOLINT - - Desc *desc = static_cast(data); - memset(desc, 0, sizeof(*desc)); - desc->size = total_size; - desc->data_type = data_type(); - desc->data_size = GetDataSize(data_type()); - desc->name_offset = 0; - desc->name_size = name_size; - desc->semantic_offset = 0; - desc->num_elements = num_elements; - desc->semantic_size = semantic_size; - unsigned int current_offset = sizeof(Desc); - if (name && current_offset + name_size <= size) { - desc->name_offset = current_offset; - memcpy(static_cast(data) + current_offset, name, name_size); - current_offset += name_size; - } - if (semantic && current_offset + semantic_size <= size) { - desc->semantic_offset = current_offset; - memcpy(static_cast(data) + current_offset, semantic, semantic_size); - current_offset += semantic_size; - } - return true; -} - -// Sets the data into the Cg effect parameter, using the appropriate Cg call. -bool EffectParamGL::SetData(GAPIGL *gapi, - unsigned int size, - const void * data) { - if (!effect_) - return false; - - EffectGL::LowLevelParam &low_level_param = - effect_->low_level_params_[low_level_param_index_]; - - if (low_level_param.num_elements != 0) { - DLOG(ERROR) << "Attempt to set array parameter to value."; - return false; - } - - CGparameter vp_param = low_level_param.vp_param; - CGparameter fp_param = low_level_param.fp_param; - effect_param::DataType type = data_type(); - if (size < effect_param::GetDataSize(type)) - return false; - - switch (type) { - case effect_param::kFloat1: - if (vp_param) - cgSetParameter1f(vp_param, *static_cast(data)); - if (fp_param) - cgSetParameter1f(fp_param, *static_cast(data)); - break; - case effect_param::kFloat2: - if (vp_param) - cgSetParameter2fv(vp_param, static_cast(data)); - if (fp_param) - cgSetParameter2fv(fp_param, static_cast(data)); - break; - case effect_param::kFloat3: - if (vp_param) - cgSetParameter3fv(vp_param, static_cast(data)); - if (fp_param) - cgSetParameter3fv(fp_param, static_cast(data)); - break; - case effect_param::kFloat4: - if (vp_param) - cgSetParameter4fv(vp_param, static_cast(data)); - if (fp_param) - cgSetParameter4fv(fp_param, static_cast(data)); - break; - case effect_param::kMatrix4: - if (vp_param) - cgSetMatrixParameterfr(vp_param, static_cast(data)); - if (fp_param) - cgSetMatrixParameterfr(fp_param, static_cast(data)); - break; - case effect_param::kInt: - if (vp_param) cgSetParameter1i(vp_param, *static_cast(data)); - if (fp_param) cgSetParameter1i(fp_param, *static_cast(data)); - break; - case effect_param::kBool: { - int bool_value = *static_cast(data)?1:0; - if (vp_param) cgSetParameter1i(vp_param, bool_value); - if (fp_param) cgSetParameter1i(fp_param, bool_value); - break; - } - case effect_param::kSampler: { - DCHECK_GE(low_level_param.sampler_ids.size(), 1U); - low_level_param.sampler_ids[0] = *static_cast(data); - if (effect_ == gapi->current_effect()) { - gapi->DirtyEffect(); - } - break; - } - default: - DLOG(ERROR) << "Invalid parameter type."; - return false; - } - return true; -} -EffectGL::EffectGL(CGprogram vertex_program, - CGprogram fragment_program) - : vertex_program_(vertex_program), - fragment_program_(fragment_program), - update_samplers_(true) { -} - -EffectGL::~EffectGL() { - for (ParamList::iterator it = params_.begin(); - it != params_.end(); ++it) { - (*it)->ResetEffect(); - } -} - -void EffectGL::LinkParam(EffectParamGL *param) { - params_.push_back(param); -} - -void EffectGL::UnlinkParam(EffectParamGL *param) { - std::remove(params_.begin(), params_.end(), param); -} - -// Rewrites vertex program assembly code to match GL semantics for clipping. -// This parses the source, breaking it down into pieces: -// - declaration ("!!ARBvp1.0") -// - comments (that contain the parameter information) -// - instructions -// - "END" token. -// Then it rewrites the instructions so that 'result.position' doesn't get -// written directly, instead it is written to a temporary variable. Then a -// transformation is done on that variable before outputing to -// 'result.position': -// - offset x an y by half a pixel (times w). -// - remap z from [0..w] to [-w..w]. -// -// Note that for the 1/2 pixel offset, we need a parameter that depends on the -// current viewport. This is done through 'program.env[0]' which is shared -// across all programs (so we only have to update it once when we change the -// viewport), because Cg won't use them currently (it uses 'program.local' -// instead). -static bool RewriteVertexProgramSource(String *source) { - String::size_type pos = source->find('\n'); - if (pos == String::npos) { - DLOG(ERROR) << "could not find program declaration"; - return false; - } - String decl(*source, 0, pos + 1); - String::size_type start_comments = pos + 1; - // skip the comments that contain the parameters etc. - for (; pos < source->size(); pos = source->find('\n', pos)) { - ++pos; - if (pos >= source->size()) - break; - if ((*source)[pos] != '#') - break; - } - if (pos >= source->size()) { - // we only found comments. - return false; - } - String comments(*source, start_comments, pos - start_comments); - - String::size_type end_token = source->find("\nEND", pos + 1); - if (end_token == String::npos) { - DLOG(ERROR) << "Compiled shader doesn't have an END token"; - return false; - } - String instructions(*source, pos, end_token + 1 - pos); - - // Replace accesses to 'result.position' by accesses to our temp variable - // '$O3D_HPOS'. - // '$' is a valid symbol for identifiers, but Cg doesn't seem to be using - // it, so we can use it to ensure we don't have name conflicts. - static const char kOutPositionRegister[] = "result.position"; - for (String::size_type i = instructions.find(kOutPositionRegister); - i < String::npos; i = instructions.find(kOutPositionRegister, i)) { - instructions.replace(i, strlen(kOutPositionRegister), "$O3D_HPOS"); - } - - *source = decl + - comments + - // .x = 1/viewport.width; .y = 1/viewport.height; .z = 2.0; - "PARAM $O3D_HELPER = program.env[0];\n" - "TEMP $O3D_HPOS;\n" + - instructions + - // hpos.x <- hpos.x + hpos.w / viewport.width; - // hpos.y <- hpos.y - hpos.w / viewport.height; - "MAD $O3D_HPOS.xy, $O3D_HELPER.xyyy, $O3D_HPOS.w, $O3D_HPOS.xyyy;\n" - // hpos.z <- hpos.z * 2 - hpos.w - "MAD $O3D_HPOS.z, $O3D_HPOS.z, $O3D_HELPER.z, -$O3D_HPOS.w;\n" - "MOV result.position, $O3D_HPOS;\n" - "END\n"; - return true; -} - -EffectGL *EffectGL::Create(GAPIGL *gapi, - const String& effect_code, - const String& vertex_program_entry, - const String& fragment_program_entry) { - CGcontext context = gapi->cg_context(); - // Compile the original vertex program once, to get the ARBVP1 assembly code. - CGprogram original_vp = cgCreateProgram( - context, CG_SOURCE, effect_code.c_str(), CG_PROFILE_ARBVP1, - vertex_program_entry.c_str(), NULL); - const char* listing = cgGetLastListing(context); - if (original_vp == NULL) { - DLOG(ERROR) << "Effect Compile Error: " << cgGetErrorString(cgGetError()) - << " : " << listing; - return NULL; - } - - if (listing && listing[0] != 0) { - DLOG(WARNING) << "Effect Compile Warnings: " << listing; - } - - String vp_assembly = cgGetProgramString(original_vp, CG_COMPILED_PROGRAM); - cgDestroyProgram(original_vp); - if (!RewriteVertexProgramSource(&vp_assembly)) { - return NULL; - } - CGprogram vertex_program = cgCreateProgram( - context, CG_OBJECT, vp_assembly.c_str(), CG_PROFILE_ARBVP1, - vertex_program_entry.c_str(), NULL); - listing = cgGetLastListing(context); - if (vertex_program == NULL) { - DLOG(ERROR) << "Effect post-rewrite Compile Error: " - << cgGetErrorString(cgGetError()) << " : " << listing; - return false; - } - - if (listing && listing[0] != 0) { - DLOG(WARNING) << "Effect post-rewrite compile warnings: " << listing; - } - - CHECK_GL_ERROR(); - - // If the program rewrite introduced some syntax or semantic errors, we won't - // know it until we load the program (through a GL error). - // So flush all GL errors first... - do {} while (glGetError() != GL_NO_ERROR); - - // ... Then load the program ... - cgGLLoadProgram(vertex_program); - - // ... And check for GL errors. - if (glGetError() != GL_NO_ERROR) { - DLOG(ERROR) << "Effect post-rewrite GL Error: " - << glGetString(GL_PROGRAM_ERROR_STRING_ARB) - << "\nSource: \n" - << vp_assembly; - return NULL; - } - - CGprogram fragment_program = cgCreateProgram( - context, CG_SOURCE, effect_code.c_str(), CG_PROFILE_ARBFP1, - fragment_program_entry.c_str(), NULL); - listing = cgGetLastListing(context); - if (fragment_program == NULL) { - DLOG(ERROR) << "Effect Compile Error: " - << cgGetErrorString(cgGetError()) << " : " - << listing; - return NULL; - } - - if (listing && listing[0] != 0) { - DLOG(WARNING) << "Effect Compile Warnings: " << listing; - } - - cgGLLoadProgram(fragment_program); - - // Also check for GL errors, in case Cg managed to compile, but generated a - // bad program. - if (glGetError() != GL_NO_ERROR) { - DLOG(ERROR) << "Effect GL Error: " - << glGetString(GL_PROGRAM_ERROR_STRING_ARB); - return false; - } - EffectGL *effect = new EffectGL(vertex_program, fragment_program); - effect->Initialize(); - return effect; -} - -int EffectGL::GetLowLevelParamIndexByName(const char *name) { - DCHECK(name); - for (unsigned int index = 0; index < low_level_params_.size(); ++index) { - if (!strcmp(name, low_level_params_[index].name)) { - return index; - } - } - return -1; -} - -void EffectGL::AddLowLevelParams(CGprogram prog, CGenum name_space, bool vp) { - // Iterate through parameters and add them to the vector of low level - // parameters, visiting only CGparameters that have had storage allocated to - // them, and add the params to the low_level_params_ vector. - for (CGparameter cg_param = cgGetFirstParameter(prog, name_space); - cg_param != NULL; - cg_param = cgGetNextParameter(cg_param)) { - CGenum variability = cgGetParameterVariability(cg_param); - if (variability != CG_UNIFORM) - continue; - CGenum direction = cgGetParameterDirection(cg_param); - if (direction != CG_IN) - continue; - const char *name = cgGetParameterName(cg_param); - if (!name) - continue; - - CGtype cg_type = cgGetParameterType(cg_param); - - int num_elements; - if (cg_type == CG_ARRAY) { - num_elements = cgGetArraySize(cg_param, 0); - // Substitute the first element's type for our type. - cg_type = cgGetParameterType(cgGetArrayParameter(cg_param, 0)); - } else { - num_elements = 0; - } - - int index = GetLowLevelParamIndexByName(name); - if (index < 0) { - LowLevelParam param; - param.name = name; - param.vp_param = NULL; - param.fp_param = NULL; - param.num_elements = num_elements; - - index = low_level_params_.size(); - if (cg_type == CG_SAMPLER || - cg_type == CG_SAMPLER1D || - cg_type == CG_SAMPLER2D || - cg_type == CG_SAMPLER3D || - cg_type == CG_SAMPLERCUBE) { - sampler_params_.push_back(index); - if (num_elements == 0) { - param.sampler_ids.push_back(kInvalidResource); - } else { - param.sampler_ids.resize(num_elements); - std::vector::iterator iter; - for (iter = param.sampler_ids.begin(); - iter != param.sampler_ids.end(); - ++iter) { - *iter = kInvalidResource; - } - } - } - low_level_params_.push_back(param); - } - - if (vp) { - low_level_params_[index].vp_param = cg_param; - } else { - low_level_params_[index].fp_param = cg_param; - } - } -} - -typedef std::pair SemanticMapElement; -typedef std::map SemanticMap; - -// The map batween the semantics on vertex program varying parameters names -// and vertex attribute indices under the VP_30 profile. -// TODO(gman): remove this. -SemanticMapElement semantic_map_array[] = { - SemanticMapElement("POSITION", - effect_stream::Desc(vertex_struct::kPosition, 0)), - SemanticMapElement("ATTR0", - effect_stream::Desc(vertex_struct::kPosition, 0)), - SemanticMapElement("BLENDWEIGHT", - effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)), - SemanticMapElement("ATTR1", - effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)), - SemanticMapElement("NORMAL", - effect_stream::Desc(vertex_struct::kNormal, 0)), - SemanticMapElement("ATTR2", - effect_stream::Desc(vertex_struct::kNormal, 0)), - SemanticMapElement("COLOR0", - effect_stream::Desc(vertex_struct::kColor, 0)), - SemanticMapElement("DIFFUSE", - effect_stream::Desc(vertex_struct::kColor, 0)), - SemanticMapElement("ATTR3", - effect_stream::Desc(vertex_struct::kColor, 0)), - SemanticMapElement("COLOR1", - effect_stream::Desc(vertex_struct::kColor, 1)), - SemanticMapElement("SPECULAR", - effect_stream::Desc(vertex_struct::kColor, 1)), - SemanticMapElement("ATTR4", - effect_stream::Desc(vertex_struct::kColor, 1)), - SemanticMapElement("TESSFACTOR", - effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)), - SemanticMapElement("FOGCOORD", - effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)), - SemanticMapElement("ATTR5", - effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)), - SemanticMapElement("PSIZE", - effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)), - SemanticMapElement("ATTR6", - effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)), - SemanticMapElement("BLENDINDICES", - effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)), - SemanticMapElement("ATTR7", - effect_stream::Desc(vertex_struct::kUnknownSemantic, 0)), - SemanticMapElement("TEXCOORD0", - effect_stream::Desc(vertex_struct::kTexCoord, 0)), - SemanticMapElement("ATTR8", - effect_stream::Desc(vertex_struct::kTexCoord, 0)), - SemanticMapElement("TEXCOORD1", - effect_stream::Desc(vertex_struct::kTexCoord, 1)), - SemanticMapElement("ATTR9", - effect_stream::Desc(vertex_struct::kTexCoord, 1)), - SemanticMapElement("TEXCOORD2", - effect_stream::Desc(vertex_struct::kTexCoord, 2)), - SemanticMapElement("ATTR10", - effect_stream::Desc(vertex_struct::kTexCoord, 2)), - SemanticMapElement("TEXCOORD3", - effect_stream::Desc(vertex_struct::kTexCoord, 3)), - SemanticMapElement("ATTR11", - effect_stream::Desc(vertex_struct::kTexCoord, 3)), - SemanticMapElement("TEXCOORD4", - effect_stream::Desc(vertex_struct::kTexCoord, 4)), - SemanticMapElement("ATTR12", - effect_stream::Desc(vertex_struct::kTexCoord, 4)), - SemanticMapElement("TEXCOORD5", - effect_stream::Desc(vertex_struct::kTexCoord, 5)), - SemanticMapElement("ATTR13", - effect_stream::Desc(vertex_struct::kTexCoord, 5)), - SemanticMapElement("TEXCOORD6", - effect_stream::Desc(vertex_struct::kTexCoord, 6)), - SemanticMapElement("TANGENT", - effect_stream::Desc(vertex_struct::kTexCoord, 6)), - SemanticMapElement("ATTR14", - effect_stream::Desc(vertex_struct::kTexCoord, 7)), - SemanticMapElement("TEXCOORD7", - effect_stream::Desc(vertex_struct::kTexCoord, 7)), - SemanticMapElement("BINORMAL", - effect_stream::Desc(vertex_struct::kTexCoord, 8)), - SemanticMapElement("ATTR15", - effect_stream::Desc(vertex_struct::kTexCoord, 8)) -}; - -static SemanticMap semantic_map(semantic_map_array, - semantic_map_array + - arraysize(semantic_map_array)); - -void EffectGL::Initialize() { - AddLowLevelParams(vertex_program_, CG_PROGRAM, true); - AddLowLevelParams(vertex_program_, CG_GLOBAL, true); - AddLowLevelParams(fragment_program_, CG_PROGRAM, false); - AddLowLevelParams(fragment_program_, CG_GLOBAL, false); - - AddStreams(vertex_program_, CG_PROGRAM); - AddStreams(vertex_program_, CG_GLOBAL); -} - -// Loop over all leaf parameters, and find the ones that are bound to a -// semantic. -void EffectGL::AddStreams(CGprogram prog, CGenum name_space) { - for (CGparameter cg_param = cgGetFirstLeafParameter(prog, name_space); - cg_param != NULL; - cg_param = cgGetNextLeafParameter(cg_param)) { - CGenum variability = cgGetParameterVariability(cg_param); - if (variability != CG_VARYING) - continue; - CGenum direction = cgGetParameterDirection(cg_param); - if (direction != CG_IN) - continue; - const char* cg_semantic = cgGetParameterSemantic(cg_param); - if (cg_semantic == NULL) - continue; - - SemanticMap::iterator iter = semantic_map.find(String(cg_semantic)); - if (iter == semantic_map.end()) { - streams_.push_back(effect_stream::Desc( - vertex_struct::kUnknownSemantic, 0)); - } else { - streams_.push_back(iter->second); - } - } -} - -// Begins rendering with the effect, setting all the appropriate states. -bool EffectGL::Begin(GAPIGL *gapi) { - cgGLBindProgram(vertex_program_); - cgGLBindProgram(fragment_program_); - - // sampler->ApplyStates will mess with the texture binding on unit 0, so we - // do 2 passes. - // First to set the sampler states on the texture - for (unsigned int i = 0; i < sampler_params_.size(); ++i) { - unsigned int param_index = sampler_params_[i]; - std::vector &ids = low_level_params_[param_index].sampler_ids; - for (std::vector::iterator iter = ids.begin(); - iter != ids.end(); - ++iter) { - ResourceId id = *iter; - if (id != kInvalidResource) { - SamplerGL *sampler = gapi->GetSampler(id); - if (!sampler->ApplyStates(gapi)) { - return false; - } - } - } - } - // Second to enable/disable the sampler params. - for (unsigned int i = 0; i < sampler_params_.size(); ++i) { - unsigned int param_index = sampler_params_[i]; - const LowLevelParam &ll_param = low_level_params_[param_index]; - std::vector &ids = low_level_params_[param_index].sampler_ids; - // TODO(petersont): Rewrite the following so it handles arrays of samplers - // instead of simply bailing. - if (cgGetParameterType(ll_param.fp_param) == CG_ARRAY) - return false; - for (std::vector::iterator iter = ids.begin(); - iter != ids.end(); - ++iter) { - ResourceId id = *iter; - if (id != kInvalidResource) { - SamplerGL *sampler = gapi->GetSampler(id); - GLuint gl_texture = sampler->gl_texture(); - cgGLSetTextureParameter(ll_param.fp_param, gl_texture); - cgGLEnableTextureParameter(ll_param.fp_param); - } else { - cgGLSetTextureParameter(ll_param.fp_param, 0); - cgGLDisableTextureParameter(ll_param.fp_param); - } - } - } - return true; -} - -// Terminates rendering with the effect, resetting all the appropriate states. -void EffectGL::End(GAPIGL *gapi) { -} - -// Gets the parameter count from the list. -unsigned int EffectGL::GetParamCount() const { - return low_level_params_.size(); -} - -// Gets the number of input streams from the shader. -unsigned int EffectGL::GetStreamCount() const { - return streams_.size(); -} - -// Gets a handle to the selected parameter, and wraps it into an -// EffectParamGL if successful. -EffectParamGL *EffectGL::CreateParam(unsigned int index) { - if (index >= GetParamCount()) - return NULL; - return EffectParamGL::Create(this, index); -} - -// Provided enough room is available in the buffer, fills the Desc structure, -// appending name and semantic if any. -bool EffectGL::GetStreamDesc(unsigned int index, - unsigned int size, - void *data) { - using effect_stream::Desc; - if (size < sizeof(Desc) || index >= streams_.size()) // NOLINT - return false; - - Desc *desc = static_cast(data); - *desc = streams_[index]; - return true; -} - -// Gets a handle to the selected parameter, and wraps it into an -// EffectParamGL if successful. -EffectParamGL *EffectGL::CreateParamByName(const char *name) { - int index = GetLowLevelParamIndexByName(name); - if (index < 0) return NULL; - return EffectParamGL::Create(this, index); -} - -parse_error::ParseError GAPIGL::CreateEffect(ResourceId id, - unsigned int size, - const void *data) { - if (id == current_effect_id_) DirtyEffect(); - // Even though Assign would Destroy the effect at id, we do it explicitly in - // case the creation fails. - effects_.Destroy(id); - // Data is vp_main \0 fp_main \0 effect_text. - String vertex_program_entry; - String fragment_program_entry; - String effect_code; - if (!ParseEffectData(size, data, - &vertex_program_entry, - &fragment_program_entry, - &effect_code)) { - return parse_error::kParseInvalidArguments; - } - EffectGL * effect = EffectGL::Create(this, effect_code, - vertex_program_entry, - fragment_program_entry); - if (!effect) return parse_error::kParseInvalidArguments; - effects_.Assign(id, effect); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIGL::DestroyEffect(ResourceId id) { - if (id == current_effect_id_) DirtyEffect(); - return effects_.Destroy(id) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -parse_error::ParseError GAPIGL::SetEffect(ResourceId id) { - DirtyEffect(); - current_effect_id_ = id; - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIGL::GetParamCount(ResourceId id, - unsigned int size, - void *data) { - EffectGL *effect = effects_.Get(id); - if (!effect || size < sizeof(Uint32)) // NOLINT - return parse_error::kParseInvalidArguments; - *static_cast(data) = effect->GetParamCount(); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIGL::CreateParam(ResourceId param_id, - ResourceId effect_id, - unsigned int index) { - EffectGL *effect = effects_.Get(effect_id); - if (!effect) return parse_error::kParseInvalidArguments; - EffectParamGL *param = effect->CreateParam(index); - if (!param) return parse_error::kParseInvalidArguments; - effect_params_.Assign(param_id, param); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIGL::CreateParamByName(ResourceId param_id, - ResourceId effect_id, - unsigned int size, - const void *name) { - EffectGL *effect = effects_.Get(effect_id); - if (!effect) return parse_error::kParseInvalidArguments; - std::string string_name(static_cast(name), size); - EffectParamGL *param = effect->CreateParamByName(string_name.c_str()); - if (!param) return parse_error::kParseInvalidArguments; - effect_params_.Assign(param_id, param); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIGL::DestroyParam(ResourceId id) { - return effect_params_.Destroy(id) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -parse_error::ParseError GAPIGL::SetParamData(ResourceId id, - unsigned int size, - const void *data) { - EffectParamGL *param = effect_params_.Get(id); - if (!param) return parse_error::kParseInvalidArguments; - return param->SetData(this, size, data) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -parse_error::ParseError GAPIGL::GetParamDesc(ResourceId id, - unsigned int size, - void *data) { - EffectParamGL *param = effect_params_.Get(id); - if (!param) return parse_error::kParseInvalidArguments; - return param->GetDesc(size, data) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -parse_error::ParseError GAPIGL::GetStreamCount( - ResourceId id, - unsigned int size, - void *data) { - EffectGL *effect = effects_.Get(id); - if (!effect || size < sizeof(Uint32)) // NOLINT - return parse_error::kParseInvalidArguments; - *static_cast(data) = effect->GetStreamCount(); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIGL::GetStreamDesc(ResourceId id, - unsigned int index, - unsigned int size, - void *data) { - EffectGL *effect = effects_.Get(id); - if (!effect) return parse_error::kParseInvalidArguments; - return effect->GetStreamDesc(index, size, data) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -// If the current effect is valid, call End on it, and tag for revalidation. -void GAPIGL::DirtyEffect() { - if (validate_effect_) return; - DCHECK(current_effect_); - current_effect_->End(this); - current_effect_ = NULL; - validate_effect_ = true; -} - -// Gets the current effect, and calls Begin on it (if successful). -// Should only be called if the current effect is not valid. -bool GAPIGL::ValidateEffect() { - DCHECK(validate_effect_); - DCHECK(!current_effect_); - current_effect_ = effects_.Get(current_effect_id_); - if (!current_effect_) return false; - validate_effect_ = false; - return current_effect_->Begin(this); -} - -} // namespace o3d -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/service/effect_gl.h b/o3d/gpu/command_buffer/service/effect_gl.h deleted file mode 100644 index b38cc92..0000000 --- a/o3d/gpu/command_buffer/service/effect_gl.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the declaration of the EffectParamGL and EffectGL classes. - -#ifndef GPU_COMMAND_BUFFER_SERVICE_EFFECT_GL_H_ -#define GPU_COMMAND_BUFFER_SERVICE_EFFECT_GL_H_ - -#include - -#include "gpu/command_buffer/common/gapi_interface.h" -#include "gpu/command_buffer/service/resource.h" -#include "gpu/command_buffer/service/gl_utils.h" - -namespace command_buffer { -namespace o3d { - -class GAPIGL; -class EffectGL; - -// GL version of EffectParam. -class EffectParamGL: public EffectParam { - public: - EffectParamGL(effect_param::DataType data_type, - EffectGL *effect, - unsigned int param_index); - virtual ~EffectParamGL(); - - // Sets the data into the GL effect parameter. - bool SetData(GAPIGL *gapi, unsigned int size, const void * data); - - // Gets the description of the parameter. - bool GetDesc(unsigned int size, void *data); - - // Resets the effect back-pointer. This is called when the effect gets - // destroyed, to invalidate the parameter. - void ResetEffect() { effect_ = NULL; } - - // Creates an EffectParamGL from the EffectGL, by index. - static EffectParamGL *Create(EffectGL *effect, - unsigned int index); - private: - EffectGL *effect_; - unsigned int low_level_param_index_; - DISALLOW_COPY_AND_ASSIGN(EffectParamGL); -}; - -// GL version of Effect. -class EffectGL : public Effect { - public: - EffectGL(CGprogram vertex_program, - CGprogram fragment_program); - virtual ~EffectGL(); - - // Compiles and creates an effect from source code. - static EffectGL *Create(GAPIGL *gapi, - const String &effect_code, - const String &vertex_program_entry, - const String &fragment_program_entry); - - // Applies the effect states (vertex shader, pixel shader) to GL. - bool Begin(GAPIGL *gapi); - - // Resets the effect states (vertex shader, pixel shader) to GL. - void End(GAPIGL *gapi); - - // Gets the number of parameters in the effect. - unsigned int GetParamCount() const; - - // Gets the number of streams in the effect. - unsigned int GetStreamCount() const; - - // Creates an effect parameter with the specified index. - EffectParamGL *CreateParam(unsigned int index); - - // Gets the stream data with the specified index. - bool GetStreamDesc(unsigned int index, unsigned int size, void *data); - - // Creates an effect parameter of the specified name. - EffectParamGL *CreateParamByName(const char *name); - - private: - struct LowLevelParam { - const char *name; - CGparameter vp_param; - CGparameter fp_param; - int num_elements; - std::vector sampler_ids; - }; - typedef std::vector LowLevelParamList; - typedef std::vector ParamList; - typedef std::vector StreamList; - - static CGparameter GetEitherCgParameter( - const LowLevelParam &low_level_param) { - return low_level_param.vp_param ? - low_level_param.vp_param : low_level_param.fp_param; - } - - int GetLowLevelParamIndexByName(const char *name); - void AddLowLevelParams(CGprogram prog, CGenum name_space, bool vp); - void AddStreams(CGprogram prog, CGenum name_space); - - // Creates the low level structures. - void Initialize(); - - // Links a param into this effect. - void LinkParam(EffectParamGL *param); - - // Unlinks a param into this effect. - void UnlinkParam(EffectParamGL *param); - - CGprogram vertex_program_; - CGprogram fragment_program_; - // List of all the Params created. - ParamList params_; - StreamList streams_; - // List of all the Cg parameters present in either the vertex program or the - // fragment program. - LowLevelParamList low_level_params_; - - // List of the indices of the low level params that are samplers. - std::vector sampler_params_; - bool update_samplers_; - - friend class EffectParamGL; - DISALLOW_COPY_AND_ASSIGN(EffectGL); -}; - -} // namespace o3d -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_SERVICE_EFFECT_GL_H_ diff --git a/o3d/gpu/command_buffer/service/effect_utils.cc b/o3d/gpu/command_buffer/service/effect_utils.cc deleted file mode 100644 index 021b49f..0000000 --- a/o3d/gpu/command_buffer/service/effect_utils.cc +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file implements effect related utilities. - -#include "gpu/command_buffer/service/precompile.h" -#include "gpu/command_buffer/service/effect_utils.h" - -namespace command_buffer { - -bool ParseEffectData(unsigned int size, - const void *data, - String *vertex_program_entry, - String *fragment_program_entry, - String *effect_code) { - const char *data_char = static_cast(data); - unsigned int index = 0; - - for (; index < size && data_char[index]; ++index) { } - if (index >= size) return false; - *vertex_program_entry = String(data_char, index); - ++index; // skip \0 - unsigned int fragment_program_entry_begin = index; - - for (; index < size && data_char[index]; ++index) { } - if (index >= size) return false; - *fragment_program_entry = String(data_char + fragment_program_entry_begin, - index - fragment_program_entry_begin); - ++index; // skip \0 - unsigned int effect_code_begin = index; - - // text doesn't have to be 0-terminated, but look for one so that we don't - // construct a std::string with a '\0' in it. - for (; index < size && data_char[index]; ++index) { } - *effect_code = String(data_char + effect_code_begin, - index - effect_code_begin); - return true; -} - -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/service/effect_utils.h b/o3d/gpu/command_buffer/service/effect_utils.h deleted file mode 100644 index ae22fb9..0000000 --- a/o3d/gpu/command_buffer/service/effect_utils.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file declares some effect related utilities. - -#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_EFFECT_UTILS_H_ -#define GPU_COMMAND_BUFFER_SERVICE_CROSS_EFFECT_UTILS_H_ - -#include "gpu/command_buffer/common/types.h" - -namespace command_buffer { - -// This function parses the data passed to the CreateEffect commands, which -// follows the following format: -// vertex_program_entry \0 fragment_program_entry \0 effect_code -// It returns the various components. -bool ParseEffectData(unsigned int size, - const void *data, - String *vertex_program_entry, - String *fragment_program_entry, - String *effect_code); - -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_EFFECT_UTILS_H_ diff --git a/o3d/gpu/command_buffer/service/effect_utils_test.cc b/o3d/gpu/command_buffer/service/effect_utils_test.cc deleted file mode 100644 index 695291e..0000000 --- a/o3d/gpu/command_buffer/service/effect_utils_test.cc +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the unit tests for the effect utilities. - -#include "gpu/command_buffer/service/precompile.h" -#include "tests/common/win/testing_common.h" -#include "gpu/command_buffer/service/cross/effect_utils.h" - -namespace o3d { -namespace command_buffer { - -TEST(ParseEffectDataTest, ValidData) { - // Tests well-formed data. - const char kEffect[] = "vertex_entry\0fragment_entry\0effect code"; - String vertex_program_entry; - String fragment_program_entry; - String effect_code; - EXPECT_TRUE(ParseEffectData(sizeof(kEffect), kEffect, &vertex_program_entry, - &fragment_program_entry, &effect_code)); - EXPECT_EQ(vertex_program_entry, "vertex_entry"); - EXPECT_EQ(fragment_program_entry, "fragment_entry"); - EXPECT_EQ(effect_code, "effect code"); - - // The terminal \0 isn't needed, check that we parse correctly without it. - EXPECT_TRUE(ParseEffectData(sizeof(kEffect)-1, kEffect, - &vertex_program_entry, &fragment_program_entry, - &effect_code)); - EXPECT_EQ(vertex_program_entry, "vertex_entry"); - EXPECT_EQ(fragment_program_entry, "fragment_entry"); - EXPECT_EQ(effect_code, "effect code"); -} - -TEST(ParseEffectDataTest, InvalidData) { - const char kEffect[] = "vertex_entry\0fragment_entry\0effect code"; - String vertex_program_entry; - String fragment_program_entry; - String effect_code; - // 0-size - EXPECT_FALSE(ParseEffectData(0, kEffect, - &vertex_program_entry, &fragment_program_entry, - &effect_code)); - // Only vertex_entry, no \0 - EXPECT_FALSE(ParseEffectData(strlen("vertex_entry"), kEffect, - &vertex_program_entry, &fragment_program_entry, - &effect_code)); - // Only vertex_entry\0 - EXPECT_FALSE(ParseEffectData(strlen("vertex_entry") + 1, kEffect, - &vertex_program_entry, &fragment_program_entry, - &effect_code)); - // Only vertex_entry\0fragment_entry, no \0 - EXPECT_FALSE(ParseEffectData(strlen("vertex_entry.fragment_entry"), kEffect, - &vertex_program_entry, &fragment_program_entry, - &effect_code)); -} - -} // namespace command_buffer -} // namespace o3d diff --git a/o3d/gpu/command_buffer/service/gapi_d3d9.cc b/o3d/gpu/command_buffer/service/gapi_d3d9.cc deleted file mode 100644 index 8ca8cfd..0000000 --- a/o3d/gpu/command_buffer/service/gapi_d3d9.cc +++ /dev/null @@ -1,393 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the implementation of the GAPID3D9 class. - -#include "gpu/command_buffer/service/precompile.h" -#include "gpu/command_buffer/service/gapi_d3d9.h" - -namespace command_buffer { -namespace o3d { - -GAPID3D9::GAPID3D9() - : d3d_module_(NULL), - d3dx_module_(NULL), - d3d_(NULL), - d3d_device_(NULL), - hwnd_(NULL), - current_vertex_struct_(0), - validate_streams_(true), - max_vertices_(0), - current_effect_id_(0), - validate_effect_(true), - current_effect_(NULL), - vertex_buffers_(), - index_buffers_(), - vertex_structs_(), - back_buffer_surface_(NULL), - back_buffer_depth_surface_(NULL), - current_surface_id_(kInvalidResource), - current_depth_surface_id_(kInvalidResource), - direct3d_create9_(NULL), - get_shader_constant_table_(NULL), - create_effect_(NULL), - get_shader_input_semantics_(NULL) {} - -GAPID3D9::~GAPID3D9() {} - -// Initializes a D3D interface and device, and sets basic states. -bool GAPID3D9::Initialize() { - if (!FindDirect3DFunctions()) { - Destroy(); - return false; - } - - d3d_ = Direct3DCreate(D3D_SDK_VERSION); - if (NULL == d3d_) { - LOG(ERROR) << "Failed to create the initial D3D9 Interface"; - Destroy(); - return false; - } - d3d_device_ = NULL; - - D3DDISPLAYMODE d3ddm; - d3d_->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm); - // NOTE: make sure the backbuffer matches this format, as it is - // currently currently assumed to be 32-bit 8X8R8G8B - - D3DPRESENT_PARAMETERS d3dpp; - ZeroMemory(&d3dpp, sizeof(d3dpp)); - d3dpp.Windowed = TRUE; - d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; - d3dpp.BackBufferFormat = d3ddm.Format; - d3dpp.EnableAutoDepthStencil = TRUE; - d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; - d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; // wait for vsync - // Note: SwapEffect=DISCARD is req. for multisample to function - // Note: AutoDepthStencilFormat is 16-bit (not the usual 8-bit) - - // query multisampling - const int kNumTypesToCheck = 4; - D3DMULTISAMPLE_TYPE multisample_types[] = { D3DMULTISAMPLE_5_SAMPLES, - D3DMULTISAMPLE_4_SAMPLES, - D3DMULTISAMPLE_2_SAMPLES, - D3DMULTISAMPLE_NONE }; - DWORD multisample_quality = 0; - for (int i = 0; i < kNumTypesToCheck; ++i) { - // check back-buffer for multisampling at level "i"; - // back buffer = 32-bit XRGB (i.e. no alpha) - if (SUCCEEDED(d3d_->CheckDeviceMultiSampleType( - D3DADAPTER_DEFAULT, - D3DDEVTYPE_HAL, - D3DFMT_X8R8G8B8, - true, // result is windowed - multisample_types[i], - &multisample_quality))) { - // back buffer succeeded, now check depth-buffer - // depth buffer = 24-bit, stencil = 8-bit - // NOTE: 8-bit not 16-bit like the D3DPRESENT_PARAMETERS - if (SUCCEEDED(d3d_->CheckDeviceMultiSampleType( - D3DADAPTER_DEFAULT, - D3DDEVTYPE_HAL, - D3DFMT_D24S8, - true, // result is windowed - multisample_types[i], - &multisample_quality))) { - d3dpp.MultiSampleType = multisample_types[i]; - d3dpp.MultiSampleQuality = multisample_quality - 1; - break; - } - } - } - // D3DCREATE_FPU_PRESERVE is there because Firefox 3 relies on specific FPU - // flags for its UI rendering. Apparently Firefox 2 does not, though we don't - // currently propagate that info. - // TODO: check if FPU_PRESERVE has a significant perf hit, in which - // case find out if we can disable it for Firefox 2/other browsers, and/or if - // it makes sense to switch FPU flags before/after every DX call. - DWORD flags = D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE; - if (!SUCCEEDED(d3d_->CreateDevice(D3DADAPTER_DEFAULT, - D3DDEVTYPE_HAL, - hwnd_, - flags, - &d3dpp, - &d3d_device_))) { - LOG(ERROR) << "Failed to create the D3D Device"; - Destroy(); - return false; - } - // initialise the d3d graphics state. - HR(d3d_device_->SetRenderState(D3DRS_LIGHTING, FALSE)); - HR(d3d_device_->SetRenderState(D3DRS_ZENABLE, TRUE)); - HR(d3d_device_->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE)); - return true; -} - -// Deletes the D3D9 Device and releases the D3D interface. -void GAPID3D9::Destroy() { - vertex_buffers_.DestroyAllResources(); - index_buffers_.DestroyAllResources(); - vertex_structs_.DestroyAllResources(); - effects_.DestroyAllResources(); - effect_params_.DestroyAllResources(); - textures_.DestroyAllResources(); - samplers_.DestroyAllResources(); - render_surfaces_.DestroyAllResources(); - depth_surfaces_.DestroyAllResources(); - if (d3d_device_) { - d3d_device_->Release(); - d3d_device_ = NULL; - } - if (d3d_) { - d3d_->Release(); - d3d_ = NULL; - } - if (d3dx_module_) { - FreeLibrary(d3dx_module_); - d3dx_module_ = NULL; - get_shader_constant_table_ = NULL; - create_effect_ = NULL; - get_shader_input_semantics_ = NULL; - } - if (d3d_module_) { - FreeLibrary(d3d_module_); - d3d_module_ = NULL; - direct3d_create9_ = NULL; - } -} - -// Begins the frame. -void GAPID3D9::BeginFrame() { - HR(d3d_device_->GetRenderTarget(0, &back_buffer_surface_)); - HR(d3d_device_->GetDepthStencilSurface(&back_buffer_depth_surface_)); - HR(d3d_device_->BeginScene()); -} - -// Ends the frame, presenting the back buffer. -void GAPID3D9::EndFrame() { - DirtyEffect(); - HR(d3d_device_->EndScene()); - HR(d3d_device_->Present(NULL, NULL, NULL, NULL)); - - // Release the back-buffer references. - back_buffer_surface_ = NULL; - back_buffer_depth_surface_ = NULL; -} - -// Clears the selected buffers. -void GAPID3D9::Clear(unsigned int buffers, - const RGBA &color, - float depth, - unsigned int stencil) { - DWORD flags = (buffers & kColor ? D3DCLEAR_TARGET : 0) | - (buffers & kDepth ? D3DCLEAR_ZBUFFER : 0) | - (buffers & kStencil ? D3DCLEAR_STENCIL : 0); - HR(d3d_device_->Clear(0, - NULL, - flags, - D3DCOLOR_COLORVALUE(color.red, - color.green, - color.blue, - color.alpha), - depth, - stencil)); -} - -// Sets the viewport. -void GAPID3D9::SetViewport(unsigned int x, - unsigned int y, - unsigned int width, - unsigned int height, - float z_min, - float z_max) { - D3DVIEWPORT9 viewport = {x, y, width, height, z_min, z_max}; - HR(d3d_device_->SetViewport(&viewport)); -} - -// Converts an unsigned int RGBA color into an unsigned int ARGB (DirectX) -// color. -static unsigned int RGBAToARGB(unsigned int rgba) { - return (rgba >> 8) | (rgba << 24); -} - -// Sets the current VertexStruct. Just keep track of the ID. -parse_error::ParseError GAPID3D9::SetVertexStruct(ResourceId id) { - current_vertex_struct_ = id; - validate_streams_ = true; - return parse_error::kParseNoError; -} - -bool GAPID3D9::FindDirect3DFunctions() { - d3d_module_ = LoadLibrary(TEXT("d3d9.dll")); - if (NULL == d3d_module_) { - LOG(ERROR) << "Failed to load d3d9.dll"; - return false; - } - - direct3d_create9_ = reinterpret_cast( - GetProcAddress(d3d_module_, "Direct3DCreate9")); - if (NULL == direct3d_create9_) { - LOG(ERROR) << "Failed to find Direct3DCreate9 in d3d9.dll"; - Destroy(); - return false; - } - - d3dx_module_ = LoadLibrary(TEXT("d3dx9_36.dll")); - if (NULL == d3d_module_) { - LOG(ERROR) << "Failed to load d3dx9_36.dll"; - return false; - } - - get_shader_constant_table_ = reinterpret_cast( - GetProcAddress(d3dx_module_, "D3DXGetShaderConstantTable")); - if (NULL == get_shader_constant_table_) { - LOG(ERROR) << "Failed to find D3DXGetShaderConstantTable in d3dx9_36.dll"; - Destroy(); - return false; - } - - create_effect_ = reinterpret_cast( - GetProcAddress(d3dx_module_, "D3DXCreateEffect")); - if (NULL == create_effect_) { - LOG(ERROR) << "Failed to find D3DXCreateEffect in d3dx9_36.dll"; - Destroy(); - return false; - } - - get_shader_input_semantics_ = - reinterpret_cast( - GetProcAddress(d3dx_module_, "D3DXGetShaderInputSemantics")); - if (NULL == get_shader_input_semantics_) { - LOG(ERROR) << "Failed to find D3DXGetShaderInputSemantics in d3dx9_36.dll"; - Destroy(); - return false; - } - - return true; -} - -// Sets in D3D the input streams of the current vertex struct. -bool GAPID3D9::ValidateStreams() { - DCHECK(validate_streams_); - VertexStructD3D9 *vertex_struct = vertex_structs_.Get(current_vertex_struct_); - if (!vertex_struct) { - LOG(ERROR) << "Drawing with invalid streams."; - return false; - } - max_vertices_ = vertex_struct->SetStreams(this); - validate_streams_ = false; - return max_vertices_ > 0; -} - -// Converts a GAPID3D9::PrimitiveType to a D3DPRIMITIVETYPE. -static D3DPRIMITIVETYPE D3DPrimitive( - PrimitiveType primitive_type) { - switch (primitive_type) { - case kPoints: - return D3DPT_POINTLIST; - case kLines: - return D3DPT_LINELIST; - case kLineStrips: - return D3DPT_LINESTRIP; - case kTriangles: - return D3DPT_TRIANGLELIST; - case kTriangleStrips: - return D3DPT_TRIANGLESTRIP; - case kTriangleFans: - return D3DPT_TRIANGLEFAN; - default: - LOG(FATAL) << "Invalid primitive type"; - return D3DPT_POINTLIST; - } -} - -// Draws with the current vertex struct. -parse_error::ParseError GAPID3D9::Draw( - PrimitiveType primitive_type, - unsigned int first, - unsigned int count) { - if (validate_streams_ && !ValidateStreams()) { - // TODO: add proper error management - return parse_error::kParseInvalidArguments; - } - if (validate_effect_ && !ValidateEffect()) { - // TODO: add proper error management - return parse_error::kParseInvalidArguments; - } - DCHECK(current_effect_); - if (!current_effect_->CommitParameters()) { - return parse_error::kParseInvalidArguments; - } - if (first + count > max_vertices_) { - // TODO: add proper error management - return parse_error::kParseInvalidArguments; - } - HR(d3d_device_->DrawPrimitive(D3DPrimitive(primitive_type), first, count)); - return parse_error::kParseNoError; -} - -// Draws with the current vertex struct. -parse_error::ParseError GAPID3D9::DrawIndexed( - PrimitiveType primitive_type, - ResourceId index_buffer_id, - unsigned int first, - unsigned int count, - unsigned int min_index, - unsigned int max_index) { - IndexBufferD3D9 *index_buffer = index_buffers_.Get(index_buffer_id); - if (!index_buffer) return parse_error::kParseInvalidArguments; - if (validate_streams_ && !ValidateStreams()) { - // TODO: add proper error management - return parse_error::kParseInvalidArguments; - } - if (validate_effect_ && !ValidateEffect()) { - // TODO: add proper error management - return parse_error::kParseInvalidArguments; - } - DCHECK(current_effect_); - if (!current_effect_->CommitParameters()) { - return parse_error::kParseInvalidArguments; - } - if ((min_index >= max_vertices_) || (max_index > max_vertices_)) { - // TODO: add proper error management - return parse_error::kParseInvalidArguments; - } - - HR(d3d_device_->SetIndices(index_buffer->d3d_index_buffer())); - HR(d3d_device_->DrawIndexedPrimitive(D3DPrimitive(primitive_type), 0, - min_index, max_index - min_index + 1, - first, count)); - return parse_error::kParseNoError; -} - -} // namespace o3d -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/service/gapi_d3d9.h b/o3d/gpu/command_buffer/service/gapi_d3d9.h deleted file mode 100644 index 1056dc1..0000000 --- a/o3d/gpu/command_buffer/service/gapi_d3d9.h +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the GAPID3D9 class, implementing the GAPI interface for -// D3D9. - -#ifndef GPU_COMMAND_BUFFER_SERVICE_GAPI_D3D9_H_ -#define GPU_COMMAND_BUFFER_SERVICE_GAPI_D3D9_H_ - -#include "gpu/command_buffer/common/gapi_interface.h" -#include "gpu/command_buffer/service/d3d9_utils.h" -#include "gpu/command_buffer/service/geometry_d3d9.h" -#include "gpu/command_buffer/service/effect_d3d9.h" -#include "gpu/command_buffer/service/texture_d3d9.h" -#include "gpu/command_buffer/service/sampler_d3d9.h" -#include "gpu/command_buffer/service/render_surface_d3d9.h" - -namespace command_buffer { -namespace o3d { - -// This class implements the GAPI interface for D3D9. -class GAPID3D9 : public GAPIInterface { - public: - GAPID3D9(); - virtual ~GAPID3D9(); - - void set_hwnd(HWND hwnd) { hwnd_ = hwnd; } - HWND hwnd() const { return hwnd_; } - - // Initializes the graphics context, bound to a window. - // Returns: - // true if successful. - virtual bool Initialize(); - - // Destroys the graphics context. - virtual void Destroy(); - - // Implements the BeginFrame function for D3D9. - virtual void BeginFrame(); - - // Implements the EndFrame function for D3D9. - virtual void EndFrame(); - - // Implements the Clear function for D3D9. - virtual void Clear(unsigned int buffers, - const RGBA &color, - float depth, - unsigned int stencil); - - // Implements the SetViewport function for D3D9. - virtual void SetViewport(unsigned int x, - unsigned int y, - unsigned int width, - unsigned int height, - float z_min, - float z_max); - - // Implements the CreateVertexBuffer function for D3D9. - virtual ParseError CreateVertexBuffer(ResourceId id, - unsigned int size, - unsigned int flags); - - // Implements the DestroyVertexBuffer function for D3D9. - virtual ParseError DestroyVertexBuffer(ResourceId id); - - // Implements the SetVertexBufferData function for D3D9. - virtual ParseError SetVertexBufferData(ResourceId id, - unsigned int offset, - unsigned int size, - const void *data); - - // Implements the GetVertexBufferData function for D3D9. - virtual ParseError GetVertexBufferData(ResourceId id, - unsigned int offset, - unsigned int size, - void *data); - - // Implements the CreateIndexBuffer function for D3D9. - virtual ParseError CreateIndexBuffer(ResourceId id, - unsigned int size, - unsigned int flags); - - // Implements the DestroyIndexBuffer function for D3D9. - virtual ParseError DestroyIndexBuffer(ResourceId id); - - // Implements the SetIndexBufferData function for D3D9. - virtual ParseError SetIndexBufferData(ResourceId id, - unsigned int offset, - unsigned int size, - const void *data); - - // Implements the GetIndexBufferData function for D3D9. - virtual ParseError GetIndexBufferData(ResourceId id, - unsigned int offset, - unsigned int size, - void *data); - - // Implements the CreateVertexStruct function for D3D9. - virtual ParseError CreateVertexStruct(ResourceId id, - unsigned int input_count); - - // Implements the DestroyVertexStruct function for D3D9. - virtual ParseError DestroyVertexStruct(ResourceId id); - - // Implements the SetVertexInput function for D3D9. - virtual ParseError SetVertexInput(ResourceId vertex_struct_id, - unsigned int input_index, - ResourceId vertex_buffer_id, - unsigned int offset, - unsigned int stride, - vertex_struct::Type type, - vertex_struct::Semantic semantic, - unsigned int semantic_index); - - // Implements the SetVertexStruct function for D3D9. - virtual ParseError SetVertexStruct(ResourceId id); - - // Implements the Draw function for D3D9. - virtual ParseError Draw(PrimitiveType primitive_type, - unsigned int first, - unsigned int count); - - // Implements the DrawIndexed function for D3D9. - virtual ParseError DrawIndexed(PrimitiveType primitive_type, - ResourceId index_buffer_id, - unsigned int first, - unsigned int count, - unsigned int min_index, - unsigned int max_index); - - // Implements the CreateEffect function for D3D9. - virtual ParseError CreateEffect(ResourceId id, - unsigned int size, - const void *data); - - // Implements the DestroyEffect function for D3D9. - virtual ParseError DestroyEffect(ResourceId id); - - // Implements the SetEffect function for D3D9. - virtual ParseError SetEffect(ResourceId id); - - // Implements the GetParamCount function for D3D9. - virtual ParseError GetParamCount(ResourceId id, - unsigned int size, - void *data); - - // Implements the CreateParam function for D3D9. - virtual ParseError CreateParam(ResourceId param_id, - ResourceId effect_id, - unsigned int index); - - // Implements the CreateParamByName function for D3D9. - virtual ParseError CreateParamByName(ResourceId param_id, - ResourceId effect_id, - unsigned int size, - const void *name); - - // Implements the DestroyParam function for D3D9. - virtual ParseError DestroyParam(ResourceId id); - - // Implements the SetParamData function for D3D9. - virtual ParseError SetParamData(ResourceId id, - unsigned int size, - const void *data); - - // Implements the GetParamDesc function for D3D9. - virtual ParseError GetParamDesc(ResourceId id, - unsigned int size, - void *data); - - // Implements the GetStreamCount function for D3D9. - virtual ParseError GetStreamCount(ResourceId id, - unsigned int size, - void *data); - - // Implements the GetStreamDesc function for D3D9. - virtual ParseError GetStreamDesc(ResourceId id, - unsigned int index, - unsigned int size, - void *data); - - // Implements the CreateTexture2D function for D3D9. - virtual ParseError CreateTexture2D(ResourceId id, - unsigned int width, - unsigned int height, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces); - - // Implements the CreateTexture3D function for D3D9. - virtual ParseError CreateTexture3D(ResourceId id, - unsigned int width, - unsigned int height, - unsigned int depth, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces); - - // Implements the CreateTextureCube function for D3D9. - virtual ParseError CreateTextureCube(ResourceId id, - unsigned int side, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces); - - // Implements the SetTextureData function for D3D9. - virtual ParseError SetTextureData(ResourceId id, - unsigned int x, - unsigned int y, - unsigned int z, - unsigned int width, - unsigned int height, - unsigned int depth, - unsigned int level, - texture::Face face, - unsigned int pitch, - unsigned int slice_pitch, - unsigned int size, - const void *data); - - // Implements the GetTextureData function for D3D9. - virtual ParseError GetTextureData(ResourceId id, - unsigned int x, - unsigned int y, - unsigned int z, - unsigned int width, - unsigned int height, - unsigned int depth, - unsigned int level, - texture::Face face, - unsigned int pitch, - unsigned int slice_pitch, - unsigned int size, - void *data); - - // Implements the DestroyTexture function for D3D9. - virtual ParseError DestroyTexture(ResourceId id); - - // Implements the CreateSampler function for D3D9. - virtual ParseError CreateSampler(ResourceId id); - - // Implements the DestroySampler function for D3D9. - virtual ParseError DestroySampler(ResourceId id); - - // Implements the SetSamplerStates function for D3D9. - virtual ParseError SetSamplerStates(ResourceId id, - sampler::AddressingMode addressing_u, - sampler::AddressingMode addressing_v, - sampler::AddressingMode addressing_w, - sampler::FilteringMode mag_filter, - sampler::FilteringMode min_filter, - sampler::FilteringMode mip_filter, - unsigned int max_anisotropy); - - // Implements the SetSamplerBorderColor function for D3D9. - virtual ParseError SetSamplerBorderColor(ResourceId id, const RGBA &color); - - // Implements the SetSamplerTexture function for D3D9. - virtual ParseError SetSamplerTexture(ResourceId id, ResourceId texture_id); - - // Implements the SetScissor function for D3D9. - virtual void SetScissor(bool enable, - unsigned int x, - unsigned int y, - unsigned int width, - unsigned int height); - - // Implements the SetPointLineRaster function for D3D9. - virtual void SetPointLineRaster(bool line_smooth, - bool point_sprite, - float point_size); - - // Implements the SetPolygonOffset function for D3D9. - virtual void SetPolygonOffset(float slope_factor, float units); - - // Implements the SetPolygonRaster function for D3D9. - virtual void SetPolygonRaster(PolygonMode fill_mode, - FaceCullMode cull_mode); - - // Implements the SetAlphaTest function for D3D9. - virtual void SetAlphaTest(bool enable, - float reference, - Comparison comp); - - // Implements the SetDepthTest function for D3D9. - virtual void SetDepthTest(bool enable, - bool write_enable, - Comparison comp); - - // Implements the SetStencilTest function for D3D9. - virtual void SetStencilTest(bool enable, - bool separate_ccw, - unsigned int write_mask, - unsigned int compare_mask, - unsigned int ref, - Uint32 func_ops); - - // Implements the SetColorWritefunction for D3D9. - virtual void SetColorWrite(bool red, - bool green, - bool blue, - bool alpha, - bool dither); - - // Implements the SetBlending function for D3D9. - virtual void SetBlending(bool enable, - bool separate_alpha, - BlendEq color_eq, - BlendFunc color_src_func, - BlendFunc color_dst_func, - BlendEq alpha_eq, - BlendFunc alpha_src_func, - BlendFunc alpha_dst_func); - - // Implements the SetBlendingColor function for D3D9. - virtual void SetBlendingColor(const RGBA &color); - - // Implements the CreateRenderSurface function for D3D9. - virtual ParseError CreateRenderSurface(ResourceId id, - unsigned int width, - unsigned int height, - unsigned int mip_level, - unsigned int side, - ResourceId texture_id); - - // Implements the DestroyRenderSurface function for D3D9. - virtual ParseError DestroyRenderSurface(ResourceId id); - - // Implements the CreateDepthSurface function for D3D9. - virtual ParseError CreateDepthSurface(ResourceId id, - unsigned int width, - unsigned int height); - - // Implements teh DestroyDepthSurface function for D3D9. - virtual ParseError DestroyDepthSurface(ResourceId id); - - // Implements the SetRenderSurface function for D3D9. - virtual ParseError SetRenderSurface(ResourceId render_surface_id, - ResourceId depth_stencil_id); - - // Implements the SetBackSurfaces function for D3D9. - virtual void SetBackSurfaces(); - - // Gets the D3D9 device. - IDirect3DDevice9 *d3d_device() const { return d3d_device_; } - - // Gets a vertex buffer by resource ID. - VertexBufferD3D9 *GetVertexBuffer(ResourceId id) { - return vertex_buffers_.Get(id); - } - - // Gets a texture by resource ID. - TextureD3D9 *GetTexture(ResourceId id) { - return textures_.Get(id); - } - - // Gets a sampler by resource ID. - SamplerD3D9 *GetSampler(ResourceId id) { - return samplers_.Get(id); - } - - EffectD3D9 *current_effect() { return current_effect_; } - - // Direct3D functions cannot be called directly because the DLLs are loaded - // dynamically via LoadLibrary. If you need to add another Direct3D function - // add another function here, a typedef matching the signature and a member - // variable of that type below. Then add code to FindDirect3DFunctions to - // get the address of that function out of the DLL and assign it to the - // member variable. Be careful to initialize the value of the variable to - // NULL in the constructor and to set it to again NULL in Destroy. - - IDirect3D9* Direct3DCreate(UINT version) { - DCHECK(direct3d_create9_); - return direct3d_create9_(version); - } - - HRESULT D3DXGetShaderConstantTable(const DWORD* function, - LPD3DXCONSTANTTABLE* table) { - DCHECK(get_shader_constant_table_); - return get_shader_constant_table_(function, table); - } - - HRESULT D3DXCreateEffect(LPDIRECT3DDEVICE9 device, - LPCVOID src_data, - UINT src_data_len, - CONST D3DXMACRO * defines, - LPD3DXINCLUDE include, - DWORD flags, - LPD3DXEFFECTPOOL pool, - LPD3DXEFFECT * effect, - LPD3DXBUFFER * compilation_errors) { - DCHECK(create_effect_); - return create_effect_(device, src_data, src_data_len, defines, include, - flags, pool, effect, compilation_errors); - } - - HRESULT D3DXGetShaderInputSemantics(const DWORD* function, - D3DXSEMANTIC* semantics, - UINT* count) { - DCHECK(get_shader_input_semantics_); - return get_shader_input_semantics_(function, semantics, count); - } - - private: - bool FindDirect3DFunctions(); - - // Validates the current vertex struct to D3D, setting the streams. - bool ValidateStreams(); - // Validates the current effect to D3D. This sends the effect states to D3D. - bool ValidateEffect(); - // "Dirty" the current effect. This resets the effect states to D3D, and - // requires ValidateEffect() to be called before further draws occur. - void DirtyEffect(); - - // Module handle for d3d9.dll. - HMODULE d3d_module_; - - // Module handle for d3dx9_n.dll - HMODULE d3dx_module_; - - LPDIRECT3D9 d3d_; - LPDIRECT3DDEVICE9 d3d_device_; - HWND hwnd_; - ResourceId current_vertex_struct_; - bool validate_streams_; - unsigned int max_vertices_; - ResourceId current_effect_id_; - bool validate_effect_; - EffectD3D9 *current_effect_; - IDirect3DSurface9* back_buffer_surface_; - IDirect3DSurface9* back_buffer_depth_surface_; - ResourceId current_surface_id_; - ResourceId current_depth_surface_id_; - - ResourceMap vertex_buffers_; - ResourceMap index_buffers_; - ResourceMap vertex_structs_; - ResourceMap effects_; - ResourceMap effect_params_; - ResourceMap textures_; - ResourceMap samplers_; - ResourceMap render_surfaces_; - ResourceMap depth_surfaces_; - - typedef IDirect3D9* (WINAPI *Direct3DCreate9Proc)(UINT version); - Direct3DCreate9Proc direct3d_create9_; - - typedef HRESULT (WINAPI *D3DXGetShaderConstantTableProc)( - const DWORD* function, - LPD3DXCONSTANTTABLE* table); - D3DXGetShaderConstantTableProc get_shader_constant_table_; - - typedef HRESULT (WINAPI *D3DXCreateEffectProc)( - LPDIRECT3DDEVICE9 device, - LPCVOID src_data, - UINT src_data_len, - CONST D3DXMACRO * defines, - LPD3DXINCLUDE include, - DWORD flags, - LPD3DXEFFECTPOOL pool, - LPD3DXEFFECT * effect, - LPD3DXBUFFER * compilation_errors); - D3DXCreateEffectProc create_effect_; - - typedef HRESULT (WINAPI *D3DXGetShaderInputSemanticsProc)( - const DWORD* function, - D3DXSEMANTIC* semantics, - UINT* count); - D3DXGetShaderInputSemanticsProc get_shader_input_semantics_; -}; - -} // namespace o3d -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_SERVICE_GAPI_D3D9_H_ - diff --git a/o3d/gpu/command_buffer/service/gapi_decoder.cc b/o3d/gpu/command_buffer/service/gapi_decoder.cc deleted file mode 100644 index 4d91b69..0000000 --- a/o3d/gpu/command_buffer/service/gapi_decoder.cc +++ /dev/null @@ -1,940 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This class contains the implementation of the GAPI decoder class, decoding -// GAPI commands into calls to a GAPIInterface class. - -#include "gpu/command_buffer/service/precompile.h" - -#include "base/cross/bits.h" -#include "gpu/command_buffer/common/gapi_interface.h" -#include "gpu/command_buffer/service/gapi_decoder.h" - -namespace command_buffer { -namespace o3d { - -namespace { - -// Returns the address of the first byte after a struct. -template -const void* AddressAfterStruct(const T& pod) { - return reinterpret_cast(&pod) + sizeof(pod); -} - -// Returns the size in bytes of the data of an Immediate command, a command with -// its data inline in the command buffer. -template -unsigned int ImmediateDataSize(uint32 arg_count, const T& pod) { - return static_cast( - (arg_count + 1 - ComputeNumEntries(sizeof(pod))) * - sizeof(CommandBufferEntry)); // NOLINT -} - -// A struct to hold info about each command. -struct CommandInfo { - int arg_flags; // How to handle the arguments for this command - int arg_count; // How many arguments are expected for this command. -}; - -// A table of CommandInfo for all the commands. -const CommandInfo g_command_info[] = { - #define O3D_COMMAND_BUFFER_CMD_OP(name) { \ - name::kArgFlags, \ - sizeof(name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ \ - - O3D_COMMAND_BUFFER_CMDS(O3D_COMMAND_BUFFER_CMD_OP) - - #undef O3D_COMMAND_BUFFER_CMD_OP -}; - -} // anonymous namespace. - -// Decode command with its arguments, and call the corresponding method. -// Note: args is a pointer to the command buffer. As such, it could be changed -// by a (malicious) client at any time, so if validation has to happen, it -// should operate on a copy of them. -parse_error::ParseError GAPIDecoder::DoCommand( - unsigned int command, - unsigned int arg_count, - const void* cmd_data) { - unsigned int command_index = command - kStartPoint - 1; - if (command_index < arraysize(g_command_info)) { - const CommandInfo& info = g_command_info[command_index]; - unsigned int info_arg_count = static_cast(info.arg_count); - if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) || - (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) { - switch (command) { - #define O3D_COMMAND_BUFFER_CMD_OP(name) \ - case name::kCmdId: \ - return Handle ## name( \ - arg_count, \ - *static_cast(cmd_data)); \ - - O3D_COMMAND_BUFFER_CMDS(O3D_COMMAND_BUFFER_CMD_OP) - - #undef O3D_COMMAND_BUFFER_CMD_OP - } - } else { - return parse_error::kParseInvalidArguments; - } - } - return DoCommonCommand(command, arg_count, cmd_data); - return parse_error::kParseUnknownCommand; -} - - // Overridden from AsyncAPIInterface. -const char* GAPIDecoder::GetCommandName(unsigned int command_id) const { - if (command_id > kStartPoint && command_id < kNumCommands) { - return o3d::GetCommandName(static_cast(command_id)); - } - return GetCommonCommandName(static_cast(command_id)); -} - -parse_error::ParseError GAPIDecoder::HandleBeginFrame( - uint32 arg_count, - const BeginFrame& args) { - gapi_->BeginFrame(); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIDecoder::HandleEndFrame( - uint32 arg_count, - const EndFrame& args) { - gapi_->EndFrame(); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIDecoder::HandleClear( - uint32 arg_count, - const Clear& args) { - // Pull out some values so they can't be changed by another thread after we've - // validated them. - uint32 buffers = args.buffers; - if (buffers & ~kAllBuffers) - return parse_error::kParseInvalidArguments; - RGBA rgba; - rgba.red = args.red; - rgba.green = args.green; - rgba.blue = args.blue; - rgba.alpha = args.alpha; - gapi_->Clear(buffers, rgba, args.depth, args.stencil); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIDecoder::HandleSetViewport( - uint32 arg_count, - const SetViewport& args) { - gapi_->SetViewport(args.left, - args.top, - args.width, - args.height, - args.z_min, - args.z_max); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIDecoder::HandleCreateVertexBuffer( - uint32 arg_count, - const CreateVertexBuffer& args) { - return gapi_->CreateVertexBuffer( - args.vertex_buffer_id, args.size, args.flags); -} - -parse_error::ParseError GAPIDecoder::HandleDestroyVertexBuffer( - uint32 arg_count, - const DestroyVertexBuffer& args) { - return gapi_->DestroyVertexBuffer(args.vertex_buffer_id); -} - -parse_error::ParseError GAPIDecoder::HandleSetVertexBufferDataImmediate( - uint32 arg_count, - const SetVertexBufferDataImmediate& args) { - uint32 size = ImmediateDataSize(arg_count, args); - if (size == 0) { - return parse_error::kParseNoError; - } - return gapi_->SetVertexBufferData(args.vertex_buffer_id, args.offset, - size, - AddressAfterStruct(args)); -} - -parse_error::ParseError GAPIDecoder::HandleSetVertexBufferData( - uint32 arg_count, - const SetVertexBufferData& args) { - // Pull out some values so they can't be changed by another thread after we've - // validated them. - uint32 size = args.size; - void *data = GetAddressAndCheckSize(args.shared_memory.id, - args.shared_memory.offset, - size); - if (!data) return parse_error::kParseInvalidArguments; - return gapi_->SetVertexBufferData( - args.vertex_buffer_id, args.offset, size, data); -} - -parse_error::ParseError GAPIDecoder::HandleGetVertexBufferData( - uint32 arg_count, - const GetVertexBufferData& args) { - // Pull out some values so they can't be changed by another thread after we've - // validated them. - uint32 size = args.size; - void *data = GetAddressAndCheckSize(args.shared_memory.id, - args.shared_memory.offset, - size); - if (!data) return parse_error::kParseInvalidArguments; - return gapi_->GetVertexBufferData( - args.vertex_buffer_id, args.offset, size, data); -} - -parse_error::ParseError GAPIDecoder::HandleCreateIndexBuffer( - uint32 arg_count, - const CreateIndexBuffer& args) { - return gapi_->CreateIndexBuffer(args.index_buffer_id, args.size, args.flags); -} - -parse_error::ParseError GAPIDecoder::HandleDestroyIndexBuffer( - uint32 arg_count, - const DestroyIndexBuffer& args) { - return gapi_->DestroyIndexBuffer(args.index_buffer_id); -} - -parse_error::ParseError GAPIDecoder::HandleSetIndexBufferDataImmediate( - uint32 arg_count, - const SetIndexBufferDataImmediate& args) { - uint32 size = ImmediateDataSize(arg_count, args); - if (size == 0) { - return parse_error::kParseNoError; - } - return gapi_->SetIndexBufferData(args.index_buffer_id, args.offset, size, - AddressAfterStruct(args)); -} - -parse_error::ParseError GAPIDecoder::HandleSetIndexBufferData( - uint32 arg_count, - const SetIndexBufferData& args) { - // Pull out some values so they can't be changed by another thread after we've - // validated them. - uint32 size = args.size; - void *data = GetAddressAndCheckSize(args.shared_memory.id, - args.shared_memory.offset, - size); - if (!data) return parse_error::kParseInvalidArguments; - return gapi_->SetIndexBufferData( - args.index_buffer_id, args.offset, size, data); -} - -parse_error::ParseError GAPIDecoder::HandleGetIndexBufferData( - uint32 arg_count, - const GetIndexBufferData& args) { - // Pull out some values so they can't be changed by another thread after we've - // validated them. - uint32 size = args.size; - void *data = GetAddressAndCheckSize(args.shared_memory.id, - args.shared_memory.offset, - size); - if (!data) return parse_error::kParseInvalidArguments; - return gapi_->GetIndexBufferData( - args.index_buffer_id, args.offset, size, data); -} - -parse_error::ParseError GAPIDecoder::HandleCreateVertexStruct( - uint32 arg_count, - const CreateVertexStruct& args) { - return gapi_->CreateVertexStruct(args.vertex_struct_id, args.input_count); -} - -parse_error::ParseError GAPIDecoder::HandleDestroyVertexStruct( - uint32 arg_count, - const DestroyVertexStruct& args) { - return gapi_->DestroyVertexStruct(args.vertex_struct_id); -} - -parse_error::ParseError GAPIDecoder::HandleSetVertexInput( - uint32 arg_count, - const SetVertexInput& args) { - unsigned int type_stride_semantic = args.type_stride_semantic; - unsigned int semantic_index = - SetVertexInput::SemanticIndex::Get(type_stride_semantic); - unsigned int semantic = - SetVertexInput::Semantic::Get(type_stride_semantic); - unsigned int type = - SetVertexInput::Type::Get(type_stride_semantic); - unsigned int stride = - SetVertexInput::Stride::Get(type_stride_semantic); - if (semantic >= vertex_struct::kNumSemantics || - type >= vertex_struct::kNumTypes || stride == 0) - return parse_error::kParseInvalidArguments; - return gapi_->SetVertexInput( - args.vertex_struct_id, args.input_index, args.vertex_buffer_id, - args.offset, stride, - static_cast(type), - static_cast(semantic), - semantic_index); -} - -parse_error::ParseError GAPIDecoder::HandleSetVertexStruct( - uint32 arg_count, - const SetVertexStruct& args) { - return gapi_->SetVertexStruct(args.vertex_struct_id); -} - -parse_error::ParseError GAPIDecoder::HandleDraw( - uint32 arg_count, - const Draw& args) { - // Pull out some values so they can't be changed by another thread after we've - // validated them. - uint32 primitive_type = args.primitive_type; - if (primitive_type >= kMaxPrimitiveType) - return parse_error::kParseInvalidArguments; - return gapi_->Draw( - static_cast(primitive_type), - args.first, args.count); -} - -parse_error::ParseError GAPIDecoder::HandleDrawIndexed( - uint32 arg_count, - const DrawIndexed& args) { - // Pull out some values so they can't be changed by another thread after we've - // validated them. - uint32 primitive_type = args.primitive_type; - if (primitive_type >= kMaxPrimitiveType) - return parse_error::kParseInvalidArguments; - return gapi_->DrawIndexed( - static_cast(primitive_type), - args.index_buffer_id, - args.first, args.count, args.min_index, args.max_index); -} - -parse_error::ParseError GAPIDecoder::HandleCreateEffect( - uint32 arg_count, - const CreateEffect& args) { - // Pull out some values so they can't be changed by another thread after we've - // validated them. - uint32 size = args.size; - void *data = GetAddressAndCheckSize(args.shared_memory.id, - args.shared_memory.offset, - size); - if (!data) return parse_error::kParseInvalidArguments; - return gapi_->CreateEffect(args.effect_id, size, data); -} - -parse_error::ParseError GAPIDecoder::HandleCreateEffectImmediate( - uint32 arg_count, - const CreateEffectImmediate& args) { - // Pull out some values so they can't be changed by another thread after we've - // validated them. - uint32 size = args.size; - uint32 data_size = ImmediateDataSize(arg_count, args); - if (size > data_size) { - return parse_error::kParseInvalidArguments; - } - if (data_size == 0) { - return parse_error::kParseNoError; - } - return gapi_->CreateEffect(args.effect_id, size, AddressAfterStruct(args)); -} - -parse_error::ParseError GAPIDecoder::HandleDestroyEffect( - uint32 arg_count, - const DestroyEffect& args) { - return gapi_->DestroyEffect(args.effect_id); -} - -parse_error::ParseError GAPIDecoder::HandleSetEffect( - uint32 arg_count, - const SetEffect& args) { - return gapi_->SetEffect(args.effect_id); -} - -parse_error::ParseError GAPIDecoder::HandleGetParamCount( - uint32 arg_count, - const GetParamCount& args) { - // Pull out some values so they can't be changed by another thread after we've - // validated them. - uint32 size = args.size; - void *data = GetAddressAndCheckSize(args.shared_memory.id, - args.shared_memory.offset, - size); - if (!data) return parse_error::kParseInvalidArguments; - return gapi_->GetParamCount(args.effect_id, size, data); -} - -parse_error::ParseError GAPIDecoder::HandleCreateParam( - uint32 arg_count, - const CreateParam& args) { - return gapi_->CreateParam(args.param_id, args.effect_id, args.index); -} - -parse_error::ParseError GAPIDecoder::HandleCreateParamByName( - uint32 arg_count, - const CreateParamByName& args) { - // Pull out some values so they can't be changed by another thread after we've - // validated them. - uint32 size = args.size; - void *data = GetAddressAndCheckSize(args.shared_memory.id, - args.shared_memory.offset, - size); - if (!data) return parse_error::kParseInvalidArguments; - return gapi_->CreateParamByName(args.param_id, args.effect_id, size, - data); -} - -parse_error::ParseError GAPIDecoder::HandleCreateParamByNameImmediate( - uint32 arg_count, - const CreateParamByNameImmediate& args) { - // Pull out some values so they can't be changed by another thread after we've - // validated them. - uint32 size = args.size; - uint32 data_size = ImmediateDataSize(arg_count, args); - if (size > data_size) - return parse_error::kParseInvalidArguments; - if (data_size == 0) { - return parse_error::kParseNoError; - } - return gapi_->CreateParamByName(args.param_id, args.effect_id, size, - AddressAfterStruct(args)); -} - -parse_error::ParseError GAPIDecoder::HandleDestroyParam( - uint32 arg_count, - const DestroyParam& args) { - return gapi_->DestroyParam(args.param_id); -} - -parse_error::ParseError GAPIDecoder::HandleSetParamData( - uint32 arg_count, - const SetParamData& args) { - // Pull out some values so they can't be changed by another thread after we've - // validated them. - uint32 size = args.size; - void *data = GetAddressAndCheckSize(args.shared_memory.id, - args.shared_memory.offset, - size); - if (!data) return parse_error::kParseInvalidArguments; - return gapi_->SetParamData(args.param_id, size, data); -} - -parse_error::ParseError GAPIDecoder::HandleSetParamDataImmediate( - uint32 arg_count, - const SetParamDataImmediate& args) { - // Pull out some values so they can't be changed by another thread after we've - // validated them. - uint32 size = args.size; - uint32 data_size = ImmediateDataSize(arg_count, args); - if (size > data_size) { - return parse_error::kParseInvalidArguments; - } - if (data_size == 0) { - return parse_error::kParseNoError; - } - return gapi_->SetParamData(args.param_id, size, AddressAfterStruct(args)); -} - -parse_error::ParseError GAPIDecoder::HandleGetParamDesc( - uint32 arg_count, - const GetParamDesc& args) { - // Pull out some values so they can't be changed by another thread after we've - // validated them. - uint32 size = args.size; - void *data = GetAddressAndCheckSize(args.shared_memory.id, - args.shared_memory.offset, - size); - if (!data) return parse_error::kParseInvalidArguments; - return gapi_->GetParamDesc(args.param_id, size, data); -} - -parse_error::ParseError GAPIDecoder::HandleGetStreamCount( - uint32 arg_count, - const GetStreamCount& args) { - // Pull out some values so they can't be changed by another thread after we've - // validated them. - uint32 size = args.size; - void *data = GetAddressAndCheckSize(args.shared_memory.id, - args.shared_memory.offset, - size); - if (!data) return parse_error::kParseInvalidArguments; - return gapi_->GetStreamCount(args.effect_id, size, data); -} - -parse_error::ParseError GAPIDecoder::HandleGetStreamDesc( - uint32 arg_count, - const GetStreamDesc& args) { - // Pull out some values so they can't be changed by another thread after we've - // validated them. - uint32 size = args.size; - void *data = GetAddressAndCheckSize(args.shared_memory.id, - args.shared_memory.offset, - size); - if (!data) return parse_error::kParseInvalidArguments; - return gapi_->GetStreamDesc(args.effect_id, args.index, size, data); -} - -parse_error::ParseError GAPIDecoder::HandleDestroyTexture( - uint32 arg_count, - const DestroyTexture& args) { - return gapi_->DestroyTexture(args.texture_id); -} - -parse_error::ParseError GAPIDecoder::HandleCreateTexture2d( - uint32 arg_count, - const CreateTexture2d& args) { - unsigned int width_height = args.width_height; - unsigned int levels_format_flags = args.levels_format_flags; - unsigned int width = CreateTexture2d::Width::Get(width_height); - unsigned int height = CreateTexture2d::Height::Get(width_height); - unsigned int levels = CreateTexture2d::Levels::Get(levels_format_flags); - unsigned int unused = CreateTexture2d::Unused::Get(levels_format_flags); - unsigned int format = CreateTexture2d::Format::Get(levels_format_flags); - unsigned int flags = CreateTexture2d::Flags::Get(levels_format_flags); - unsigned int max_levels = - 1 + ::o3d::base::bits::Log2Ceiling(std::max(width, height)); - if ((width == 0) || (height == 0) || (levels > max_levels) || - (unused != 0) || (format == texture::kUnknown) || (levels == 0)) - return parse_error::kParseInvalidArguments; - bool enable_render_surfaces = !!flags; - return gapi_->CreateTexture2D(args.texture_id, width, height, levels, - static_cast(format), flags, - enable_render_surfaces); -} - -parse_error::ParseError GAPIDecoder::HandleCreateTexture3d( - uint32 arg_count, - const CreateTexture3d& args) { - unsigned int width_height = args.width_height; - unsigned int depth_unused = args.depth_unused; - unsigned int levels_format_flags = args.levels_format_flags; - unsigned int width = CreateTexture3d::Width::Get(width_height); - unsigned int height = CreateTexture3d::Height::Get(width_height); - unsigned int depth = CreateTexture3d::Depth::Get(depth_unused); - unsigned int unused1 = CreateTexture3d::Unused1::Get(depth_unused); - unsigned int levels = CreateTexture3d::Levels::Get(levels_format_flags); - unsigned int unused2 = CreateTexture3d::Unused2::Get(levels_format_flags); - unsigned int format = CreateTexture3d::Format::Get(levels_format_flags); - unsigned int flags = CreateTexture3d::Flags::Get(levels_format_flags); - unsigned int max_levels = - 1 + ::o3d::base::bits::Log2Ceiling(std::max(depth, std::max(width, height))); - if ((width == 0) || (height == 0) || (depth == 0) || - (levels > max_levels) || (unused1 != 0) || (unused2 != 0) || - (format == texture::kUnknown) || (levels == 0)) - return parse_error::kParseInvalidArguments; - bool enable_render_surfaces = !!flags; - return gapi_->CreateTexture3D(args.texture_id, width, height, depth, levels, - static_cast(format), flags, - enable_render_surfaces); -} - -parse_error::ParseError GAPIDecoder::HandleCreateTextureCube( - uint32 arg_count, - const CreateTextureCube& args) { - unsigned int side_unused = args.edge_length; - unsigned int levels_format_flags = args.levels_format_flags; - unsigned int side = CreateTextureCube::Side::Get(side_unused); - unsigned int unused1 = CreateTextureCube::Unused1::Get(side_unused); - unsigned int levels = CreateTextureCube::Levels::Get(levels_format_flags); - unsigned int unused2 = CreateTextureCube::Unused2::Get(levels_format_flags); - unsigned int format = CreateTextureCube::Format::Get(levels_format_flags); - unsigned int flags = CreateTextureCube::Flags::Get(levels_format_flags); - unsigned int max_levels = 1 + ::o3d::base::bits::Log2Ceiling(side); - if ((side == 0) || (levels > max_levels) || (unused1 != 0) || - (unused2 != 0) || (format == texture::kUnknown) || (levels == 0)) - return parse_error::kParseInvalidArguments; - bool enable_render_surfaces = !!flags; - return gapi_->CreateTextureCube(args.texture_id, side, levels, - static_cast(format), - flags, enable_render_surfaces); -} - -parse_error::ParseError GAPIDecoder::HandleSetTextureData( - uint32 arg_count, - const SetTextureData& args) { - unsigned int x_y = args.x_y; - unsigned int width_height = args.width_height; - unsigned int z_depth = args.z_depth; - unsigned int level_face = args.level_face; - unsigned int size = args.size; - unsigned int x = SetTextureData::X::Get(x_y); - unsigned int y = SetTextureData::Y::Get(x_y); - unsigned int width = SetTextureData::Width::Get(width_height); - unsigned int height = SetTextureData::Height::Get(width_height); - unsigned int z = SetTextureData::Z::Get(z_depth); - unsigned int depth = SetTextureData::Depth::Get(z_depth); - unsigned int level = SetTextureData::Level::Get(level_face); - unsigned int face = SetTextureData::Face::Get(level_face); - unsigned int unused = SetTextureData::Unused::Get(level_face); - const void *data = GetAddressAndCheckSize(args.shared_memory.id, - args.shared_memory.offset, size); - if (face >= 6 || unused != 0 || !data) - return parse_error::kParseInvalidArguments; - return gapi_->SetTextureData( - args.texture_id, x, y, z, width, height, depth, level, - static_cast(face), args.row_pitch, - args.slice_pitch, size, data); -} - -parse_error::ParseError GAPIDecoder::HandleSetTextureDataImmediate( - uint32 arg_count, - const SetTextureDataImmediate& args) { - unsigned int x_y = args.x_y; - unsigned int width_height = args.width_height; - unsigned int z_depth = args.z_depth; - unsigned int level_face = args.level_face; - unsigned int size = args.size; - unsigned int x = SetTextureDataImmediate::X::Get(x_y); - unsigned int y = SetTextureDataImmediate::Y::Get(x_y); - unsigned int width = SetTextureDataImmediate::Width::Get(width_height); - unsigned int height = SetTextureDataImmediate::Height::Get(width_height); - unsigned int z = SetTextureDataImmediate::Z::Get(z_depth); - unsigned int depth = SetTextureDataImmediate::Depth::Get(z_depth); - unsigned int level = SetTextureDataImmediate::Level::Get(level_face); - unsigned int face = SetTextureDataImmediate::Face::Get(level_face); - unsigned int unused = SetTextureDataImmediate::Unused::Get(level_face); - uint32 data_size = ImmediateDataSize(arg_count, args); - if (face >= 6 || unused != 0 || - size > data_size) - return parse_error::kParseInvalidArguments; - if (data_size == 0) { - return parse_error::kParseNoError; - } - return gapi_->SetTextureData( - args.texture_id, x, y, z, width, height, depth, level, - static_cast(face), args.row_pitch, - args.slice_pitch, size, AddressAfterStruct(args)); -} - -parse_error::ParseError GAPIDecoder::HandleGetTextureData( - uint32 arg_count, - const GetTextureData& args) { - unsigned int x_y = args.x_y; - unsigned int width_height = args.width_height; - unsigned int z_depth = args.z_depth; - unsigned int level_face = args.level_face; - unsigned int size = args.size; - unsigned int x = GetTextureData::X::Get(x_y); - unsigned int y = GetTextureData::Y::Get(x_y); - unsigned int width = GetTextureData::Width::Get(width_height); - unsigned int height = GetTextureData::Height::Get(width_height); - unsigned int z = GetTextureData::Z::Get(z_depth); - unsigned int depth = GetTextureData::Depth::Get(z_depth); - unsigned int level = GetTextureData::Level::Get(level_face); - unsigned int face = GetTextureData::Face::Get(level_face); - unsigned int unused = GetTextureData::Unused::Get(level_face); - void *data = GetAddressAndCheckSize(args.shared_memory.id, - args.shared_memory.offset, size); - if (face >= 6 || unused != 0 || !data) - return parse_error::kParseInvalidArguments; - return gapi_->GetTextureData( - args.texture_id, x, y, z, width, height, depth, level, - static_cast(face), args.row_pitch, - args.slice_pitch, size, data); -} - -parse_error::ParseError GAPIDecoder::HandleCreateSampler( - uint32 arg_count, - const CreateSampler& args) { - return gapi_->CreateSampler(args.sampler_id); -} - -parse_error::ParseError GAPIDecoder::HandleDestroySampler( - uint32 arg_count, - const DestroySampler& args) { - return gapi_->DestroySampler(args.sampler_id); -} - -parse_error::ParseError GAPIDecoder::HandleSetSamplerStates( - uint32 arg_count, - const SetSamplerStates& args) { - Uint32 arg = args.sampler_states; - if (SetSamplerStates::Unused::Get(arg) != 0) - return parse_error::kParseInvalidArguments; - unsigned int address_u_value = SetSamplerStates::AddressingU::Get(arg); - unsigned int address_v_value = SetSamplerStates::AddressingV::Get(arg); - unsigned int address_w_value = SetSamplerStates::AddressingW::Get(arg); - unsigned int mag_filter_value = SetSamplerStates::MagFilter::Get(arg); - unsigned int min_filter_value = SetSamplerStates::MinFilter::Get(arg); - unsigned int mip_filter_value = SetSamplerStates::MipFilter::Get(arg); - unsigned int max_anisotropy = SetSamplerStates::MaxAnisotropy::Get(arg); - if (address_u_value >= sampler::kNumAddressingMode || - address_v_value >= sampler::kNumAddressingMode || - address_w_value >= sampler::kNumAddressingMode || - mag_filter_value >= sampler::kNumFilteringMode || - min_filter_value >= sampler::kNumFilteringMode || - mip_filter_value >= sampler::kNumFilteringMode || - mag_filter_value == sampler::kNone || - min_filter_value == sampler::kNone || - max_anisotropy == 0) { - return parse_error::kParseInvalidArguments; - } - gapi_->SetSamplerStates( - args.sampler_id, - static_cast(address_u_value), - static_cast(address_v_value), - static_cast(address_w_value), - static_cast(mag_filter_value), - static_cast(min_filter_value), - static_cast(mip_filter_value), - max_anisotropy); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIDecoder::HandleSetSamplerBorderColor( - uint32 arg_count, - const SetSamplerBorderColor& args) { - RGBA rgba; - rgba.red = args.red; - rgba.green = args.green; - rgba.blue = args.blue; - rgba.alpha = args.alpha; - return gapi_->SetSamplerBorderColor(args.sampler_id, rgba); -} - -parse_error::ParseError GAPIDecoder::HandleSetSamplerTexture( - uint32 arg_count, - const SetSamplerTexture& args) { - return gapi_->SetSamplerTexture(args.sampler_id, args.texture_id); -} - -parse_error::ParseError GAPIDecoder::HandleSetScissor( - uint32 arg_count, - const SetScissor& args) { - Uint32 x_y_enable = args.x_y_enable; - if (SetScissor::Unused::Get(x_y_enable) != 0) - return parse_error::kParseInvalidArguments; - unsigned int x = SetScissor::X::Get(x_y_enable); - unsigned int y = SetScissor::Y::Get(x_y_enable); - bool enable = SetScissor::Enable::Get(x_y_enable) != 0; - Uint32 width_height = args.width_height; - unsigned int width = SetScissor::Width::Get(width_height); - unsigned int height = SetScissor::Height::Get(width_height); - gapi_->SetScissor(enable, x, y, width, height); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIDecoder::HandleSetPolygonOffset( - uint32 arg_count, - const SetPolygonOffset& args) { - gapi_->SetPolygonOffset(args.slope_factor, args.units); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIDecoder::HandleSetPointLineRaster( - uint32 arg_count, - const SetPointLineRaster& args) { - Uint32 enables = args.enables; - if (SetPointLineRaster::Unused::Get(enables) != 0) - return parse_error::kParseInvalidArguments; - bool line_smooth = !!SetPointLineRaster::LineSmoothEnable::Get(enables); - bool point_sprite = !!SetPointLineRaster::PointSpriteEnable::Get(enables); - gapi_->SetPointLineRaster(line_smooth, point_sprite, args.point_size); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIDecoder::HandleSetPolygonRaster( - uint32 arg_count, - const SetPolygonRaster& args) { - Uint32 fill_cull = args.fill_cull; - unsigned int fill_value = SetPolygonRaster::FillMode::Get(fill_cull); - unsigned int cull_value = SetPolygonRaster::CullMode::Get(fill_cull); - if (SetPolygonRaster::Unused::Get(fill_cull) != 0 || - fill_value >= kNumPolygonMode || - cull_value >= kNumFaceCullMode) - return parse_error::kParseInvalidArguments; - gapi_->SetPolygonRaster( - static_cast(fill_value), - static_cast(cull_value)); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIDecoder::HandleSetAlphaTest( - uint32 arg_count, - const SetAlphaTest& args) { - Uint32 func_enable = args.func_enable; - if (SetAlphaTest::Unused::Get(func_enable) != 0) - return parse_error::kParseInvalidArguments; - // Check that the bitmask get cannot generate values outside of the - // allowed range. - COMPILE_ASSERT(SetAlphaTest::Func::kMask < - kNumComparison, - set_alpha_test_Func_may_produce_invalid_values); - Comparison comp = static_cast( - SetAlphaTest::Func::Get(func_enable)); - bool enable = SetAlphaTest::Enable::Get(func_enable) != 0; - gapi_->SetAlphaTest(enable, args.value, comp); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIDecoder::HandleSetDepthTest( - uint32 arg_count, - const SetDepthTest& args) { - Uint32 func_enable = args.func_enable; - if (SetDepthTest::Unused::Get(func_enable) != 0) - return parse_error::kParseInvalidArguments; - // Check that the bitmask get cannot generate values outside of the - // allowed range. - COMPILE_ASSERT(SetDepthTest::Func::kMask < - kNumComparison, - set_alpha_test_Func_may_produce_invalid_values); - Comparison comp = static_cast( - SetDepthTest::Func::Get(func_enable)); - bool write_enable = SetDepthTest::WriteEnable::Get(func_enable) != 0; - bool enable = SetDepthTest::Enable::Get(func_enable) != 0; - gapi_->SetDepthTest(enable, write_enable, comp); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIDecoder::HandleSetStencilTest( - uint32 arg_count, - const SetStencilTest& args) { - Uint32 arg0 = args.stencil_args0; - Uint32 arg1 = args.stencil_args1; - if (SetStencilTest::Unused0::Get(arg0) != 0 || - SetStencilTest::Unused1::Get(arg1) != 0 || - SetStencilTest::Unused2::Get(arg1) != 0) - return parse_error::kParseInvalidArguments; - unsigned int write_mask = SetStencilTest::WriteMask::Get(arg0); - unsigned int compare_mask = SetStencilTest::CompareMask::Get(arg0); - unsigned int ref = SetStencilTest::ReferenceValue::Get(arg0); - bool enable = SetStencilTest::Enable::Get(arg0) != 0; - bool separate_ccw = SetStencilTest::SeparateCCW::Get(arg0) != 0; - gapi_->SetStencilTest(enable, separate_ccw, write_mask, compare_mask, ref, - arg1); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIDecoder::HandleSetColorWrite( - uint32 arg_count, - const SetColorWrite& args) { - Uint32 enables = args.flags; - if (SetColorWrite::Unused::Get(enables) != 0) - return parse_error::kParseInvalidArguments; - bool red = SetColorWrite::RedMask::Get(enables) != 0; - bool green = SetColorWrite::GreenMask::Get(enables) != 0; - bool blue = SetColorWrite::BlueMask::Get(enables) != 0; - bool alpha = SetColorWrite::AlphaMask::Get(enables) != 0; - bool dither = SetColorWrite::DitherEnable::Get(enables) != 0; - gapi_->SetColorWrite(red, green, blue, alpha, dither); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIDecoder::HandleSetBlending( - uint32 arg_count, - const SetBlending& args) { - Uint32 arg = args.blend_settings; - bool enable = SetBlending::Enable::Get(arg) != 0; - bool separate_alpha = SetBlending::SeparateAlpha::Get(arg) != 0; - unsigned int color_eq = SetBlending::ColorEq::Get(arg); - unsigned int color_src = SetBlending::ColorSrcFunc::Get(arg); - unsigned int color_dst = SetBlending::ColorDstFunc::Get(arg); - unsigned int alpha_eq = SetBlending::AlphaEq::Get(arg); - unsigned int alpha_src = SetBlending::AlphaSrcFunc::Get(arg); - unsigned int alpha_dst = SetBlending::AlphaDstFunc::Get(arg); - if (SetBlending::Unused0::Get(arg) != 0 || - SetBlending::Unused1::Get(arg) != 0 || - color_eq >= kNumBlendEq || - color_src >= kNumBlendFunc || - color_dst >= kNumBlendFunc || - alpha_eq >= kNumBlendEq || - alpha_src >= kNumBlendFunc || - alpha_dst >= kNumBlendFunc) - return parse_error::kParseInvalidArguments; - gapi_->SetBlending(enable, - separate_alpha, - static_cast(color_eq), - static_cast(color_src), - static_cast(color_dst), - static_cast(alpha_eq), - static_cast(alpha_src), - static_cast(alpha_dst)); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIDecoder::HandleSetBlendingColor( - uint32 arg_count, - const SetBlendingColor& args) { - RGBA rgba; - rgba.red = args.red; - rgba.green = args.green; - rgba.blue = args.blue; - rgba.alpha = args.alpha; - gapi_->SetBlendingColor(rgba); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIDecoder::HandleCreateRenderSurface( - uint32 arg_count, - const CreateRenderSurface& args) { - unsigned int width_height = args.width_height; - unsigned int width = CreateRenderSurface::Width::Get(width_height); - unsigned int height = CreateRenderSurface::Height::Get(width_height); - unsigned int levels_side = args.levels_side; - unsigned int mip_level = CreateRenderSurface::Levels::Get(levels_side); - unsigned int side = CreateRenderSurface::Side::Get(levels_side); - return gapi_->CreateRenderSurface(args.render_surface_id, - width, height, mip_level, - side, args.texture_id); -} - -parse_error::ParseError GAPIDecoder::HandleDestroyRenderSurface( - uint32 arg_count, - const DestroyRenderSurface& args) { - return gapi_->DestroyRenderSurface(args.render_surface_id); -} - -parse_error::ParseError GAPIDecoder::HandleCreateDepthSurface( - uint32 arg_count, - const CreateDepthSurface& args) { - unsigned int width_height = args.width_height; - unsigned int width = CreateDepthSurface::Width::Get(width_height); - unsigned int height = CreateDepthSurface::Height::Get(width_height); - return gapi_->CreateDepthSurface(args.depth_surface_id, width, height); -} - -parse_error::ParseError GAPIDecoder::HandleDestroyDepthSurface( - uint32 arg_count, - const DestroyDepthSurface& args) { - return gapi_->DestroyDepthSurface(args.depth_surface_id); -} - -parse_error::ParseError GAPIDecoder::HandleSetRenderSurface( - uint32 arg_count, - const SetRenderSurface& args) { - return gapi_->SetRenderSurface(args.render_surface_id, args.depth_surface_id); -} - -parse_error::ParseError GAPIDecoder::HandleSetBackSurfaces( - uint32 arg_count, - const SetBackSurfaces& args) { - gapi_->SetBackSurfaces(); - return parse_error::kParseNoError; -} - -} // namespace o3d -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/service/gapi_decoder.h b/o3d/gpu/command_buffer/service/gapi_decoder.h deleted file mode 100644 index e043598..0000000 --- a/o3d/gpu/command_buffer/service/gapi_decoder.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the GAPI decoder class. - -#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_GAPI_DECODER_H_ -#define GPU_COMMAND_BUFFER_SERVICE_CROSS_GAPI_DECODER_H_ - -#include "gpu/command_buffer/service/common_decoder.h" -#include "gpu/command_buffer/common/o3d_cmd_format.h" - -namespace command_buffer { -namespace o3d { - -class GAPIInterface; - -// This class implements the AsyncAPIInterface interface, decoding GAPI -// commands and sending them to a GAPI interface. -class GAPIDecoder : public CommonDecoder { - public: - typedef parse_error::ParseError ParseError; - - explicit GAPIDecoder(GAPIInterface *gapi) : gapi_(gapi) {} - virtual ~GAPIDecoder() {} - - // Overridden from AsyncAPIInterface. - virtual ParseError DoCommand(unsigned int command, - unsigned int arg_count, - const void* args); - - // Overridden from AsyncAPIInterface. - virtual const char* GetCommandName(unsigned int command_id) const; - - private: - // Generate a member function prototype for each command in an automated and - // typesafe way. - #define GPU_COMMAND_BUFFER_CMD_OP(name) \ - ParseError Handle ## name( \ - unsigned int arg_count, \ - const o3d::name& args); \ - - O3D_COMMAND_BUFFER_CMDS(GPU_COMMAND_BUFFER_CMD_OP) - - #undef GPU_COMMAND_BUFFER_CMD_OP - - GAPIInterface *gapi_; -}; - -} // namespace o3d -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_GAPI_DECODER_H_ diff --git a/o3d/gpu/command_buffer/service/gapi_gl.cc b/o3d/gpu/command_buffer/service/gapi_gl.cc deleted file mode 100644 index c5f82de..0000000 --- a/o3d/gpu/command_buffer/service/gapi_gl.cc +++ /dev/null @@ -1,420 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file implements the GAPIGL class. - -#include "gpu/command_buffer/service/precompile.h" - -#include - -#include "gpu/command_buffer/service/gapi_gl.h" - -#ifdef OS_LINUX -#include "gpu/command_buffer/service/linux/x_utils.h" -#endif // OS_LINUX - -namespace command_buffer { -namespace o3d { - -GAPIGL::GAPIGL() - : cg_context_(NULL), -#ifdef OS_LINUX - window_(NULL), -#endif -#ifdef OS_WIN - hwnd_(NULL), - device_context_(NULL), - gl_context_(NULL), -#endif - anti_aliased_(false), - current_vertex_struct_(kInvalidResource), - validate_streams_(true), - max_vertices_(0), - current_effect_id_(kInvalidResource), - validate_effect_(true), - current_effect_(NULL) { -} - -GAPIGL::~GAPIGL() { -} - -bool GAPIGL::Initialize() { - if (!InitPlatformSpecific()) - return false; - if (!InitCommon()) - return false; - CHECK_GL_ERROR(); - return true; -} - -#if defined(OS_WIN) -static const PIXELFORMATDESCRIPTOR kPixelFormatDescriptor = { - sizeof(kPixelFormatDescriptor), // Size of structure. - 1, // Default version. - PFD_DRAW_TO_WINDOW | // Window drawing support. - PFD_SUPPORT_OPENGL | // OpenGL support. - PFD_DOUBLEBUFFER, // Double buffering support (not stereo). - PFD_TYPE_RGBA, // RGBA color mode (not indexed). - 24, // 24 bit color mode. - 0, 0, 0, 0, 0, 0, // Don't set RGB bits & shifts. - 8, 0, // 8 bit alpha - 0, // No accumulation buffer. - 0, 0, 0, 0, // Ignore accumulation bits. - 24, // 24 bit z-buffer size. - 8, // 8-bit stencil buffer. - 0, // No aux buffer. - PFD_MAIN_PLANE, // Main drawing plane (not overlay). - 0, // Reserved. - 0, 0, 0, // Layer masks ignored. -}; - -LRESULT CALLBACK IntermediateWindowProc(HWND window, - UINT message, - WPARAM w_param, - LPARAM l_param) { - return ::DefWindowProc(window, message, w_param, l_param); -} - -// Helper routine that returns the highest quality pixel format supported on -// the current platform. Returns true upon success. -static bool GetWindowsPixelFormat(HWND window, - bool anti_aliased, - int* pixel_format) { - // We must initialize a GL context before we can determine the multi-sampling - // supported on the current hardware, so we create an intermediate window - // and context here. - HINSTANCE module_handle; - if (!::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | - GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, - reinterpret_cast(IntermediateWindowProc), - &module_handle)) { - return false; - } - - WNDCLASS intermediate_class; - intermediate_class.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; - intermediate_class.lpfnWndProc = IntermediateWindowProc; - intermediate_class.cbClsExtra = 0; - intermediate_class.cbWndExtra = 0; - intermediate_class.hInstance = module_handle; - intermediate_class.hIcon = LoadIcon(NULL, IDI_APPLICATION); - intermediate_class.hCursor = LoadCursor(NULL, IDC_ARROW); - intermediate_class.hbrBackground = NULL; - intermediate_class.lpszMenuName = NULL; - intermediate_class.lpszClassName = L"Intermediate GL Window"; - - ATOM class_registration = ::RegisterClass(&intermediate_class); - if (!class_registration) { - return false; - } - - HWND intermediate_window = ::CreateWindow( - reinterpret_cast(class_registration), - L"", - WS_OVERLAPPEDWINDOW, - 0, 0, - CW_USEDEFAULT, CW_USEDEFAULT, - NULL, - NULL, - NULL, - NULL); - - if (!intermediate_window) { - ::UnregisterClass(reinterpret_cast(class_registration), - module_handle); - return false; - } - - HDC intermediate_dc = ::GetDC(intermediate_window); - int format_index = ::ChoosePixelFormat(intermediate_dc, - &kPixelFormatDescriptor); - if (format_index == 0) { - DLOG(ERROR) << "Unable to get the pixel format for GL context."; - ::ReleaseDC(intermediate_window, intermediate_dc); - ::DestroyWindow(intermediate_window); - ::UnregisterClass(reinterpret_cast(class_registration), - module_handle); - return false; - } - if (!::SetPixelFormat(intermediate_dc, format_index, - &kPixelFormatDescriptor)) { - DLOG(ERROR) << "Unable to set the pixel format for GL context."; - ::ReleaseDC(intermediate_window, intermediate_dc); - ::DestroyWindow(intermediate_window); - ::UnregisterClass(reinterpret_cast(class_registration), - module_handle); - return false; - } - - // Store the pixel format without multisampling. - *pixel_format = format_index; - HGLRC gl_context = ::wglCreateContext(intermediate_dc); - if (::wglMakeCurrent(intermediate_dc, gl_context)) { - // GL context was successfully created and applied to the window's DC. - // Startup GLEW, the GL extensions wrangler. - GLenum glew_error = ::glewInit(); - if (glew_error == GLEW_OK) { - DLOG(INFO) << "Initialized GLEW " << ::glewGetString(GLEW_VERSION); - } else { - DLOG(ERROR) << "Unable to initialise GLEW : " - << ::glewGetErrorString(glew_error); - ::wglMakeCurrent(intermediate_dc, NULL); - ::wglDeleteContext(gl_context); - ::ReleaseDC(intermediate_window, intermediate_dc); - ::DestroyWindow(intermediate_window); - ::UnregisterClass(reinterpret_cast(class_registration), - module_handle); - return false; - } - - // If the multi-sample extensions are present, query the api to determine - // the pixel format. - if (anti_aliased && WGLEW_ARB_pixel_format && WGLEW_ARB_multisample) { - int pixel_attributes[] = { - WGL_SAMPLES_ARB, 4, - WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, - WGL_SUPPORT_OPENGL_ARB, GL_TRUE, - WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, - WGL_COLOR_BITS_ARB, 24, - WGL_ALPHA_BITS_ARB, 8, - WGL_DEPTH_BITS_ARB, 24, - WGL_STENCIL_BITS_ARB, 8, - WGL_DOUBLE_BUFFER_ARB, GL_TRUE, - WGL_SAMPLE_BUFFERS_ARB, GL_TRUE, - 0, 0}; - - float pixel_attributes_f[] = {0, 0}; - int msaa_pixel_format; - unsigned int num_formats; - - // Query for the highest sampling rate supported, starting at 4x. - static const int kSampleCount[] = {4, 2}; - static const int kNumSamples = 2; - for (int sample = 0; sample < kNumSamples; ++sample) { - pixel_attributes[1] = kSampleCount[sample]; - if (GL_TRUE == ::wglChoosePixelFormatARB(intermediate_dc, - pixel_attributes, - pixel_attributes_f, - 1, - &msaa_pixel_format, - &num_formats)) { - *pixel_format = msaa_pixel_format; - break; - } - } - } - } - - ::wglMakeCurrent(intermediate_dc, NULL); - ::wglDeleteContext(gl_context); - ::ReleaseDC(intermediate_window, intermediate_dc); - ::DestroyWindow(intermediate_window); - ::UnregisterClass(reinterpret_cast(class_registration), - module_handle); - return true; -} -#endif - -bool GAPIGL::InitPlatformSpecific() { -#if defined(OS_WIN) - device_context_ = ::GetDC(hwnd_); - - int pixel_format; - - if (!GetWindowsPixelFormat(hwnd_, - anti_aliased(), - &pixel_format)) { - DLOG(ERROR) << "Unable to determine optimal pixel format for GL context."; - return false; - } - - if (!::SetPixelFormat(device_context_, pixel_format, - &kPixelFormatDescriptor)) { - DLOG(ERROR) << "Unable to set the pixel format for GL context."; - return false; - } - - gl_context_ = ::wglCreateContext(device_context_); - if (!gl_context_) { - DLOG(ERROR) << "Failed to create GL context."; - return false; - } - - if (!::wglMakeCurrent(device_context_, gl_context_)) { - DLOG(ERROR) << "Unable to make gl context current."; - return false; - } -#elif defined(OS_LINUX) - DCHECK(window_); - if (!window_->Initialize()) - return false; - if (!window_->MakeCurrent()) - return false; -#endif - - return true; -} - -bool GAPIGL::InitCommon() { - if (!InitGlew()) - return false; - InitCG(); - - // Initialize global GL settings. - // Tell GL that texture buffers can be single-byte aligned. - glPixelStorei(GL_PACK_ALIGNMENT, 1); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); - glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); - // Get the initial viewport (set to the window size) to set up the helper - // constant. - GLint viewport[4]; - glGetIntegerv(GL_VIEWPORT, viewport); - SetViewport(viewport[0], viewport[1], viewport[2], viewport[3], 0.f, 1.f); - CHECK_GL_ERROR(); - - ::glGenFramebuffersEXT(1, &render_surface_framebuffer_); - CHECK_GL_ERROR(); - return true; -} - -void GAPIGL::InitCG() { - cg_context_ = cgCreateContext(); - // Set up all Cg State Assignments for OpenGL. - cgGLRegisterStates(cg_context_); - cgGLSetDebugMode(CG_FALSE); - // Enable the profiles we use. - cgGLEnableProfile(CG_PROFILE_ARBVP1); - cgGLEnableProfile(CG_PROFILE_ARBFP1); -} - -bool GAPIGL::InitGlew() { - DLOG(INFO) << "Initializing GL and GLEW for GAPI."; - - GLenum glew_error = glewInit(); - if (glew_error != GLEW_OK) { - DLOG(ERROR) << "Unable to initialise GLEW : " - << ::glewGetErrorString(glew_error); - return false; - } - - // Check to see that we can use the OpenGL vertex attribute APIs - // TODO(petersont): Return false if this check fails, but because some - // Intel hardware does not support OpenGL 2.0, yet does support all of the - // extensions we require, we only log an error. A future CL should change - // this check to ensure that all of the extension strings we require are - // present. - if (!GLEW_VERSION_2_0) { - DLOG(ERROR) << "GL drivers do not have OpenGL 2.0 functionality."; - } - - bool extensions_found = true; - if (!GLEW_ARB_vertex_buffer_object) { - // NOTE: Linux NVidia drivers claim to support OpenGL 2.0 when using - // indirect rendering (e.g. remote X), but it is actually lying. The - // ARB_vertex_buffer_object functions silently no-op (!) when using - // indirect rendering, leading to crashes. Fortunately, in that case, the - // driver claims to not support ARB_vertex_buffer_object, so fail in that - // case. - DLOG(ERROR) << "GL drivers do not support vertex buffer objects."; - extensions_found = false; - } - if (!GLEW_EXT_framebuffer_object) { - DLOG(ERROR) << "GL drivers do not support framebuffer objects."; - extensions_found = false; - } - // Check for necessary extensions - if (!GLEW_VERSION_2_0 && !GLEW_EXT_stencil_two_side) { - DLOG(ERROR) << "Two sided stencil extension missing."; - extensions_found = false; - } - if (!GLEW_VERSION_1_4 && !GLEW_EXT_blend_func_separate) { - DLOG(ERROR) <<"Separate blend func extension missing."; - extensions_found = false; - } - if (!GLEW_VERSION_2_0 && !GLEW_EXT_blend_equation_separate) { - DLOG(ERROR) << "Separate blend function extension missing."; - extensions_found = false; - } - if (!extensions_found) - return false; - - return true; -} - -void GAPIGL::Destroy() { - vertex_buffers_.DestroyAllResources(); - index_buffers_.DestroyAllResources(); - vertex_structs_.DestroyAllResources(); - effects_.DestroyAllResources(); - effect_params_.DestroyAllResources(); - // textures_.DestroyAllResources(); - // samplers_.DestroyAllResources(); - cgDestroyContext(cg_context_); - cg_context_ = NULL; -#ifdef OS_LINUX - DCHECK(window_); - window_->Destroy(); -#endif -} - -void GAPIGL::BeginFrame() { -} - -void GAPIGL::EndFrame() { -#ifdef OS_WIN - ::SwapBuffers(device_context_); -#endif - -#ifdef OS_LINUX - DCHECK(window_); - window_->SwapBuffers(); -#endif - - CHECK_GL_ERROR(); -} - -void GAPIGL::Clear(unsigned int buffers, - const RGBA &color, - float depth, - unsigned int stencil) { - glClearColor(color.red, color.green, color.blue, color.alpha); - glClearDepth(depth); - glClearStencil(stencil); - glClear((buffers & kColor ? GL_COLOR_BUFFER_BIT : 0) | - (buffers & kDepth ? GL_DEPTH_BUFFER_BIT : 0) | - (buffers & kStencil ? GL_STENCIL_BUFFER_BIT : 0)); - CHECK_GL_ERROR(); -} - -} // namespace o3d -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/service/gapi_gl.h b/o3d/gpu/command_buffer/service/gapi_gl.h deleted file mode 100644 index 0719fba..0000000 --- a/o3d/gpu/command_buffer/service/gapi_gl.h +++ /dev/null @@ -1,465 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the GAPIGL class, implementing the GAPI interface for -// GL. - -#ifndef GPU_COMMAND_BUFFER_SERVICE_GAPI_GL_H_ -#define GPU_COMMAND_BUFFER_SERVICE_GAPI_GL_H_ - -#include -#include -#include -#include -#include "gpu/command_buffer/common/gapi_interface.h" -#include "gpu/command_buffer/service/gl_utils.h" -#include "gpu/command_buffer/service/effect_gl.h" -#include "gpu/command_buffer/service/geometry_gl.h" -#include "gpu/command_buffer/service/render_surface_gl.h" -#include "gpu/command_buffer/service/sampler_gl.h" -#include "gpu/command_buffer/service/texture_gl.h" - -namespace command_buffer { -namespace o3d { -#if defined(OS_LINUX) -class XWindowWrapper; -#endif // defined(OS_LINUX) - -// This class implements the GAPI interface for GL. -class GAPIGL : public GAPIInterface { - public: - GAPIGL(); - virtual ~GAPIGL(); - -#if defined(OS_LINUX) - void set_window_wrapper(XWindowWrapper *window) { window_ = window; } -#elif defined(OS_WIN) - void set_hwnd(HWND hwnd) { hwnd_ = hwnd; } - - HWND hwnd() const { - return hwnd_; - } -#endif - - // Initializes the graphics context, bound to a window. - // Returns: - // true if successful. - virtual bool Initialize(); - - // Initailizes Cg. - void InitCG(); - - // Helper function for Initailize that inits just glew. - bool InitGlew(); - - // Destroys the graphics context. - virtual void Destroy(); - - // Implements the BeginFrame function for GL. - virtual void BeginFrame(); - - // Implements the EndFrame function for GL. - virtual void EndFrame(); - - // Implements the Clear function for GL. - virtual void Clear(unsigned int buffers, - const RGBA &color, - float depth, - unsigned int stencil); - - // Implements the SetViewport function for GL. - virtual void SetViewport(unsigned int x, - unsigned int y, - unsigned int width, - unsigned int height, - float z_min, - float z_max); - - // Implements the CreateVertexBuffer function for GL. - virtual ParseError CreateVertexBuffer(ResourceId id, - unsigned int size, - unsigned int flags); - - // Implements the DestroyVertexBuffer function for GL. - virtual ParseError DestroyVertexBuffer(ResourceId id); - - // Implements the SetVertexBufferData function for GL. - virtual ParseError SetVertexBufferData(ResourceId id, - unsigned int offset, - unsigned int size, - const void *data); - - // Implements the GetVertexBufferData function for GL. - virtual ParseError GetVertexBufferData(ResourceId id, - unsigned int offset, - unsigned int size, - void *data); - - // Implements the CreateIndexBuffer function for GL. - virtual ParseError CreateIndexBuffer(ResourceId id, - unsigned int size, - unsigned int flags); - - // Implements the DestroyIndexBuffer function for GL. - virtual ParseError DestroyIndexBuffer(ResourceId id); - - // Implements the SetIndexBufferData function for GL. - virtual ParseError SetIndexBufferData(ResourceId id, - unsigned int offset, - unsigned int size, - const void *data); - - // Implements the GetIndexBufferData function for GL. - virtual ParseError GetIndexBufferData(ResourceId id, - unsigned int offset, - unsigned int size, - void *data); - - // Implements the CreateVertexStruct function for GL. - virtual ParseError CreateVertexStruct(ResourceId id, - unsigned int input_count); - - // Implements the DestroyVertexStruct function for GL. - virtual ParseError DestroyVertexStruct(ResourceId id); - - // Implements the SetVertexInput function for GL. - virtual ParseError SetVertexInput(ResourceId vertex_struct_id, - unsigned int input_index, - ResourceId vertex_buffer_id, - unsigned int offset, - unsigned int stride, - vertex_struct::Type type, - vertex_struct::Semantic semantic, - unsigned int semantic_index); - - // Implements the SetVertexStruct function for GL. - virtual ParseError SetVertexStruct(ResourceId id); - - // Implements the Draw function for GL. - virtual ParseError Draw(PrimitiveType primitive_type, - unsigned int first, - unsigned int count); - - // Implements the DrawIndexed function for GL. - virtual ParseError DrawIndexed(PrimitiveType primitive_type, - ResourceId index_buffer_id, - unsigned int first, - unsigned int count, - unsigned int min_index, - unsigned int max_index); - - // Implements the CreateEffect function for GL. - virtual ParseError CreateEffect(ResourceId id, - unsigned int size, - const void *data); - - // Implements the DestroyEffect function for GL. - virtual ParseError DestroyEffect(ResourceId id); - - // Implements the SetEffect function for GL. - virtual ParseError SetEffect(ResourceId id); - - // Implements the GetParamCount function for GL. - virtual ParseError GetParamCount(ResourceId id, - unsigned int size, - void *data); - - // Implements the CreateParam function for GL. - virtual ParseError CreateParam(ResourceId param_id, - ResourceId effect_id, - unsigned int index); - - // Implements the CreateParamByName function for GL. - virtual ParseError CreateParamByName(ResourceId param_id, - ResourceId effect_id, - unsigned int size, - const void *name); - - // Implements the DestroyParam function for GL. - virtual ParseError DestroyParam(ResourceId id); - - // Implements the SetParamData function for GL. - virtual ParseError SetParamData(ResourceId id, - unsigned int size, - const void *data); - - // Implements the GetParamDesc function for GL. - virtual ParseError GetParamDesc(ResourceId id, - unsigned int size, - void *data); - - // Implements the GetStreamCount function for GL. - virtual ParseError GetStreamCount(ResourceId id, - unsigned int size, - void *data); - - // Implements the GetStreamDesc function for GL. - virtual ParseError GetStreamDesc(ResourceId id, - unsigned int index, - unsigned int size, - void *data); - - // Implements the CreateTexture2D function for GL. - virtual ParseError CreateTexture2D(ResourceId id, - unsigned int width, - unsigned int height, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces); - - // Implements the CreateTexture3D function for GL. - virtual ParseError CreateTexture3D(ResourceId id, - unsigned int width, - unsigned int height, - unsigned int depth, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces); - - // Implements the CreateTextureCube function for GL. - virtual ParseError CreateTextureCube(ResourceId id, - unsigned int side, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces); - - // Implements the SetTextureData function for GL. - virtual ParseError SetTextureData(ResourceId id, - unsigned int x, - unsigned int y, - unsigned int z, - unsigned int width, - unsigned int height, - unsigned int depth, - unsigned int level, - texture::Face face, - unsigned int pitch, - unsigned int slice_pitch, - unsigned int size, - const void *data); - - // Implements the GetTextureData function for GL. - virtual ParseError GetTextureData(ResourceId id, - unsigned int x, - unsigned int y, - unsigned int z, - unsigned int width, - unsigned int height, - unsigned int depth, - unsigned int level, - texture::Face face, - unsigned int pitch, - unsigned int slice_pitch, - unsigned int size, - void *data); - - // Implements the DestroyTexture function for GL. - virtual ParseError DestroyTexture(ResourceId id); - - // Implements the CreateSampler function for GL. - virtual ParseError CreateSampler(ResourceId id); - - // Implements the DestroySampler function for GL. - virtual ParseError DestroySampler(ResourceId id); - - // Implements the SetSamplerStates function for GL. - virtual ParseError SetSamplerStates(ResourceId id, - sampler::AddressingMode addressing_u, - sampler::AddressingMode addressing_v, - sampler::AddressingMode addressing_w, - sampler::FilteringMode mag_filter, - sampler::FilteringMode min_filter, - sampler::FilteringMode mip_filter, - unsigned int max_anisotropy); - - // Implements the SetSamplerBorderColor function for GL. - virtual ParseError SetSamplerBorderColor(ResourceId id, const RGBA &color); - - // Implements the SetSamplerTexture function for GL. - virtual ParseError SetSamplerTexture(ResourceId id, ResourceId texture_id); - - // Implements the SetScissor function for GL. - virtual void SetScissor(bool enable, - unsigned int x, - unsigned int y, - unsigned int width, - unsigned int height); - - // Implements the SetPointLineRaster function for GL. - virtual void SetPointLineRaster(bool line_smooth, - bool point_sprite, - float point_size); - - // Implements the SetPolygonOffset function for GL. - virtual void SetPolygonOffset(float slope_factor, float units); - - // Implements the SetPolygonRaster function for GL. - virtual void SetPolygonRaster(PolygonMode fill_mode, - FaceCullMode cull_mode); - - // Implements the SetAlphaTest function for GL. - virtual void SetAlphaTest(bool enable, - float reference, - Comparison comp); - - // Implements the SetDepthTest function for GL. - virtual void SetDepthTest(bool enable, - bool write_enable, - Comparison comp); - - // Implements the SetStencilTest function for GL. - virtual void SetStencilTest(bool enable, - bool separate_ccw, - unsigned int write_mask, - unsigned int compare_mask, - unsigned int ref, - Uint32 func_ops); - - // Implements the SetColorWritefunction for GL. - virtual void SetColorWrite(bool red, - bool green, - bool blue, - bool alpha, - bool dither); - - // Implements the SetBlending function for GL. - virtual void SetBlending(bool enable, - bool separate_alpha, - BlendEq color_eq, - BlendFunc color_src_func, - BlendFunc color_dst_func, - BlendEq alpha_eq, - BlendFunc alpha_src_func, - BlendFunc alpha_dst_func); - - // Implements the SetBlendingColor function for GL. - virtual void SetBlendingColor(const RGBA &color); - - // Implements the CreateRenderSurface function for GL. - virtual ParseError CreateRenderSurface(ResourceId id, - unsigned int width, - unsigned int height, - unsigned int mip_level, - unsigned int side, - ResourceId texture_id); - - // Implements the DestroyRenderSurface function for GL. - virtual ParseError DestroyRenderSurface(ResourceId id); - - // Implements the CreateDepthSurface function for GL. - virtual ParseError CreateDepthSurface(ResourceId id, - unsigned int width, - unsigned int height); - - // Implements the DestroyDepthSurface function for GL. - virtual ParseError DestroyDepthSurface(ResourceId id); - - // Implements the SetRenderSurface function for GL. - virtual ParseError SetRenderSurface(ResourceId render_surface_id, - ResourceId depth_stencil_id); - - // Implements the SetBackSurfaces function for GL. - virtual void SetBackSurfaces(); - - // Gets a vertex buffer by resource ID. - VertexBufferGL *GetVertexBuffer(ResourceId id) { - return vertex_buffers_.Get(id); - } - - // Gets a texture by resource ID. - TextureGL *GetTexture(ResourceId id) { - return textures_.Get(id); - } - - // Gets a sampler by resource ID. - SamplerGL *GetSampler(ResourceId id) { - return samplers_.Get(id); - } - void set_anti_aliased(bool anti_aliased) { anti_aliased_ = anti_aliased; } - - bool anti_aliased() const { return anti_aliased_; } - - CGcontext cg_context() const { return cg_context_; } - - EffectGL *current_effect() const { return current_effect_; } - // "Dirty" the current effect. This resets the vertex and fragment program, - // and requires ValidateEffect() to be called before further draws occur. - void DirtyEffect(); - private: - bool InitPlatformSpecific(); - bool InitCommon(); - // Validates the current vertex struct to GL, setting the vertex attributes. - bool ValidateStreams(); - // Validates the current effect to GL. This sets the vertex and fragment - // programs, and updates parameters if needed. - bool ValidateEffect(); - - CGcontext cg_context_; - -#if defined(OS_LINUX) - XWindowWrapper *window_; -#elif defined(OS_WIN) - // Handle to the GL device. - HWND hwnd_; - HDC device_context_; - HGLRC gl_context_; -#endif - - bool anti_aliased_; - ResourceId current_vertex_struct_; - bool validate_streams_; - unsigned int max_vertices_; - ResourceId current_effect_id_; - bool validate_effect_; - EffectGL *current_effect_; - ResourceId current_surface_id_; - ResourceId current_depth_surface_id_; - GLuint render_surface_framebuffer_; - - ResourceMap vertex_buffers_; - ResourceMap index_buffers_; - ResourceMap vertex_structs_; - ResourceMap effects_; - ResourceMap effect_params_; - ResourceMap textures_; - ResourceMap samplers_; - ResourceMap render_surfaces_; - ResourceMap depth_surfaces_; -}; - -} // namespace o3d -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_SERVICE_GAPI_GL_H_ diff --git a/o3d/gpu/command_buffer/service/geometry_d3d9.cc b/o3d/gpu/command_buffer/service/geometry_d3d9.cc deleted file mode 100644 index c3b5eb5..0000000 --- a/o3d/gpu/command_buffer/service/geometry_d3d9.cc +++ /dev/null @@ -1,439 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the implementation of the D3D9 versions of the -// VertexBuffer, IndexBuffer and VertexStruct resources. -// This file also contains the related GAPID3D9 function implementations. - -#include "gpu/command_buffer/service/precompile.h" - -#include - -#include "gpu/command_buffer/service/d3d9_utils.h" -#include "gpu/command_buffer/service/geometry_d3d9.h" -#include "gpu/command_buffer/service/gapi_d3d9.h" - -namespace command_buffer { -namespace o3d { - -// Destroys the D3D9 vertex buffer. -VertexBufferD3D9::~VertexBufferD3D9() { - DCHECK(d3d_vertex_buffer_ != NULL); - if (d3d_vertex_buffer_) { - d3d_vertex_buffer_->Release(); - d3d_vertex_buffer_ = NULL; - } -} - -// Creates a D3D9 vertex buffer. -void VertexBufferD3D9::Create(GAPID3D9 *gapi) { - DCHECK(d3d_vertex_buffer_ == NULL); - - DWORD d3d_usage = (flags() & vertex_buffer::kDynamic) ? D3DUSAGE_DYNAMIC : 0; - D3DPOOL d3d_pool = D3DPOOL_MANAGED; - HR(gapi->d3d_device()->CreateVertexBuffer(size(), d3d_usage, 0, d3d_pool, - &d3d_vertex_buffer_, NULL)); -} - -// Sets the data into the D3D9 vertex buffer, using Lock() and memcpy. -bool VertexBufferD3D9::SetData(unsigned int offset, - unsigned int size, - const void *data) { - if (!d3d_vertex_buffer_) { - LOG(ERROR) << "Calling SetData on a non-initialized VertexBufferD3D9."; - return false; - } - if ((offset >= this->size()) || (offset + size > this->size())) { - LOG(ERROR) << "Invalid size or offset on VertexBufferD3D9::SetData."; - return false; - } - void *ptr = NULL; - DWORD lock_flags = 0; - // If we are setting the full buffer, discard the old data. That's only - // possible to do for a dynamic d3d vertex buffer. - if ((offset == 0) && (size == this->size()) && - (flags() & vertex_buffer::kDynamic)) - lock_flags = D3DLOCK_DISCARD; - HR(d3d_vertex_buffer_->Lock(offset, size, &ptr, lock_flags)); - memcpy(ptr, data, size); - HR(d3d_vertex_buffer_->Unlock()); - return true; -} - -// Gets the data from the D3D9 vertex buffer, using Lock() and memcpy. -bool VertexBufferD3D9::GetData(unsigned int offset, - unsigned int size, - void *data) { - if (!d3d_vertex_buffer_) { - LOG(ERROR) << "Calling SetData on a non-initialized VertexBufferD3D9."; - return false; - } - if ((offset >= this->size()) || (offset + size > this->size())) { - LOG(ERROR) << "Invalid size or offset on VertexBufferD3D9::SetData."; - return false; - } - void *ptr = NULL; - DWORD lock_flags = D3DLOCK_READONLY; - HR(d3d_vertex_buffer_->Lock(offset, size, &ptr, lock_flags)); - memcpy(data, ptr, size); - HR(d3d_vertex_buffer_->Unlock()); - return true; -} - -// Destroys the D3D9 index buffer. -IndexBufferD3D9::~IndexBufferD3D9() { - DCHECK(d3d_index_buffer_ != NULL); - if (d3d_index_buffer_) { - d3d_index_buffer_->Release(); - d3d_index_buffer_ = NULL; - } -} - -// Creates a D3D9 index buffer. -void IndexBufferD3D9::Create(GAPID3D9 *gapi) { - DCHECK(d3d_index_buffer_ == NULL); - - DWORD d3d_usage = (flags() & index_buffer::kDynamic) ? D3DUSAGE_DYNAMIC : 0; - D3DFORMAT d3d_format = - (flags() & index_buffer::kIndex32Bit) ? D3DFMT_INDEX32 : D3DFMT_INDEX16; - D3DPOOL d3d_pool = D3DPOOL_MANAGED; - HR(gapi->d3d_device()->CreateIndexBuffer(size(), d3d_usage, d3d_format, - d3d_pool, &d3d_index_buffer_, - NULL)); -} - -// Sets the data into the D3D9 index buffer, using Lock() and memcpy. -bool IndexBufferD3D9::SetData(unsigned int offset, - unsigned int size, - const void *data) { - if (!d3d_index_buffer_) { - LOG(ERROR) << "Calling SetData on a non-initialized IndexBufferD3D9."; - return false; - } - if ((offset >= this->size()) || (offset + size > this->size())) { - LOG(ERROR) << "Invalid size or offset on IndexBufferD3D9::SetData."; - return false; - } - void *ptr = NULL; - DWORD lock_flags = 0; - // If we are setting the full buffer, discard the old data. That's only - // possible to do for a dynamic d3d index buffer. - if ((offset == 0) && (size == this->size()) && - (flags() & index_buffer::kDynamic)) - lock_flags = D3DLOCK_DISCARD; - HR(d3d_index_buffer_->Lock(offset, size, &ptr, lock_flags)); - memcpy(ptr, data, size); - HR(d3d_index_buffer_->Unlock()); - return true; -} - -// Gets the data from the D3D9 index buffer, using Lock() and memcpy. -bool IndexBufferD3D9::GetData(unsigned int offset, - unsigned int size, - void *data) { - if (!d3d_index_buffer_) { - LOG(ERROR) << "Calling SetData on a non-initialized IndexBufferD3D9."; - return false; - } - if ((offset >= this->size()) || (offset + size > this->size())) { - LOG(ERROR) << "Invalid size or offset on IndexBufferD3D9::SetData."; - return false; - } - void *ptr = NULL; - DWORD lock_flags = D3DLOCK_READONLY; - HR(d3d_index_buffer_->Lock(offset, size, &ptr, lock_flags)); - memcpy(data, ptr, size); - HR(d3d_index_buffer_->Unlock()); - return true; -} - -// Sets the input element in the VertexStruct resource. -void VertexStructD3D9::SetInput(unsigned int input_index, - ResourceId vertex_buffer_id, - unsigned int offset, - unsigned int stride, - vertex_struct::Type type, - vertex_struct::Semantic semantic, - unsigned int semantic_index) { - Element &element = GetElement(input_index); - element.vertex_buffer = vertex_buffer_id; - element.offset = offset; - element.stride = stride; - element.type = type; - element.semantic = semantic; - element.semantic_index = semantic_index; - dirty_ = true; -} - -// Sets the vdecl and stream sources in D3D9. Compiles them if needed. -unsigned int VertexStructD3D9::SetStreams(GAPID3D9 *gapi) { - IDirect3DDevice9 *d3d_device = gapi->d3d_device(); - if (dirty_) Compile(d3d_device); - HR(d3d_device->SetVertexDeclaration(d3d_vertex_decl_)); - unsigned int max_vertices = UINT_MAX; - for (unsigned int i = 0; i < streams_.size(); ++i) { - const StreamPair &pair = streams_[i]; - VertexBufferD3D9 *vertex_buffer = gapi->GetVertexBuffer(pair.first); - if (!vertex_buffer) { - max_vertices = 0; - continue; - } - HR(d3d_device->SetStreamSource(i, vertex_buffer->d3d_vertex_buffer(), 0, - pair.second)); - - // TODO(apatrick): A zero size stride is valid. It means the first element - // in the vertex buffer will be used for every vertex. There doesn't seem - // to be enough information here to determine whether a zero stride - // vertex buffer is big enough to contain a single element. - if (pair.second != 0) { - max_vertices = std::min(max_vertices, - vertex_buffer->size() / pair.second); - } - } - return max_vertices; -} - -// Converts a vertex_struct::Type to a D3DDECLTYPE. -static D3DDECLTYPE D3DType(vertex_struct::Type type) { - switch (type) { - case vertex_struct::kFloat1: - return D3DDECLTYPE_FLOAT1; - case vertex_struct::kFloat2: - return D3DDECLTYPE_FLOAT2; - case vertex_struct::kFloat3: - return D3DDECLTYPE_FLOAT3; - case vertex_struct::kFloat4: - return D3DDECLTYPE_FLOAT4; - case vertex_struct::kUChar4N: - return D3DDECLTYPE_UBYTE4N; - case vertex_struct::kNumTypes: - break; - } - LOG(FATAL) << "Invalid type"; - return D3DDECLTYPE_FLOAT1; -} - -// Converts a vertex_struct::Semantic to a D3DDECLUSAGE. -static D3DDECLUSAGE D3DUsage(vertex_struct::Semantic semantic) { - switch (semantic) { - case vertex_struct::kPosition: - return D3DDECLUSAGE_POSITION; - case vertex_struct::kNormal: - return D3DDECLUSAGE_NORMAL; - case vertex_struct::kColor: - return D3DDECLUSAGE_COLOR; - case vertex_struct::kTexCoord: - return D3DDECLUSAGE_TEXCOORD; - case vertex_struct::kNumSemantics: - break; - } - LOG(FATAL) << "Invalid type"; - return D3DDECLUSAGE_POSITION; -} - -// Destroys the d3d vertex declaration. -VertexStructD3D9::~VertexStructD3D9() { - Destroy(); -} - -void VertexStructD3D9::Destroy() { - if (d3d_vertex_decl_) { - d3d_vertex_decl_->Release(); - d3d_vertex_decl_ = NULL; - } - streams_.clear(); -} - -// Compiles a stream map and a d3d vertex declaration from the list of inputs. -// 2 inputs that use the same vertex buffer and stride will use the same -// d3d stream. -void VertexStructD3D9::Compile(IDirect3DDevice9 *d3d_device) { - DCHECK(dirty_); - Destroy(); - streams_.reserve(count_); - scoped_array d3d_elements( - new D3DVERTEXELEMENT9[count_ + 1]); - memset(d3d_elements.get(), 0, sizeof(D3DVERTEXELEMENT9) * (count_ + 1)); - // build streams_ like a set, but the order matters. - for (unsigned int i = 0; i < count_ ; ++i) { - Element &element = GetElement(i); - D3DVERTEXELEMENT9 &d3d_element = d3d_elements[i]; - StreamPair pair(element.vertex_buffer, element.stride); - std::vector::iterator it = - std::find(streams_.begin(), streams_.end(), pair); - unsigned int stream_index = 0; - if (it == streams_.end()) { - streams_.push_back(pair); - stream_index = static_cast(streams_.size() - 1); - } else { - stream_index = it - streams_.begin(); - } - d3d_element.Stream = stream_index; - d3d_element.Offset = element.offset; - d3d_element.Type = D3DType(element.type); - d3d_element.Usage = D3DUsage(element.semantic); - d3d_element.UsageIndex = element.semantic_index; - } - D3DVERTEXELEMENT9 &end = d3d_elements[count_]; - end.Stream = 0xFF; - end.Type = D3DDECLTYPE_UNUSED; - HR(d3d_device->CreateVertexDeclaration(d3d_elements.get(), - &d3d_vertex_decl_)); - dirty_ = false; -} - -// Creates and assigns a VertexBufferD3D9 resource. -parse_error::ParseError GAPID3D9::CreateVertexBuffer( - ResourceId id, - unsigned int size, - unsigned int flags) { - VertexBufferD3D9 *vertex_buffer = new VertexBufferD3D9(size, flags); - vertex_buffer->Create(this); - vertex_buffers_.Assign(id, vertex_buffer); - return parse_error::kParseNoError; -} - -// Destroys a VertexBufferD3D9 resource. -parse_error::ParseError GAPID3D9::DestroyVertexBuffer(ResourceId id) { - return vertex_buffers_.Destroy(id) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -// Copies the data into the VertexBufferD3D9 resource. -parse_error::ParseError GAPID3D9::SetVertexBufferData( - ResourceId id, - unsigned int offset, - unsigned int size, - const void *data) { - VertexBufferD3D9 *vertex_buffer = vertex_buffers_.Get(id); - if (!vertex_buffer) return parse_error::kParseInvalidArguments; - return vertex_buffer->SetData(offset, size, data) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -// Copies the data from the VertexBufferD3D9 resource. -parse_error::ParseError GAPID3D9::GetVertexBufferData( - ResourceId id, - unsigned int offset, - unsigned int size, - void *data) { - VertexBufferD3D9 *vertex_buffer = vertex_buffers_.Get(id); - if (!vertex_buffer) return parse_error::kParseInvalidArguments; - return vertex_buffer->GetData(offset, size, data) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -// Creates and assigns an IndexBufferD3D9 resource. -parse_error::ParseError GAPID3D9::CreateIndexBuffer( - ResourceId id, - unsigned int size, - unsigned int flags) { - IndexBufferD3D9 *index_buffer = new IndexBufferD3D9(size, flags); - index_buffer->Create(this); - index_buffers_.Assign(id, index_buffer); - return parse_error::kParseNoError; -} - -// Destroys an IndexBufferD3D9 resource. -parse_error::ParseError GAPID3D9::DestroyIndexBuffer(ResourceId id) { - return index_buffers_.Destroy(id) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -// Copies the data into the IndexBufferD3D9 resource. -parse_error::ParseError GAPID3D9::SetIndexBufferData( - ResourceId id, - unsigned int offset, - unsigned int size, - const void *data) { - IndexBufferD3D9 *index_buffer = index_buffers_.Get(id); - if (!index_buffer) return parse_error::kParseInvalidArguments; - return index_buffer->SetData(offset, size, data) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -// Copies the data from the IndexBufferD3D9 resource. -parse_error::ParseError GAPID3D9::GetIndexBufferData( - ResourceId id, - unsigned int offset, - unsigned int size, - void *data) { - IndexBufferD3D9 *index_buffer = index_buffers_.Get(id); - if (!index_buffer) return parse_error::kParseInvalidArguments; - return index_buffer->GetData(offset, size, data) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -// Creates and assigns a VertexStructD3D9 resource. -parse_error::ParseError GAPID3D9::CreateVertexStruct( - ResourceId id, unsigned int input_count) { - if (id == current_vertex_struct_) validate_streams_ = true; - VertexStructD3D9 *vertex_struct = new VertexStructD3D9(input_count); - vertex_structs_.Assign(id, vertex_struct); - return parse_error::kParseNoError; -} - -// Destroys a VertexStructD3D9 resource. -parse_error::ParseError GAPID3D9::DestroyVertexStruct(ResourceId id) { - if (id == current_vertex_struct_) validate_streams_ = true; - return vertex_structs_.Destroy(id) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -// Sets an input into a VertexStructD3D9 resource. -parse_error::ParseError GAPID3D9::SetVertexInput( - ResourceId vertex_struct_id, - unsigned int input_index, - ResourceId vertex_buffer_id, - unsigned int offset, - unsigned int stride, - vertex_struct::Type type, - vertex_struct::Semantic semantic, - unsigned int semantic_index) { - if (vertex_buffer_id == current_vertex_struct_) validate_streams_ = true; - VertexStructD3D9 *vertex_struct = vertex_structs_.Get(vertex_struct_id); - if (!vertex_struct || input_index >= vertex_struct->count()) - return parse_error::kParseInvalidArguments; - vertex_struct->SetInput(input_index, vertex_buffer_id, offset, stride, type, - semantic, semantic_index); - return parse_error::kParseNoError; -} - -} // namespace o3d -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/service/geometry_d3d9.h b/o3d/gpu/command_buffer/service/geometry_d3d9.h deleted file mode 100644 index 50f534d..0000000 --- a/o3d/gpu/command_buffer/service/geometry_d3d9.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the definition of the D3D9 versions of geometry-related -// resource classes. - -#ifndef GPU_COMMAND_BUFFER_SERVICE_GEOMETRY_D3D9_H_ -#define GPU_COMMAND_BUFFER_SERVICE_GEOMETRY_D3D9_H_ - -#include -#include -#include "gpu/command_buffer/common/gapi_interface.h" -#include "gpu/command_buffer/service/d3d9_utils.h" -#include "gpu/command_buffer/service/resource.h" - -namespace command_buffer { -namespace o3d { - -class GAPID3D9; - -// D3D9 version of VertexBuffer. -class VertexBufferD3D9 : public VertexBuffer { - public: - VertexBufferD3D9(unsigned int size, unsigned int flags) - : VertexBuffer(size, flags), - d3d_vertex_buffer_(NULL) {} - virtual ~VertexBufferD3D9(); - // Creates the D3D vertex buffer. - void Create(GAPID3D9 *gapi); - // Sets the data into the D3D vertex buffer. - bool SetData(unsigned int offset, unsigned int size, const void *data); - // Gets the data from the D3D vertex buffer. - bool GetData(unsigned int offset, unsigned int size, void *data); - - // Gets the D3D vertex buffer. - IDirect3DVertexBuffer9 * d3d_vertex_buffer() { return d3d_vertex_buffer_; } - private: - IDirect3DVertexBuffer9 *d3d_vertex_buffer_; - DISALLOW_COPY_AND_ASSIGN(VertexBufferD3D9); -}; - -// D3D9 version of IndexBuffer. -class IndexBufferD3D9 : public IndexBuffer { - public: - IndexBufferD3D9(unsigned int size, unsigned int flags) - : IndexBuffer(size, flags), - d3d_index_buffer_(NULL) {} - virtual ~IndexBufferD3D9(); - // Creates the D3D index buffer. - void Create(GAPID3D9 *gapi); - // Sets the data into the D3D index buffer. - bool SetData(unsigned int offset, unsigned int size, const void *data); - // Gets the data from the D3D index buffer. - bool GetData(unsigned int offset, unsigned int size, void *data); - - // Gets the D3D index buffer. - IDirect3DIndexBuffer9 *d3d_index_buffer() const { return d3d_index_buffer_; } - private: - IDirect3DIndexBuffer9 *d3d_index_buffer_; - DISALLOW_COPY_AND_ASSIGN(IndexBufferD3D9); -}; - -// D3D9 version of VertexStruct. -class VertexStructD3D9 : public VertexStruct { - public: - explicit VertexStructD3D9(unsigned int count) - : VertexStruct(count), - dirty_(true), - d3d_vertex_decl_(NULL) {} - virtual ~VertexStructD3D9(); - // Adds an input to the vertex struct. - void SetInput(unsigned int input_index, - ResourceId vertex_buffer_id, - unsigned int offset, - unsigned int stride, - vertex_struct::Type type, - vertex_struct::Semantic semantic, - unsigned int semantic_index); - // Sets the input streams to D3D. - unsigned int SetStreams(GAPID3D9 *gapi); - private: - // Destroys the vertex declaration and stream map. - void Destroy(); - // Compiles the vertex declaration and stream map. - void Compile(IDirect3DDevice9 *d3d_device); - - bool dirty_; - typedef std::pair StreamPair; - std::vector streams_; - IDirect3DVertexDeclaration9 *d3d_vertex_decl_; - DISALLOW_COPY_AND_ASSIGN(VertexStructD3D9); -}; - -} // namespace o3d -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_SERVICE_GEOMETRY_D3D9_H_ diff --git a/o3d/gpu/command_buffer/service/geometry_gl.cc b/o3d/gpu/command_buffer/service/geometry_gl.cc deleted file mode 100644 index 13390a9..0000000 --- a/o3d/gpu/command_buffer/service/geometry_gl.cc +++ /dev/null @@ -1,554 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the implementation of the VertexBufferGL, IndexBufferGL -// and VertexStructGL classes, as well as the geometry-related GAPI functions. - -#include "gpu/command_buffer/service/precompile.h" -#include "gpu/command_buffer/service/gapi_gl.h" -#include "gpu/command_buffer/service/geometry_gl.h" - -namespace command_buffer { -namespace o3d { - -VertexBufferGL::~VertexBufferGL() { - glDeleteBuffers(1, &gl_buffer_); - CHECK_GL_ERROR(); -} - -// Creates the GL buffer object. -void VertexBufferGL::Create() { - glGenBuffers(1, &gl_buffer_); - glBindBuffer(GL_ARRAY_BUFFER, gl_buffer_); - GLenum usage = - (flags() & vertex_buffer::kDynamic) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW; - glBufferData(GL_ARRAY_BUFFER, size(), NULL, usage); - CHECK_GL_ERROR(); -} - -// Sets the data into the GL buffer object. -bool VertexBufferGL::SetData(unsigned int offset, - unsigned int size, - const void *data) { - if (!gl_buffer_) { - LOG(ERROR) << "Calling SetData on a non-initialized VertexBufferGL."; - return false; - } - if ((offset >= this->size()) || (offset + size > this->size())) { - LOG(ERROR) << "Invalid size or offset on VertexBufferGL::SetData."; - return false; - } - glBindBuffer(GL_ARRAY_BUFFER, gl_buffer_); - glBufferSubData(GL_ARRAY_BUFFER, offset, size, data); - CHECK_GL_ERROR(); - return true; -} - -// Gets the data from the GL buffer object. -bool VertexBufferGL::GetData(unsigned int offset, - unsigned int size, - void *data) { - if (!gl_buffer_) { - LOG(ERROR) << "Calling GetData on a non-initialized VertexBufferGL."; - return false; - } - if ((offset >= this->size()) || (offset + size > this->size())) { - LOG(ERROR) << "Invalid size or offset on VertexBufferGL::GetData."; - return false; - } - glBindBuffer(GL_ARRAY_BUFFER, gl_buffer_); - glGetBufferSubData(GL_ARRAY_BUFFER, offset, size, data); - CHECK_GL_ERROR(); - return true; -} - -IndexBufferGL::~IndexBufferGL() { - glDeleteBuffers(1, &gl_buffer_); -} - -// Creates the GL buffer object. -void IndexBufferGL::Create() { - glGenBuffers(1, &gl_buffer_); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl_buffer_); - GLenum usage = - (flags() & vertex_buffer::kDynamic) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW; - glBufferData(GL_ELEMENT_ARRAY_BUFFER, size(), NULL, usage); - CHECK_GL_ERROR(); -} - -// Sets the data into the GL buffer object. -bool IndexBufferGL::SetData(unsigned int offset, - unsigned int size, - const void *data) { - if (!gl_buffer_) { - LOG(ERROR) << "Calling SetData on a non-initialized IndexBufferGL."; - return false; - } - if ((offset >= this->size()) || (offset + size > this->size())) { - LOG(ERROR) << "Invalid size or offset on IndexBufferGL::SetData."; - return false; - } - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl_buffer_); - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, size, data); - CHECK_GL_ERROR(); - return true; -} - -// Gets the data from the GL buffer object. -bool IndexBufferGL::GetData(unsigned int offset, - unsigned int size, - void *data) { - if (!gl_buffer_) { - LOG(ERROR) << "Calling GetData on a non-initialized IndexBufferGL."; - return false; - } - if ((offset >= this->size()) || (offset + size > this->size())) { - LOG(ERROR) << "Invalid size or offset on IndexBufferGL::GetData."; - return false; - } - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl_buffer_); - glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, size, data); - CHECK_GL_ERROR(); - return true; -} - -// Sets the input element in the VertexStruct resource. -void VertexStructGL::SetInput(unsigned int input_index, - ResourceId vertex_buffer_id, - unsigned int offset, - unsigned int stride, - vertex_struct::Type type, - vertex_struct::Semantic semantic, - unsigned int semantic_index) { - Element &element = GetElement(input_index); - element.vertex_buffer = vertex_buffer_id; - element.offset = offset; - element.stride = stride; - element.type = type; - element.semantic = semantic; - element.semantic_index = semantic_index; - dirty_ = true; -} - -namespace { - -inline ptrdiff_t OffsetToPtrDiff(unsigned int offset) { - return static_cast(offset); -} - -inline void* OffsetToPtr(ptrdiff_t offset) { - return reinterpret_cast(offset); -} - -} // anonymous namespace - -unsigned int VertexStructGL::SetStreams(GAPIGL *gapi) { - if (dirty_) Compile(); - unsigned int max_vertices = UINT_MAX; - for (unsigned int i = 0; i < kMaxAttribs; ++i) { - const AttribDesc &attrib = attribs_[i]; - if (attrib.vertex_buffer_id == kInvalidResource) { - if (i == 0) { - glDisableClientState(GL_VERTEX_ARRAY); - } else { - glDisableVertexAttribArray(i); - } - } else { - glEnableVertexAttribArray(i); - VertexBufferGL *vertex_buffer = - gapi->GetVertexBuffer(attrib.vertex_buffer_id); - if (!vertex_buffer) { - glDisableVertexAttribArray(i); - max_vertices = 0; - continue; - } - DCHECK_NE(vertex_buffer->gl_buffer(), 0); - glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer->gl_buffer()); - glVertexAttribPointer(i, attrib.size, attrib.type, attrib.normalized, - attrib.stride, - OffsetToPtr(attrib.offset)); - max_vertices = std::min(max_vertices, - vertex_buffer->size() / attrib.stride); - } - } - CHECK_GL_ERROR(); - return max_vertices; -} - -namespace { - -// from the ARB_vertex_program extension, at -// http://www.opengl.org/registry/specs/ARB/vertex_program.txt -// -// Generic -// Attribute Conventional Attribute Conventional Attribute Command -// --------- ------------------------ ------------------------------ -// 0 vertex position Vertex -// 1 vertex weights 0-3 WeightARB, VertexWeightEXT -// 2 normal Normal -// 3 primary color Color -// 4 secondary color SecondaryColorEXT -// 5 fog coordinate FogCoordEXT -// 6 - - -// 7 - - -// 8 texture coordinate set 0 MultiTexCoord(TEXTURE0, ...) -// 9 texture coordinate set 1 MultiTexCoord(TEXTURE1, ...) -// 10 texture coordinate set 2 MultiTexCoord(TEXTURE2, ...) -// 11 texture coordinate set 3 MultiTexCoord(TEXTURE3, ...) -// 12 texture coordinate set 4 MultiTexCoord(TEXTURE4, ...) -// 13 texture coordinate set 5 MultiTexCoord(TEXTURE5, ...) -// 14 texture coordinate set 6 MultiTexCoord(TEXTURE6, ...) -// 15 texture coordinate set 7 MultiTexCoord(TEXTURE7, ...) -// 8+n texture coordinate set n MultiTexCoord(TEXTURE0+n, ...) -// -// Note: we only accept at most 8 texture coordinates for maximum compatibility -// with DirectX. - -inline unsigned int GetAttribIndex(vertex_struct::Semantic semantic, - unsigned int semantic_index) { - switch (semantic) { - case vertex_struct::kPosition: - DCHECK_EQ(semantic_index, 0); - return 0; - case vertex_struct::kNormal: - DCHECK_EQ(semantic_index, 0); - return 2; - case vertex_struct::kColor: - DCHECK_LT(semantic_index, 2U); - return 3 + semantic_index; - case vertex_struct::kTexCoord: - DCHECK_LT(semantic_index, 8U); - return 8 + semantic_index; - default: - DLOG(FATAL) << "Not reached."; - return 0; - } -} - -inline void ExtractSizeTypeNormalized(vertex_struct::Type type, - GLint *size, - GLenum *gl_type, - GLboolean *normalized) { - switch (type) { - case vertex_struct::kFloat1: - case vertex_struct::kFloat2: - case vertex_struct::kFloat3: - case vertex_struct::kFloat4: - *size = type - vertex_struct::kFloat1 + 1; - *gl_type = GL_FLOAT; - *normalized = false; - break; - case vertex_struct::kUChar4N: - *size = 4; - *gl_type = GL_UNSIGNED_BYTE; - *normalized = true; - break; - default: - DLOG(FATAL) << "Not reached."; - break; - } -} - -} // anonymous namespace - -#ifndef COMPILER_MSVC -// Although required by the spec, this causes problems on MSVC. It is needed by -// GCC. -const unsigned int VertexStructGL::kMaxAttribs; -#endif - -void VertexStructGL::Compile() { - DCHECK(dirty_); - for (unsigned int i = 0; i < kMaxAttribs; ++i) { - attribs_[i].vertex_buffer_id = kInvalidResource; - } - for (unsigned int i = 0; i < count_ ; ++i) { - const Element &element = GetElement(i); - unsigned int index = GetAttribIndex(element.semantic, - element.semantic_index); - DCHECK_LT(index, kMaxAttribs); - AttribDesc &attrib = attribs_[index]; - attrib.vertex_buffer_id = element.vertex_buffer; - ExtractSizeTypeNormalized(element.type, &attrib.size, &attrib.type, - &attrib.normalized); - attrib.stride = element.stride; - attrib.offset = OffsetToPtrDiff(element.offset); - } - dirty_ = false; -} - -parse_error::ParseError GAPIGL::CreateVertexBuffer(ResourceId id, - unsigned int size, - unsigned int flags) { - VertexBufferGL *vertex_buffer = new VertexBufferGL(size, flags); - vertex_buffer->Create(); - vertex_buffers_.Assign(id, vertex_buffer); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIGL::DestroyVertexBuffer(ResourceId id) { - return vertex_buffers_.Destroy(id) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -parse_error::ParseError GAPIGL::SetVertexBufferData(ResourceId id, - unsigned int offset, - unsigned int size, - const void *data) { - VertexBufferGL *vertex_buffer = vertex_buffers_.Get(id); - if (!vertex_buffer) return parse_error::kParseInvalidArguments; - return vertex_buffer->SetData(offset, size, data) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -parse_error::ParseError GAPIGL::GetVertexBufferData(ResourceId id, - unsigned int offset, - unsigned int size, - void *data) { - VertexBufferGL *vertex_buffer = vertex_buffers_.Get(id); - if (!vertex_buffer) return parse_error::kParseInvalidArguments; - return vertex_buffer->GetData(offset, size, data) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -parse_error::ParseError GAPIGL::CreateIndexBuffer(ResourceId id, - unsigned int size, - unsigned int flags) { - IndexBufferGL *index_buffer = new IndexBufferGL(size, flags); - index_buffer->Create(); - index_buffers_.Assign(id, index_buffer); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIGL::DestroyIndexBuffer(ResourceId id) { - return index_buffers_.Destroy(id) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -parse_error::ParseError GAPIGL::SetIndexBufferData(ResourceId id, - unsigned int offset, - unsigned int size, - const void *data) { - IndexBufferGL *index_buffer = index_buffers_.Get(id); - if (!index_buffer) return parse_error::kParseInvalidArguments; - return index_buffer->SetData(offset, size, data) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -parse_error::ParseError GAPIGL::GetIndexBufferData(ResourceId id, - unsigned int offset, - unsigned int size, - void *data) { - IndexBufferGL *index_buffer = index_buffers_.Get(id); - if (!index_buffer) return parse_error::kParseInvalidArguments; - return index_buffer->GetData(offset, size, data) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -parse_error::ParseError GAPIGL::CreateVertexStruct( - ResourceId id, - unsigned int input_count) { - if (id == current_vertex_struct_) validate_streams_ = true; - VertexStructGL *vertex_struct = new VertexStructGL(input_count); - vertex_structs_.Assign(id, vertex_struct); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIGL::DestroyVertexStruct(ResourceId id) { - if (id == current_vertex_struct_) validate_streams_ = true; - return vertex_structs_.Destroy(id) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -parse_error::ParseError GAPIGL::SetVertexInput( - ResourceId vertex_struct_id, - unsigned int input_index, - ResourceId vertex_buffer_id, - unsigned int offset, - unsigned int stride, - vertex_struct::Type type, - vertex_struct::Semantic semantic, - unsigned int semantic_index) { - switch (semantic) { - case vertex_struct::kPosition: - if (semantic_index != 0) { - return parse_error::kParseInvalidArguments; - } - break; - case vertex_struct::kNormal: - if (semantic_index != 0) { - return parse_error::kParseInvalidArguments; - } - break; - case vertex_struct::kColor: - if (semantic_index >= 2) { - return parse_error::kParseInvalidArguments; - } - break; - case vertex_struct::kTexCoord: - if (semantic_index >= 8) { - return parse_error::kParseInvalidArguments; - } - break; - default: - DLOG(FATAL) << "Not reached."; - break; - } - if (vertex_buffer_id == current_vertex_struct_) validate_streams_ = true; - VertexStructGL *vertex_struct = vertex_structs_.Get(vertex_struct_id); - if (!vertex_struct || input_index >= vertex_struct->count()) - return parse_error::kParseInvalidArguments; - vertex_struct->SetInput(input_index, vertex_buffer_id, offset, stride, type, - semantic, semantic_index); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIGL::SetVertexStruct(ResourceId id) { - current_vertex_struct_ = id; - validate_streams_ = true; - return parse_error::kParseNoError; -} - -bool GAPIGL::ValidateStreams() { - DCHECK(validate_streams_); - VertexStructGL *vertex_struct = vertex_structs_.Get(current_vertex_struct_); - if (!vertex_struct) { - LOG(ERROR) << "Drawing with invalid streams."; - return false; - } - max_vertices_ = vertex_struct->SetStreams(this); - validate_streams_ = false; - return max_vertices_ > 0; -} - -namespace { - -void PrimitiveTypeToGL(o3d::PrimitiveType primitive_type, - GLenum *gl_mode, - unsigned int *count) { - switch (primitive_type) { - case o3d::kPoints: - *gl_mode = GL_POINTS; - break; - case o3d::kLines: - *gl_mode = GL_LINES; - *count *= 2; - break; - case o3d::kLineStrips: - *gl_mode = GL_LINE_STRIP; - ++*count; - break; - case o3d::kTriangles: - *gl_mode = GL_TRIANGLES; - *count *= 3; - break; - case o3d::kTriangleStrips: - *gl_mode = GL_TRIANGLE_STRIP; - *count += 2; - break; - case o3d::kTriangleFans: - *gl_mode = GL_TRIANGLE_FAN; - *count += 2; - break; - default: - LOG(FATAL) << "Invalid primitive type"; - break; - } -} - -} // anonymous namespace - -parse_error::ParseError GAPIGL::Draw(o3d::PrimitiveType primitive_type, - unsigned int first, - unsigned int count) { - if (validate_effect_ && !ValidateEffect()) { - return parse_error::kParseInvalidArguments; - } - DCHECK(current_effect_); - if (validate_streams_ && !ValidateStreams()) { - return parse_error::kParseInvalidArguments; - } - GLenum gl_mode = GL_POINTS; - PrimitiveTypeToGL(primitive_type, &gl_mode, &count); - if (first + count > max_vertices_) { - return parse_error::kParseInvalidArguments; - } - glDrawArrays(gl_mode, first, count); - CHECK_GL_ERROR(); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIGL::DrawIndexed( - o3d::PrimitiveType primitive_type, - ResourceId index_buffer_id, - unsigned int first, - unsigned int count, - unsigned int min_index, - unsigned int max_index) { - IndexBufferGL *index_buffer = index_buffers_.Get(index_buffer_id); - if (!index_buffer) return parse_error::kParseInvalidArguments; - if (validate_effect_ && !ValidateEffect()) { - return parse_error::kParseInvalidArguments; - } - DCHECK(current_effect_); - if (validate_streams_ && !ValidateStreams()) { - return parse_error::kParseInvalidArguments; - } - if ((min_index >= max_vertices_) || (max_index > max_vertices_)) { - return parse_error::kParseInvalidArguments; - } - GLenum gl_mode = GL_POINTS; - PrimitiveTypeToGL(primitive_type, &gl_mode, &count); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer->gl_buffer()); - GLenum index_type = (index_buffer->flags() & index_buffer::kIndex32Bit) ? - GL_UNSIGNED_INT : GL_UNSIGNED_SHORT; - GLuint index_size = (index_buffer->flags() & index_buffer::kIndex32Bit) ? - sizeof(GLuint) : sizeof(GLushort); // NOLINT - GLuint offset = first * index_size; - if (offset + count * index_size > index_buffer->size()) { - return parse_error::kParseInvalidArguments; - } - glDrawRangeElements(gl_mode, min_index, max_index, count, index_type, - OffsetToPtr(offset)); - CHECK_GL_ERROR(); - return parse_error::kParseNoError; -} - -} // namespace o3d -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/service/geometry_gl.h b/o3d/gpu/command_buffer/service/geometry_gl.h deleted file mode 100644 index b4d4b5f..0000000 --- a/o3d/gpu/command_buffer/service/geometry_gl.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file declares the VertexBufferGL, IndexBufferGL and VertexStructGL -// classes. - -#ifndef GPU_COMMAND_BUFFER_SERVICE_GEOMETRY_GL_H_ -#define GPU_COMMAND_BUFFER_SERVICE_GEOMETRY_GL_H_ - -#include "gpu/command_buffer/common/gapi_interface.h" -#include "gpu/command_buffer/service/resource.h" -#include "gpu/command_buffer/service/gl_utils.h" - -namespace command_buffer { -namespace o3d { - -class GAPIGL; - -// GL version of VertexBuffer. -class VertexBufferGL : public VertexBuffer { - public: - VertexBufferGL(unsigned int size, unsigned int flags) - : VertexBuffer(size, flags), - gl_buffer_(0) {} - virtual ~VertexBufferGL(); - - // Creates the GL vertex buffer. - void Create(); - - // Sets the data into the GL vertex buffer. - bool SetData(unsigned int offset, unsigned int size, const void *data); - - // Gets the data from the GL vertex buffer. - bool GetData(unsigned int offset, unsigned int size, void *data); - - // Gets the GL vertex buffer. - GLuint gl_buffer() const { return gl_buffer_; } - - private: - GLuint gl_buffer_; - DISALLOW_COPY_AND_ASSIGN(VertexBufferGL); -}; - -// GL version of IndexBuffer. -class IndexBufferGL : public IndexBuffer { - public: - IndexBufferGL(unsigned int size, unsigned int flags) - : IndexBuffer(size, flags), - gl_buffer_(0) {} - virtual ~IndexBufferGL(); - - // Creates the GL index buffer. - void Create(); - - // Sets the data into the GL index buffer. - bool SetData(unsigned int offset, unsigned int size, const void *data); - - // Gets the data from the GL index buffer. - bool GetData(unsigned int offset, unsigned int size, void *data); - - // Gets the GL index buffer. - GLuint gl_buffer() const { return gl_buffer_; } - - private: - GLuint gl_buffer_; - DISALLOW_COPY_AND_ASSIGN(IndexBufferGL); -}; - -// GL version of VertexStruct. -class VertexStructGL : public VertexStruct { - public: - explicit VertexStructGL(unsigned int count) - : VertexStruct(count), - dirty_(true) {} - virtual ~VertexStructGL() {} - - // Adds an input to the vertex struct. - void SetInput(unsigned int input_index, - ResourceId vertex_buffer_id, - unsigned int offset, - unsigned int stride, - vertex_struct::Type type, - vertex_struct::Semantic semantic, - unsigned int semantic_index); - - // Sets the input streams to GL. - unsigned int SetStreams(GAPIGL *gapi); - - private: - static const unsigned int kMaxAttribs = 16; - - // This struct describes the parameters that are passed to - // glVertexAttribPointer. - struct AttribDesc { - ResourceId vertex_buffer_id; - GLint size; - GLenum type; - GLboolean normalized; - GLsizei stride; - ptrdiff_t offset; - }; - - // Compiles the vertex declaration into the attribute array. - void Compile(); - - bool dirty_; - AttribDesc attribs_[kMaxAttribs]; - DISALLOW_COPY_AND_ASSIGN(VertexStructGL); -}; - - -} // namespace o3d -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_SERVICE_GEOMETRY_GL_H_ diff --git a/o3d/gpu/command_buffer/service/gl_utils.h b/o3d/gpu/command_buffer/service/gl_utils.h deleted file mode 100644 index 292b2d6..0000000 --- a/o3d/gpu/command_buffer/service/gl_utils.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file includes all the necessary GL/Cg headers and implements some useful -// utilities. - -#ifndef GPU_COMMAND_BUFFER_SERVICE_GL_UTILS_H_ -#define GPU_COMMAND_BUFFER_SERVICE_GL_UTILS_H_ - -#include -#if defined(OS_WIN) -#include -#endif -#include -#include -#include - -#define GL_GLEXT_PROTOTYPES - -// Define this for extra GL error debugging (slower). -// #define GL_ERROR_DEBUGGING -#ifdef GL_ERROR_DEBUGGING -#define CHECK_GL_ERROR() do { \ - GLenum gl_error = glGetError(); \ - LOG_IF(ERROR, gl_error != GL_NO_ERROR) << "GL Error :" << gl_error; \ - } while (0) -#else // GL_ERROR_DEBUGGING -#define CHECK_GL_ERROR() void(0) -#endif // GL_ERROR_DEBUGGING - -#endif // GPU_COMMAND_BUFFER_SERVICE_GL_UTILS_H_ diff --git a/o3d/gpu/command_buffer/service/mocks.h b/o3d/gpu/command_buffer/service/mocks.h deleted file mode 100644 index dbfb160..0000000 --- a/o3d/gpu/command_buffer/service/mocks.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains definitions for mock objects, used for testing. - -// TODO: This file "manually" defines some mock objects. Using gMock -// would be definitely preferable, unfortunately it doesn't work on Windows -// yet. - -#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_MOCKS_H_ -#define GPU_COMMAND_BUFFER_SERVICE_CROSS_MOCKS_H_ - -#include -#include "gmock/gmock.h" -#include "gpu/command_buffer/service/cmd_parser.h" -#include "gpu/command_buffer/service/cmd_buffer_engine.h" - -namespace command_buffer { - -// Mocks an AsyncAPIInterface, using GMock. -class AsyncAPIMock : public AsyncAPIInterface { - public: - AsyncAPIMock() { - testing::DefaultValue::Set( - parse_error::kParseNoError); - } - - // Predicate that matches args passed to DoCommand, by looking at the values. - class IsArgs { - public: - IsArgs(unsigned int arg_count, const void* args) - : arg_count_(arg_count), - args_(static_cast(const_cast(args))) { - } - - bool operator() (const void* _args) const { - const CommandBufferEntry* args = - static_cast(_args) + 1; - for (unsigned int i = 0; i < arg_count_; ++i) { - if (args[i].value_uint32 != args_[i].value_uint32) return false; - } - return true; - } - - private: - unsigned int arg_count_; - CommandBufferEntry *args_; - }; - - MOCK_METHOD3(DoCommand, parse_error::ParseError( - unsigned int command, - unsigned int arg_count, - const void* cmd_data)); - - const char* GetCommandName(unsigned int command_id) const { - return ""; - }; - - // Sets the engine, to forward SetToken commands to it. - void set_engine(CommandBufferEngine *engine) { engine_ = engine; } - - // Forwards the SetToken commands to the engine. - void SetToken(unsigned int command, - unsigned int arg_count, - const void* _args) { - DCHECK(engine_); - DCHECK_EQ(1u, command); - DCHECK_EQ(1u, arg_count); - const CommandBufferEntry* args = - static_cast(_args); - engine_->set_token(args[0].value_uint32); - } - private: - CommandBufferEngine *engine_; -}; - -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_MOCKS_H_ diff --git a/o3d/gpu/command_buffer/service/precompile.cc b/o3d/gpu/command_buffer/service/precompile.cc deleted file mode 100644 index 3e219b0..0000000 --- a/o3d/gpu/command_buffer/service/precompile.cc +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -#include "gpu/command_buffer/service/precompile.h" diff --git a/o3d/gpu/command_buffer/service/precompile.h b/o3d/gpu/command_buffer/service/precompile.h deleted file mode 100644 index 55d2b21..0000000 --- a/o3d/gpu/command_buffer/service/precompile.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains includes for common headers used by command buffer server -// files. It is used for pre-compiled header support. - -#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_PRECOMPILE_H_ -#define GPU_COMMAND_BUFFER_SERVICE_CROSS_PRECOMPILE_H_ - -#include - -#if defined(OS_WIN) -#include -#endif - -#include -#include -#include -#include - -#endif // O3D_CORE_CROSS_PRECOMPILE_H_ diff --git a/o3d/gpu/command_buffer/service/render_surface_d3d9.cc b/o3d/gpu/command_buffer/service/render_surface_d3d9.cc deleted file mode 100644 index a3880f8..0000000 --- a/o3d/gpu/command_buffer/service/render_surface_d3d9.cc +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file implements the D3D9 versions of the render surface resources, -// as well as the related GAPID3D9 function implementations. - -#include "gpu/command_buffer/service/precompile.h" -#include "gpu/command_buffer/service/render_surface_d3d9.h" -#include "gpu/command_buffer/service/gapi_d3d9.h" -#include "gpu/command_buffer/service/texture_d3d9.h" - - -namespace command_buffer { -namespace o3d { - -RenderSurfaceD3D9::RenderSurfaceD3D9(int width, - int height, - int mip_level, - int side, - TextureD3D9 *texture, - IDirect3DSurface9 *direct3d_surface) - : width_(width), - height_(height), - mip_level_(mip_level), - texture_(texture), - direct3d_surface_(direct3d_surface) { - DCHECK_GT(width, 0); - DCHECK_GT(height, 0); - DCHECK_GT(mip_level, -1); - DCHECK(texture); -} - -RenderSurfaceD3D9* RenderSurfaceD3D9::Create(GAPID3D9 *gapi, - int width, - int height, - int mip_level, - int side, - TextureD3D9 *texture) { - DCHECK(gapi); - DCHECK_GT(width, 0); - DCHECK_GT(height, 0); - DCHECK_GT(mip_level, -1); - DCHECK(texture); - CComPtr direct3d_surface_handle; - bool success = - texture->CreateRenderSurface(width, height, mip_level, side, - &direct3d_surface_handle); - if (!success || direct3d_surface_handle == NULL) { - // If the surface was not created properly, delete and return nothing. - return NULL; - } - RenderSurfaceD3D9 *render_surface = - new RenderSurfaceD3D9(width, - height, - mip_level, - side, - texture, - direct3d_surface_handle); - return render_surface; -} - -RenderDepthStencilSurfaceD3D9::RenderDepthStencilSurfaceD3D9( - int width, - int height, - IDirect3DSurface9 *direct3d_surface) - : width_(width), - height_(height), - direct3d_surface_(direct3d_surface) { - DCHECK_GT(width, 0); - DCHECK_GT(height, 0); -} - -RenderDepthStencilSurfaceD3D9* RenderDepthStencilSurfaceD3D9::Create( - GAPID3D9 *gapi, - int width, - int height) { - DCHECK(gapi); - DCHECK_GT(width, 0); - DCHECK_GT(height, 0); - - CComPtr direct3d_surface; - gapi->d3d_device()->CreateDepthStencilSurface( - width, - height, - D3DFMT_D24S8, // d3d format - D3DMULTISAMPLE_NONE, // multisampling type - 0, // multisample quality level - FALSE, // z-buffer discarding disabled - &direct3d_surface, - NULL); // This parameter is required to be NULL. - if (direct3d_surface == NULL) { - return NULL; - } - RenderDepthStencilSurfaceD3D9 *depth_stencil = - new RenderDepthStencilSurfaceD3D9(width, height, direct3d_surface); - return depth_stencil; -} - -// GAPI Interface functions --------------------------------------------------- - -// Copies the data from a texture resource. -parse_error::ParseError GAPID3D9::CreateRenderSurface( - ResourceId id, - unsigned int width, - unsigned int height, - unsigned int mip_level, - unsigned int side, - ResourceId texture_id) { - if (id == current_surface_id_) { - // This will delete the current surface which would be bad. - return parse_error::kParseInvalidArguments; - } - TextureD3D9 *texture = textures_.Get(texture_id); - if (!texture->render_surfaces_enabled()) { - return parse_error::kParseInvalidArguments; - } else { - RenderSurfaceD3D9 *render_surface = RenderSurfaceD3D9::Create(this, - width, - height, - mip_level, - side, - texture); - if (render_surface == NULL) { - return parse_error::kParseInvalidArguments; - } - render_surfaces_.Assign(id, render_surface); - } - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPID3D9::DestroyRenderSurface(ResourceId id) { - if (id == current_surface_id_) { - return parse_error::kParseInvalidArguments; - } - return render_surfaces_.Destroy(id) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -parse_error::ParseError GAPID3D9::CreateDepthSurface( - ResourceId id, - unsigned int width, - unsigned int height) { - if (id == current_depth_surface_id_) { - // This will delete the current surface which would be bad. - return parse_error::kParseInvalidArguments; - } - RenderDepthStencilSurfaceD3D9 *depth_surface = - RenderDepthStencilSurfaceD3D9::Create(this, width, height); - if (depth_surface == NULL) { - return parse_error::kParseInvalidArguments; - } - depth_surfaces_.Assign(id, depth_surface); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPID3D9::DestroyDepthSurface(ResourceId id) { - if (id == current_depth_surface_id_) { - return parse_error::kParseInvalidArguments; - } - return depth_surfaces_.Destroy(id) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -parse_error::ParseError GAPID3D9::SetRenderSurface( - ResourceId render_surface_id, - ResourceId depth_stencil_id) { - RenderSurfaceD3D9 *d3d_render_surface = - render_surfaces_.Get(render_surface_id); - RenderDepthStencilSurfaceD3D9 *d3d_render_depth_surface = - depth_surfaces_.Get(depth_stencil_id); - - if (d3d_render_surface == NULL && d3d_render_depth_surface == NULL) { - return parse_error::kParseInvalidArguments; - } - - IDirect3DSurface9 *d3d_surface = - d3d_render_surface ? d3d_render_surface->direct3d_surface() : NULL; - IDirect3DSurface9 *d3d_depth_surface = d3d_render_depth_surface ? - d3d_render_depth_surface->direct3d_surface() : NULL; - - // Get the device and set the render target and the depth stencil surface. - IDirect3DDevice9 *device = this->d3d_device(); - - HR(device->SetRenderTarget(0, d3d_surface)); - HR(device->SetDepthStencilSurface(d3d_depth_surface)); - current_surface_id_ = render_surface_id; - current_depth_surface_id_ = depth_stencil_id; - return parse_error::kParseNoError; -} - -void GAPID3D9::SetBackSurfaces() { - // Get the device and set the render target and the depth stencil surface. - IDirect3DDevice9 *device = this->d3d_device(); - HR(d3d_device()->SetRenderTarget(0, back_buffer_surface_)); - HR(d3d_device()->SetDepthStencilSurface(back_buffer_depth_surface_)); -} - -} // namespace o3d -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/service/render_surface_d3d9.h b/o3d/gpu/command_buffer/service/render_surface_d3d9.h deleted file mode 100644 index 4769f1f..0000000 --- a/o3d/gpu/command_buffer/service/render_surface_d3d9.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -#ifndef GPU_COMMAND_BUFFER_SERVICE_RENDER_SURFACE_D3D9_H_ -#define GPU_COMMAND_BUFFER_SERVICE_RENDER_SURFACE_D3D9_H_ - -// This file contains the definition of the D3D9 versions of -// render surface-related resource classes. - -#include -#include "base/scoped_ptr.h" -#include "gpu/command_buffer/common/gapi_interface.h" -#include "gpu/command_buffer/service/resource.h" -#include "gpu/command_buffer/service/d3d9_utils.h" -#include "gpu/command_buffer/service/texture_d3d9.h" - -namespace command_buffer { -namespace o3d { - -class GAPID3D9; - -// The RenderSurfaceD3D class represents a render surface resource in the d3d -// backend of the command buffer server. -class RenderSurfaceD3D9 : public RenderSurface { - public: - - // Creates a render surface resource based on D3D. - // Parameters: - // width - width of the surface to be created. Must match width of texture - // at mip_level. - // height - height of the surface to be created. Must match width of - // texture at mip_level. - // mip_level - mip level of the texture to which the render surface maps. - // side - side of a cube if texture is a cube texture. Does not apply to - // texture 2d's. - // texture - the texture to which this render surface maps. Not owned by - // the RenderSurfaceD3D9. - // direct3d_surface - a surface to be used as this render surface's - // rendering surface. The new RenderSurfaceD3D9 will own the - // direct3d_surface. - RenderSurfaceD3D9(int width, - int height, - int mip_level, - int side, - TextureD3D9 *texture, - IDirect3DSurface9 *direct3d_surface); - - // Destructor for the render surface. - virtual ~RenderSurfaceD3D9() {} - - // Performs the setup necessary to create a render surface resource based on - // D3D and returns a new one if possibe. - // Parameters: - // gapi - the gapi interface to D3D. - // width - width of the surface to be created. Must match width of texture - // at mip_level. - // height - height of the surface to be created. Must match width of - // texture at mip_level. - // mip_level - mip level of the texture to which the render surface maps. - // side - side of a cube if texture is a cube texture. Does not apply to - // texture 2d's. - // texture - the texture to which this render surface maps. - // Returns: - // a new RenderSurfaceD3D9 or NULL on failure - static RenderSurfaceD3D9* Create(GAPID3D9 *gapi, - int width, - int height, - int mip_level, - int side, - TextureD3D9 *texture); - - // Returns a reference to the actual direct3d surface that is rendered to. - IDirect3DSurface9* direct3d_surface() const { - return direct3d_surface_; - } - private: - CComPtr direct3d_surface_; - int width_; - int height_; - int mip_level_; - TextureD3D9 *texture_; - DISALLOW_COPY_AND_ASSIGN(RenderSurfaceD3D9); -}; - -// The RenderDepthStencilSurfaceD3D class represents a depth stencil surface -// resource in the d3d backend of the command buffer server. -class RenderDepthStencilSurfaceD3D9 : public RenderDepthStencilSurface { - public: - - // Creates a depth stencil surface resource based on D3D. - // Parameters: - // width - width of the surface to be created. - // height - height of the surface to be created. - // direct3d_surface - a surface to be used as this depth stencil surface's - // rendering rendering surface. The new RenderDepthStencilSurfaceD3D9 - // will own the direct3d_surface. - RenderDepthStencilSurfaceD3D9(int width, - int height, - IDirect3DSurface9 *direct3d_surface); - - // Destructor for the depth stencil surface. - virtual ~RenderDepthStencilSurfaceD3D9() {} - - - // Performs the setup necessary to create a depth stencil surface resource - // based on D3D and returns a new one if possibe. - // Parameters: - // gapi - the gapi interface to D3D. - // width - width of the surface to be created. - // height - height of the surface to be created. - // Returns: - // a new RenderDepthStencilSurfaceD3D9 or NULL on failure. - static RenderDepthStencilSurfaceD3D9* Create(GAPID3D9 *gapi, - int width, - int height); - - // Returns a reference to the actual direct3d surface that is rendered to. - IDirect3DSurface9* direct3d_surface() const { - return direct3d_surface_; - } - private: - CComPtr direct3d_surface_; - int width_; - int height_; - DISALLOW_COPY_AND_ASSIGN(RenderDepthStencilSurfaceD3D9); -}; - -} // namespace o3d -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_SERVICE_RENDER_SURFACE_D3D9_H_ - diff --git a/o3d/gpu/command_buffer/service/render_surface_gl.cc b/o3d/gpu/command_buffer/service/render_surface_gl.cc deleted file mode 100644 index 5485323..0000000 --- a/o3d/gpu/command_buffer/service/render_surface_gl.cc +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file implements the OpenGL versions of the render surface resources, -// as well as the related GAPIGL function implementations. - -#include "gpu/command_buffer/service/precompile.h" -#include "gpu/command_buffer/service/gapi_gl.h" -#include "gpu/command_buffer/service/render_surface_gl.h" - - -namespace command_buffer { -namespace o3d { - -RenderSurfaceGL::RenderSurfaceGL(int width, - int height, - int mip_level, - int side, - TextureGL *texture) - : width_(width), height_(height), mip_level_(mip_level), texture_(texture) { -} - -RenderSurfaceGL* RenderSurfaceGL::Create(int width, - int height, - int mip_level, - int side, - TextureGL *texture) { - DCHECK_GT(width, 0); - DCHECK_GT(height, 0); - DCHECK_GE(mip_level, 0); - DCHECK(texture); - - RenderSurfaceGL* render_surface = - new RenderSurfaceGL(width, height, mip_level, side, texture); - return render_surface; -} - -RenderDepthStencilSurfaceGL::RenderDepthStencilSurfaceGL( - int width, - int height) - : width_(width), height_(height) { - DCHECK_GT(width, 0); - DCHECK_GT(height, 0); - - // If packed depth stencil is supported, create only one buffer for both - // depth and stencil. - if (GLEW_EXT_packed_depth_stencil) { - glGenRenderbuffersEXT(1, render_buffers_); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, render_buffers_[0]); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, - GL_DEPTH24_STENCIL8_EXT, - width, - height); - CHECK_GL_ERROR(); - render_buffers_[1] = render_buffers_[0]; - } else { - glGenRenderbuffersEXT(2, render_buffers_); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, render_buffers_[0]); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, - GL_DEPTH_COMPONENT24, - width, - height); - CHECK_GL_ERROR(); - - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, render_buffers_[1]); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, - GL_STENCIL_INDEX8_EXT, - width, - height); - CHECK_GL_ERROR(); - } -} - -RenderDepthStencilSurfaceGL* RenderDepthStencilSurfaceGL::Create( - int width, - int height) { - DCHECK_GT(width, 0); - DCHECK_GT(height, 0); - - return new RenderDepthStencilSurfaceGL(height, width); -} - -// Copies the data from a texture resource. -parse_error::ParseError GAPIGL::CreateRenderSurface( - ResourceId id, - unsigned int width, - unsigned int height, - unsigned int mip_level, - unsigned int side, - ResourceId texture_id) { - if (id == current_surface_id_) { - // This will delete the current surface which would be bad. - return parse_error::kParseInvalidArguments; - } - TextureGL *texture = textures_.Get(texture_id); - if (!texture->render_surfaces_enabled()) { - return parse_error::kParseInvalidArguments; - } else { - RenderSurfaceGL* render_surface = RenderSurfaceGL::Create(width, - height, - mip_level, - side, - texture); - if (render_surface == NULL) { - return parse_error::kParseInvalidArguments; - } - render_surfaces_.Assign(id, render_surface); - } - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIGL::DestroyRenderSurface(ResourceId id) { - if (id == current_surface_id_) { - return parse_error::kParseInvalidArguments; - } - return render_surfaces_.Destroy(id) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -parse_error::ParseError GAPIGL::CreateDepthSurface( - ResourceId id, - unsigned int width, - unsigned int height) { - if (id == current_depth_surface_id_) { - // This will delete the current surface which would be bad. - return parse_error::kParseInvalidArguments; - } - RenderDepthStencilSurfaceGL* depth_surface = - RenderDepthStencilSurfaceGL::Create(width, height); - if (depth_surface == NULL) { - return parse_error::kParseInvalidArguments; - } - depth_surfaces_.Assign(id, depth_surface); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIGL::DestroyDepthSurface(ResourceId id) { - if (id == current_depth_surface_id_) { - return parse_error::kParseInvalidArguments; - } - return depth_surfaces_.Destroy(id) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -void ResetBoundAttachments() { -#ifdef _DEBUG - GLint bound_framebuffer; - ::glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &bound_framebuffer); - DCHECK(bound_framebuffer != 0); -#endif - - // Reset the bound attachments to the current framebuffer object. - ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - GL_RENDERBUFFER_EXT, - 0); - - ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, - GL_DEPTH_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, - 0); - - ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, - GL_STENCIL_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, - 0); - - CHECK_GL_ERROR(); -} - -bool BindDepthStencilBuffer(const RenderDepthStencilSurfaceGL* gl_surface) { - // Bind both the depth and stencil attachments. - ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, - GL_DEPTH_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, - gl_surface->depth_buffer()); - ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, - GL_STENCIL_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, - gl_surface->stencil_buffer()); - - // Check for errors. - GLenum framebuffer_status = ::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - if (GL_FRAMEBUFFER_COMPLETE_EXT != framebuffer_status) { - return false; - } - - CHECK_GL_ERROR(); - return true; -} - -parse_error::ParseError GAPIGL::SetRenderSurface( - ResourceId render_surface_id, - ResourceId depth_stencil_id) { - if (render_surfaces_.Get(render_surface_id) == NULL && - depth_surfaces_.Get(depth_stencil_id) == NULL) { - return parse_error::kParseInvalidArguments; - } - - ::glBindFramebufferEXT(GL_FRAMEBUFFER, render_surface_framebuffer_); - ResetBoundAttachments(); - - RenderSurfaceGL* render_surface = render_surfaces_.Get(render_surface_id); - RenderDepthStencilSurfaceGL* depth_surface = - depth_surfaces_.Get(render_surface_id); - - if (!render_surface->texture()-> - InstallFrameBufferObjects(render_surface) || - !BindDepthStencilBuffer(depth_surface)) { - return parse_error::kParseInvalidArguments; - } - - // RenderSurface rendering is performed with an inverted Y, so the front - // face winding must be changed to clock-wise. See comments for - // UpdateHelperConstant. - glFrontFace(GL_CW); - - current_surface_id_ = render_surface_id; - current_depth_surface_id_ = depth_stencil_id; - return parse_error::kParseNoError; -} - -void GAPIGL::SetBackSurfaces() { - // Bind the default context, and restore the default front-face winding. - ::glBindFramebufferEXT(GL_FRAMEBUFFER, 0); - glFrontFace(GL_CCW); -} - -} // namespace o3d -} // namespace command_buffer - diff --git a/o3d/gpu/command_buffer/service/render_surface_gl.h b/o3d/gpu/command_buffer/service/render_surface_gl.h deleted file mode 100644 index 01d6137..0000000 --- a/o3d/gpu/command_buffer/service/render_surface_gl.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -#ifndef GPU_COMMAND_BUFFER_SERVICE_RENDER_SURFACE_GL_H__ -#define GPU_COMMAND_BUFFER_SERVICE_RENDER_SURFACE_GL_H__ - -// This file contains the definition of the OpenGL versions of -// render surface-related resource classes. - -#include "gpu/command_buffer/service/texture_gl.h" -#include "gpu/command_buffer/service/resource.h" - -namespace command_buffer { -namespace o3d { - -class RenderSurfaceGL : public RenderSurface { - public: - RenderSurfaceGL(int width, - int height, - int mip_level, - int side, - TextureGL *texture); - virtual ~RenderSurfaceGL() {} - - static RenderSurfaceGL* Create(int width, - int height, - int mip_level, - int side, - TextureGL *texture); - TextureGL* texture() { - return texture_; - } - - int width() { - return width_; - } - - int height() { - return height_; - } - - int mip_level() { - return mip_level_; - } - - int side() { - return side_; - } - private: - unsigned int width_; - unsigned int height_; - unsigned int mip_level_; - unsigned int side_; - TextureGL* texture_; - DISALLOW_COPY_AND_ASSIGN(RenderSurfaceGL); -}; - -class RenderDepthStencilSurfaceGL : public RenderDepthStencilSurface { - public: - RenderDepthStencilSurfaceGL(int width, - int height); - virtual ~RenderDepthStencilSurfaceGL() {} - - static RenderDepthStencilSurfaceGL* Create( - int width, - int height); - - GLuint depth_buffer() const { - return render_buffers_[0]; - } - - GLuint stencil_buffer() const { - return render_buffers_[1]; - } - - private: - // Handles to the depth and stencil render-buffers, respectively. - GLuint render_buffers_[2]; - unsigned int width_; - unsigned int height_; - DISALLOW_COPY_AND_ASSIGN(RenderDepthStencilSurfaceGL); -}; - -} // namespace o3d -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_SERVICE_WIN_GL_RENDER_SURFACE_GL_H__ - diff --git a/o3d/gpu/command_buffer/service/resource.cc b/o3d/gpu/command_buffer/service/resource.cc deleted file mode 100644 index 1208d30..0000000 --- a/o3d/gpu/command_buffer/service/resource.cc +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the implementation of ResourceMapBase. - -#include "gpu/command_buffer/service/precompile.h" -#include "gpu/command_buffer/service/resource.h" - -namespace command_buffer { - -// Assigns a resource to a resource ID, by setting it at the right location -// into the list, resizing the list if necessary, and destroying an existing -// resource if one existed already. -void ResourceMapBase::Assign(ResourceId id, Resource *resource) { - if (id >= resources_.size()) { - resources_.resize(id + 1, NULL); - } else { - Resource *&entry = resources_[id]; - if (entry) { - delete entry; - entry = NULL; - } - } - DCHECK(resources_[id] == NULL); - resources_[id] = resource; -} - -// Destroys a resource contained in the map, setting its entry to NULL. If -// necessary, this will trim the list. -bool ResourceMapBase::Destroy(ResourceId id) { - if (id >= resources_.size()) { - return false; - } - Resource *&entry = resources_[id]; - if (entry) { - delete entry; - entry = NULL; - - // Removing the last element, we can trim the list. - // TODO: this may not be optimal to do every time. Investigate if it - // becomes an issue, and add a threshold before we resize. - if (id == resources_.size() - 1) { - size_t last_valid = resources_.max_size(); - for (unsigned int i = id; i < resources_.size(); --i) { - if (resources_[i]) { - last_valid = i; - break; - } - } - if (last_valid == resources_.max_size()) { - resources_.clear(); - } else { - resources_.resize(last_valid + 1); - } - } - return true; - } - return false; -} - -// Goes over all non-NULL entries in the list, destroying them, then clears the -// list. -void ResourceMapBase::DestroyAllResources() { - for (Container::iterator i = resources_.begin(); i != resources_.end(); ++i) { - if (*i) { - delete *i; - } - } - resources_.clear(); -} - -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/service/resource.h b/o3d/gpu/command_buffer/service/resource.h deleted file mode 100644 index 20e3038..0000000 --- a/o3d/gpu/command_buffer/service/resource.h +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the definition for resource classes and the resource map. - -#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_RESOURCE_H_ -#define GPU_COMMAND_BUFFER_SERVICE_CROSS_RESOURCE_H_ - -#include -#include "base/scoped_ptr.h" -#include "gpu/command_buffer/common/resource.h" - -namespace command_buffer { - -// Base class for resources, just providing a common Destroy function. -class Resource { - public: - Resource() {} - virtual ~Resource() {} - private: - DISALLOW_COPY_AND_ASSIGN(Resource); -}; - -// VertexBuffer class, representing a vertex buffer resource. -class VertexBuffer: public Resource { - public: - VertexBuffer(unsigned int size, unsigned int flags) - : size_(size), - flags_(flags) {} - virtual ~VertexBuffer() {} - - // Returns the vertex buffer flags. - unsigned int flags() const { return flags_; } - // Sets the vertex buffer flags. - void set_flags(unsigned int flags) { flags_ = flags; } - // Returns the vertex buffer size. - unsigned int size() const { return size_; } - // Sets the vertex buffer size. - void set_size(unsigned int size) { size_ = size; } - protected: - unsigned int size_; - unsigned int flags_; - private: - DISALLOW_COPY_AND_ASSIGN(VertexBuffer); -}; - -// IndexBuffer class, representing an index buffer resource. -class IndexBuffer: public Resource { - public: - IndexBuffer(unsigned int size, unsigned int flags) - : size_(size), - flags_(flags) {} - virtual ~IndexBuffer() {} - - // Returns the index buffer flags. - unsigned int flags() const { return flags_; } - // Sets the index buffer flags. - void set_flags(unsigned int flags) { flags_ = flags; } - // Returns the index buffer size. - unsigned int size() const { return size_; } - // Sets the index buffer size. - void set_size(unsigned int size) { size_ = size; } - protected: - unsigned int size_; - unsigned int flags_; - private: - DISALLOW_COPY_AND_ASSIGN(IndexBuffer); -}; - -// VertexStruct class, representing a vertex struct resource. -class VertexStruct: public Resource { - public: - // The representation of an input data stream. - struct Element { - ResourceId vertex_buffer; - unsigned int offset; - unsigned int stride; - vertex_struct::Type type; - vertex_struct::Semantic semantic; - unsigned int semantic_index; - }; - - explicit VertexStruct(unsigned int count) - : count_(count), - elements_(new Element[count]) { - memset(elements_.get(), 0, count * sizeof(Element)); // NOLINT - } - - // Returns the number of inputs in this struct. - unsigned int count() const { return count_; } - // Returns an element by index. - Element &GetElement(unsigned int i) { - DCHECK_GT(count_, i); - return elements_[i]; - } - protected: - unsigned int count_; - scoped_array elements_; - private: - DISALLOW_COPY_AND_ASSIGN(VertexStruct); -}; - -// Effect class, representing an effect. -class Effect: public Resource { - public: - Effect() {} - private: - DISALLOW_COPY_AND_ASSIGN(Effect); -}; - -// EffectParam class, representing an effect parameter. -class EffectParam: public Resource { - public: - explicit EffectParam(effect_param::DataType data_type) - : data_type_(data_type) { - } - - // Gets the data type of this parameter. - effect_param::DataType data_type() const { return data_type_; } - private: - effect_param::DataType data_type_; - DISALLOW_COPY_AND_ASSIGN(EffectParam); -}; - -// Texture class, representing a texture resource. -class Texture: public Resource { - public: - Texture(texture::Type type, - unsigned int levels, - texture::Format format, - bool enable_render_surfaces, - unsigned int flags) - : type_(type), - levels_(levels), - format_(format), - render_surfaces_enabled_(enable_render_surfaces), - flags_(flags) {} - virtual ~Texture() {} - - // Returns the type of the texture. - texture::Type type() const { return type_; } - // Returns the texture flags. - unsigned int flags() const { return flags_; } - // Returns the texture format. - texture::Format format() const { return format_; } - // Returns whether the texture supports render surfaces - bool render_surfaces_enabled() const { return render_surfaces_enabled_; } - // Returns the number of mipmap levels in the texture. - unsigned int levels() const { return levels_; } - private: - texture::Type type_; - unsigned int levels_; - texture::Format format_; - bool render_surfaces_enabled_; - unsigned int flags_; - DISALLOW_COPY_AND_ASSIGN(Texture); -}; - -// RenderSurface class, representing a render surface/target -class RenderSurface: public Resource { - public: - RenderSurface() {} - private: - DISALLOW_COPY_AND_ASSIGN(RenderSurface); -}; - -// RenderSurface class, representing a render surface/target -class RenderDepthStencilSurface: public Resource { - public: - RenderDepthStencilSurface() {} - private: - DISALLOW_COPY_AND_ASSIGN(RenderDepthStencilSurface); -}; - - -// Texture class, representing a sampler resource. -class Sampler: public Resource { - public: - Sampler() {} - private: - DISALLOW_COPY_AND_ASSIGN(Sampler); -}; - -// Base of ResourceMap. Contains most of the implementation of ResourceMap, to -// avoid template bloat. -class ResourceMapBase { - public: - ResourceMapBase() : resources_() {} - ~ResourceMapBase() {} - - // Assigns a resource to a resource ID. Assigning a resource to an ID that - // already has an existing resource will destroy that existing resource. The - // map takes ownership of the resource. - void Assign(ResourceId id, Resource* resource); - // Destroys a resource. - bool Destroy(ResourceId id); - // Destroy all resources. - void DestroyAllResources(); - // Gets a resource by ID. - Resource *Get(ResourceId id) { - return (id < resources_.size()) ? resources_[id] : NULL; - } - private: - typedef std::vector Container; - Container resources_; -}; - -// Resource Map class, allowing resource ID <-> Resource association. This is a -// dense map, optimized for retrieval (O(1)). -template class ResourceMap { - public: - ResourceMap() : container_() {} - ~ResourceMap() {} - - // Assigns a resource to a resource ID. Assigning a resource to an ID that - // already has an existing resource will destroy that existing resource. The - // map takes ownership of the resource. - void Assign(ResourceId id, T* resource) { - container_.Assign(id, resource); - } - // Destroys a resource. - bool Destroy(ResourceId id) { - return container_.Destroy(id); - } - // Destroy all resources. - void DestroyAllResources() { - return container_.DestroyAllResources(); - } - // Gets a resource by ID. - T *Get(ResourceId id) { - return static_cast(container_.Get(id)); - } - private: - ResourceMapBase container_; -}; - -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_RESOURCE_H_ diff --git a/o3d/gpu/command_buffer/service/resource_test.cc b/o3d/gpu/command_buffer/service/resource_test.cc deleted file mode 100644 index 3e95dfb..0000000 --- a/o3d/gpu/command_buffer/service/resource_test.cc +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// Tests for the ResourceMap. - -#include "gpu/command_buffer/service/precompile.h" -#include "tests/common/win/testing_common.h" -#include "gpu/command_buffer/service/resource.h" - -namespace command_buffer { - -// Mock resource implementation that checks for leaks. -class ResourceMock : public Resource { - public: - ResourceMock() : Resource() { - ++instance_count_; - } - virtual ~ResourceMock() { - --instance_count_; - } - - // Returns the instance count. The instance count is increased in the - // constructor and decreased in the destructor, to track leaks. The reason is - // that we can't mock the destructor, though we want to make sure the mock is - // destroyed. - static int instance_count() { return instance_count_; } - private: - static int instance_count_; - DISALLOW_COPY_AND_ASSIGN(ResourceMock); -}; -int ResourceMock::instance_count_ = 0; - -// Test fixture for ResourceMap test. Creates a ResourceMap using a mock -// Resource, and checks for ResourceMock leaks. -class ResourceMapTest : public testing::Test { - protected: - typedef ResourceMap Map; - virtual void SetUp() { - instance_count_ = ResourceMock::instance_count(); - map_.reset(new Map()); - } - virtual void TearDown() { - CheckLeaks(); - } - - // Makes sure we didn't leak any ResourceMock object. - void CheckLeaks() { - EXPECT_EQ(instance_count_, ResourceMock::instance_count()); - } - - Map *map() const { return map_.get(); } - private: - int instance_count_; - scoped_ptr map_; -}; - -TEST_F(ResourceMapTest, TestMap) { - // check that initial mapping is empty. - EXPECT_EQ(NULL, map()->Get(0)); - EXPECT_EQ(NULL, map()->Get(1)); - EXPECT_EQ(NULL, map()->Get(392)); - - // create a new resource, assign it to an ID. - ResourceMock *resource = new ResourceMock(); - map()->Assign(123, resource); - EXPECT_EQ(resource, map()->Get(123)); - - // Destroy the resource, making sure the object is deleted. - EXPECT_EQ(true, map()->Destroy(123)); - EXPECT_EQ(false, map()->Destroy(123)); // destroying again should fail. - resource = NULL; - CheckLeaks(); - - // create a new resource, add it to the map, and make sure it gets deleted - // when we assign a new resource to that ID. - resource = new ResourceMock(); - map()->Assign(1, resource); - resource = new ResourceMock(); - map()->Assign(1, resource); - EXPECT_EQ(resource, map()->Get(1)); // check that we have the new resource. - EXPECT_EQ(true, map()->Destroy(1)); - CheckLeaks(); - - // Adds 3 resources, then call DestroyAllResources(). - resource = new ResourceMock(); - map()->Assign(1, resource); - resource = new ResourceMock(); - map()->Assign(2, resource); - resource = new ResourceMock(); - map()->Assign(3, resource); - map()->DestroyAllResources(); - EXPECT_EQ(NULL, map()->Get(1)); - EXPECT_EQ(NULL, map()->Get(2)); - EXPECT_EQ(NULL, map()->Get(3)); - CheckLeaks(); -} - -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/service/sampler_d3d9.cc b/o3d/gpu/command_buffer/service/sampler_d3d9.cc deleted file mode 100644 index e4c3b26..0000000 --- a/o3d/gpu/command_buffer/service/sampler_d3d9.cc +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the implementation of the SamplerD3D9 class. - -#include "gpu/command_buffer/service/precompile.h" -#include "gpu/command_buffer/service/gapi_d3d9.h" -#include "gpu/command_buffer/service/sampler_d3d9.h" -#include "gpu/command_buffer/service/texture_d3d9.h" - -namespace command_buffer { -namespace o3d { - -namespace { - -// Converts an addressing mode to corresponding D3D values. -D3DTEXTUREADDRESS AddressModeToD3D(sampler::AddressingMode mode) { - switch (mode) { - case sampler::kWrap: - return D3DTADDRESS_WRAP; - case sampler::kMirrorRepeat: - return D3DTADDRESS_MIRROR; - case sampler::kClampToEdge: - return D3DTADDRESS_CLAMP; - case sampler::kClampToBorder: - return D3DTADDRESS_BORDER; - } - DLOG(FATAL) << "Not reached"; - return D3DTADDRESS_WRAP; -} - -// Converts a filtering mode to corresponding D3D values. -D3DTEXTUREFILTERTYPE FilteringModeToD3D(sampler::FilteringMode mode) { - switch (mode) { - case sampler::kNone: - return D3DTEXF_NONE; - case sampler::kPoint: - return D3DTEXF_POINT; - case sampler::kLinear: - return D3DTEXF_LINEAR; - } - DLOG(FATAL) << "Not reached"; - return D3DTEXF_POINT; -} - -} // anonymous namespace - -SamplerD3D9::SamplerD3D9() - : texture_id_(kInvalidResource) { - SetStates(sampler::kClampToEdge, - sampler::kClampToEdge, - sampler::kClampToEdge, - sampler::kLinear, - sampler::kLinear, - sampler::kPoint, - 1); - RGBA black = {0, 0, 0, 1}; - SetBorderColor(black); -} - -bool SamplerD3D9::ApplyStates(GAPID3D9 *gapi, unsigned int unit) const { - DCHECK(gapi); - TextureD3D9 *texture = gapi->GetTexture(texture_id_); - if (!texture) { - return false; - } - IDirect3DDevice9 *d3d_device = gapi->d3d_device(); - HR(d3d_device->SetTexture(unit, texture->d3d_base_texture())); - HR(d3d_device->SetSamplerState(unit, D3DSAMP_ADDRESSU, d3d_address_u_)); - HR(d3d_device->SetSamplerState(unit, D3DSAMP_ADDRESSV, d3d_address_v_)); - HR(d3d_device->SetSamplerState(unit, D3DSAMP_ADDRESSW, d3d_address_w_)); - HR(d3d_device->SetSamplerState(unit, D3DSAMP_MAGFILTER, d3d_mag_filter_)); - HR(d3d_device->SetSamplerState(unit, D3DSAMP_MINFILTER, d3d_min_filter_)); - HR(d3d_device->SetSamplerState(unit, D3DSAMP_MIPFILTER, d3d_mip_filter_)); - HR(d3d_device->SetSamplerState(unit, D3DSAMP_MAXANISOTROPY, - d3d_max_anisotropy_)); - HR(d3d_device->SetSamplerState(unit, D3DSAMP_BORDERCOLOR, d3d_border_color_)); - return true; -} - -void SamplerD3D9::SetStates(sampler::AddressingMode addressing_u, - sampler::AddressingMode addressing_v, - sampler::AddressingMode addressing_w, - sampler::FilteringMode mag_filter, - sampler::FilteringMode min_filter, - sampler::FilteringMode mip_filter, - unsigned int max_anisotropy) { - // These are validated in GAPIDecoder.cc - DCHECK_NE(mag_filter, sampler::kNone); - DCHECK_NE(min_filter, sampler::kNone); - DCHECK_GT(max_anisotropy, 0U); - d3d_address_u_ = AddressModeToD3D(addressing_u); - d3d_address_v_ = AddressModeToD3D(addressing_v); - d3d_address_w_ = AddressModeToD3D(addressing_w); - d3d_mag_filter_ = FilteringModeToD3D(mag_filter); - d3d_min_filter_ = FilteringModeToD3D(min_filter); - d3d_mip_filter_ = FilteringModeToD3D(mip_filter); - if (max_anisotropy > 1) { - d3d_mag_filter_ = D3DTEXF_ANISOTROPIC; - d3d_min_filter_ = D3DTEXF_ANISOTROPIC; - } - d3d_max_anisotropy_ = max_anisotropy; -} - -void SamplerD3D9::SetBorderColor(const RGBA &color) { - d3d_border_color_ = RGBAToD3DCOLOR(color); -} - -parse_error::ParseError GAPID3D9::CreateSampler( - ResourceId id) { - // Dirty effect, because this sampler id may be used - DirtyEffect(); - samplers_.Assign(id, new SamplerD3D9()); - return parse_error::kParseNoError; -} - -// Destroys the Sampler resource. -parse_error::ParseError GAPID3D9::DestroySampler(ResourceId id) { - // Dirty effect, because this sampler id may be used - DirtyEffect(); - return samplers_.Destroy(id) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -parse_error::ParseError GAPID3D9::SetSamplerStates( - ResourceId id, - sampler::AddressingMode addressing_u, - sampler::AddressingMode addressing_v, - sampler::AddressingMode addressing_w, - sampler::FilteringMode mag_filter, - sampler::FilteringMode min_filter, - sampler::FilteringMode mip_filter, - unsigned int max_anisotropy) { - SamplerD3D9 *sampler = samplers_.Get(id); - if (!sampler) - return parse_error::kParseInvalidArguments; - // Dirty effect, because this sampler id may be used - DirtyEffect(); - sampler->SetStates(addressing_u, addressing_v, addressing_w, - mag_filter, min_filter, mip_filter, max_anisotropy); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPID3D9::SetSamplerBorderColor( - ResourceId id, - const RGBA &color) { - SamplerD3D9 *sampler = samplers_.Get(id); - if (!sampler) - return parse_error::kParseInvalidArguments; - // Dirty effect, because this sampler id may be used - DirtyEffect(); - sampler->SetBorderColor(color); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPID3D9::SetSamplerTexture( - ResourceId id, - ResourceId texture_id) { - SamplerD3D9 *sampler = samplers_.Get(id); - if (!sampler) - return parse_error::kParseInvalidArguments; - // Dirty effect, because this sampler id may be used - DirtyEffect(); - sampler->SetTexture(texture_id); - return parse_error::kParseNoError; -} - -} // namespace o3d -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/service/sampler_d3d9.h b/o3d/gpu/command_buffer/service/sampler_d3d9.h deleted file mode 100644 index 55a6e9a..0000000 --- a/o3d/gpu/command_buffer/service/sampler_d3d9.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the definition of the SamplerD3D9 class, implementing -// samplers for D3D. - -#ifndef GPU_COMMAND_BUFFER_SERVICE_SAMPLER_D3D9_H_ -#define GPU_COMMAND_BUFFER_SERVICE_SAMPLER_D3D9_H_ - -#include "gpu/command_buffer/common/gapi_interface.h" -#include "gpu/command_buffer/service/d3d9_utils.h" -#include "gpu/command_buffer/service/resource.h" - -namespace command_buffer { -namespace o3d { - -class GAPID3D9; - -// D3D9 version of Sampler. -class SamplerD3D9 : public Sampler { - public: - SamplerD3D9(); - - // Applies sampler states to D3D. - bool ApplyStates(GAPID3D9 *gapi, unsigned int unit) const; - - // Sets sampler states. - void SetStates(sampler::AddressingMode addressing_u, - sampler::AddressingMode addressing_v, - sampler::AddressingMode addressing_w, - sampler::FilteringMode mag_filter, - sampler::FilteringMode min_filter, - sampler::FilteringMode mip_filter, - unsigned int max_anisotropy); - - // Sets the border color states. - void SetBorderColor(const RGBA &color); - - // Sets the texture. - void SetTexture(ResourceId texture) { texture_id_ = texture; } - private: - D3DTEXTUREADDRESS d3d_address_u_; - D3DTEXTUREADDRESS d3d_address_v_; - D3DTEXTUREADDRESS d3d_address_w_; - D3DTEXTUREFILTERTYPE d3d_mag_filter_; - D3DTEXTUREFILTERTYPE d3d_min_filter_; - D3DTEXTUREFILTERTYPE d3d_mip_filter_; - DWORD d3d_max_anisotropy_; - D3DCOLOR d3d_border_color_; - ResourceId texture_id_; -}; - -} // namespace o3d -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_SERVICE_SAMPLER_D3D9_H_ diff --git a/o3d/gpu/command_buffer/service/sampler_gl.cc b/o3d/gpu/command_buffer/service/sampler_gl.cc deleted file mode 100644 index 32335e1..0000000 --- a/o3d/gpu/command_buffer/service/sampler_gl.cc +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file implements the sampler-related GAPI functions on GL. - -#include "gpu/command_buffer/service/precompile.h" -#include "gpu/command_buffer/service/gapi_gl.h" -#include "gpu/command_buffer/service/sampler_gl.h" - -namespace command_buffer { -namespace o3d { - -namespace { - -// Gets the GL enum corresponding to an addressing mode. -GLenum GLAddressMode(sampler::AddressingMode o3d_mode) { - switch (o3d_mode) { - case sampler::kWrap: - return GL_REPEAT; - case sampler::kMirrorRepeat: - return GL_MIRRORED_REPEAT; - case sampler::kClampToEdge: - return GL_CLAMP_TO_EDGE; - case sampler::kClampToBorder: - return GL_CLAMP_TO_BORDER; - default: - DLOG(FATAL) << "Not Reached"; - return GL_REPEAT; - } -} - -// Gets the GL enum for the minification filter based on the command buffer min -// and mip filtering modes. -GLenum GLMinFilter(sampler::FilteringMode min_filter, - sampler::FilteringMode mip_filter) { - switch (min_filter) { - case sampler::kPoint: - if (mip_filter == sampler::kNone) - return GL_NEAREST; - else if (mip_filter == sampler::kPoint) - return GL_NEAREST_MIPMAP_NEAREST; - else if (mip_filter == sampler::kLinear) - return GL_NEAREST_MIPMAP_LINEAR; - case sampler::kLinear: - if (mip_filter == sampler::kNone) - return GL_LINEAR; - else if (mip_filter == sampler::kPoint) - return GL_LINEAR_MIPMAP_NEAREST; - else if (mip_filter == sampler::kLinear) - return GL_LINEAR_MIPMAP_LINEAR; - default: - DLOG(FATAL) << "Not Reached"; - return GL_LINEAR_MIPMAP_NEAREST; - } -} - -// Gets the GL enum for the magnification filter based on the command buffer mag -// filtering mode. -GLenum GLMagFilter(sampler::FilteringMode mag_filter) { - switch (mag_filter) { - case sampler::kPoint: - return GL_NEAREST; - case sampler::kLinear: - return GL_LINEAR; - default: - DLOG(FATAL) << "Not Reached"; - return GL_LINEAR; - } -} - -// Gets the GL enum representing the GL target based on the texture type. -GLenum GLTextureTarget(texture::Type type) { - switch (type) { - case texture::kTexture2d: - return GL_TEXTURE_2D; - case texture::kTexture3d: - return GL_TEXTURE_3D; - case texture::kTextureCube: - return GL_TEXTURE_CUBE_MAP; - default: - DLOG(FATAL) << "Not Reached"; - return GL_TEXTURE_2D; - } -} - -} // anonymous namespace - -SamplerGL::SamplerGL() - : texture_id_(kInvalidResource), - gl_texture_(0) { - SetStates(sampler::kClampToEdge, - sampler::kClampToEdge, - sampler::kClampToEdge, - sampler::kLinear, - sampler::kLinear, - sampler::kPoint, - 1); - RGBA black = {0, 0, 0, 1}; - SetBorderColor(black); -} - -bool SamplerGL::ApplyStates(GAPIGL *gapi) { - DCHECK(gapi); - TextureGL *texture = gapi->GetTexture(texture_id_); - if (!texture) { - gl_texture_ = 0; - return false; - } - GLenum target = GLTextureTarget(texture->type()); - gl_texture_ = texture->gl_texture(); - glBindTexture(target, gl_texture_); - glTexParameteri(target, GL_TEXTURE_WRAP_S, gl_wrap_s_); - glTexParameteri(target, GL_TEXTURE_WRAP_T, gl_wrap_t_); - glTexParameteri(target, GL_TEXTURE_WRAP_R, gl_wrap_r_); - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, gl_min_filter_); - glTexParameteri(target, GL_TEXTURE_MAG_FILTER, gl_mag_filter_); - glTexParameteri(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_max_anisotropy_); - glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, gl_border_color_); - return true; -} - -void SamplerGL::SetStates(sampler::AddressingMode addressing_u, - sampler::AddressingMode addressing_v, - sampler::AddressingMode addressing_w, - sampler::FilteringMode mag_filter, - sampler::FilteringMode min_filter, - sampler::FilteringMode mip_filter, - unsigned int max_anisotropy) { - // These are validated in GAPIDecoder.cc - DCHECK_NE(mag_filter, sampler::kNone); - DCHECK_NE(min_filter, sampler::kNone); - DCHECK_GT(max_anisotropy, 0U); - gl_wrap_s_ = GLAddressMode(addressing_u); - gl_wrap_t_ = GLAddressMode(addressing_v); - gl_wrap_r_ = GLAddressMode(addressing_w); - gl_mag_filter_ = GLMagFilter(mag_filter); - gl_min_filter_ = GLMinFilter(min_filter, mip_filter); - gl_max_anisotropy_ = max_anisotropy; -} - -void SamplerGL::SetBorderColor(const RGBA &color) { - gl_border_color_[0] = color.red; - gl_border_color_[1] = color.green; - gl_border_color_[2] = color.blue; - gl_border_color_[3] = color.alpha; -} - -parse_error::ParseError GAPIGL::CreateSampler( - ResourceId id) { - // Dirty effect, because this sampler id may be used. - DirtyEffect(); - samplers_.Assign(id, new SamplerGL()); - return parse_error::kParseNoError; -} - -// Destroys the Sampler resource. -parse_error::ParseError GAPIGL::DestroySampler(ResourceId id) { - // Dirty effect, because this sampler id may be used. - DirtyEffect(); - return samplers_.Destroy(id) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -parse_error::ParseError GAPIGL::SetSamplerStates( - ResourceId id, - sampler::AddressingMode addressing_u, - sampler::AddressingMode addressing_v, - sampler::AddressingMode addressing_w, - sampler::FilteringMode mag_filter, - sampler::FilteringMode min_filter, - sampler::FilteringMode mip_filter, - unsigned int max_anisotropy) { - SamplerGL *sampler = samplers_.Get(id); - if (!sampler) - return parse_error::kParseInvalidArguments; - // Dirty effect, because this sampler id may be used. - DirtyEffect(); - sampler->SetStates(addressing_u, addressing_v, addressing_w, - mag_filter, min_filter, mip_filter, max_anisotropy); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIGL::SetSamplerBorderColor( - ResourceId id, - const RGBA &color) { - SamplerGL *sampler = samplers_.Get(id); - if (!sampler) - return parse_error::kParseInvalidArguments; - // Dirty effect, because this sampler id may be used. - DirtyEffect(); - sampler->SetBorderColor(color); - return parse_error::kParseNoError; -} - -parse_error::ParseError GAPIGL::SetSamplerTexture( - ResourceId id, - ResourceId texture_id) { - SamplerGL *sampler = samplers_.Get(id); - if (!sampler) - return parse_error::kParseInvalidArguments; - // Dirty effect, because this sampler id may be used. - DirtyEffect(); - sampler->SetTexture(texture_id); - return parse_error::kParseNoError; -} - -} // namespace o3d -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/service/sampler_gl.h b/o3d/gpu/command_buffer/service/sampler_gl.h deleted file mode 100644 index 8809ea5..0000000 --- a/o3d/gpu/command_buffer/service/sampler_gl.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file declares the SamplerGL class. - -#ifndef GPU_COMMAND_BUFFER_SERVICE_SAMPLER_GL_H_ -#define GPU_COMMAND_BUFFER_SERVICE_SAMPLER_GL_H_ - -#include "gpu/command_buffer/common/gapi_interface.h" -#include "gpu/command_buffer/service/gl_utils.h" -#include "gpu/command_buffer/service/resource.h" - -namespace command_buffer { -namespace o3d { - -class GAPIGL; - -// GL version of Sampler. -class SamplerGL : public Sampler { - public: - SamplerGL(); - - // Applies sampler states to GL. - bool ApplyStates(GAPIGL *gapi); - - // Sets sampler states. - void SetStates(sampler::AddressingMode addressing_u, - sampler::AddressingMode addressing_v, - sampler::AddressingMode addressing_w, - sampler::FilteringMode mag_filter, - sampler::FilteringMode min_filter, - sampler::FilteringMode mip_filter, - unsigned int max_anisotropy); - - // Sets the border color states. - void SetBorderColor(const o3d::RGBA &color); - - // Sets the texture. - void SetTexture(ResourceId texture) { texture_id_ = texture; } - - GLuint gl_texture() const { return gl_texture_; } - - private: - GLenum gl_wrap_s_; - GLenum gl_wrap_t_; - GLenum gl_wrap_r_; - GLenum gl_mag_filter_; - GLenum gl_min_filter_; - GLuint gl_max_anisotropy_; - GLfloat gl_border_color_[4]; - GLuint gl_texture_; - ResourceId texture_id_; -}; - -} // namespace o3d -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_SERVICE_SAMPLER_GL_H_ diff --git a/o3d/gpu/command_buffer/service/states_d3d9.cc b/o3d/gpu/command_buffer/service/states_d3d9.cc deleted file mode 100644 index 7abcada..0000000 --- a/o3d/gpu/command_buffer/service/states_d3d9.cc +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the implementation of the state-related GAPID3D9 -// functions. - -#include "gpu/command_buffer/service/precompile.h" - -#include - -#include "gpu/command_buffer/common/o3d_cmd_format.h" -#include "gpu/command_buffer/service/gapi_d3d9.h" - -namespace command_buffer { -namespace o3d { - -namespace { - -// Checks that a command_buffer enum matches a D3D enum so that it can be -// converted quickly. -#define CHECK_CB_ENUM_MATCHES_D3D(CB_ENUM, D3D_ENUM) \ - COMPILE_ASSERT(CB_ENUM + 1 == D3D_ENUM, \ - CB_ENUM ## _plus_1_not_ ## D3D_ENUM) - -// Converts values from the PolygonMode enum to corresponding D3D values -inline D3DFILLMODE PolygonModeToD3D(PolygonMode fill_mode) { - DCHECK_LT(fill_mode, kNumPolygonMode); - - // Check that all acceptable values translate to D3D values by adding 1. - - CHECK_CB_ENUM_MATCHES_D3D(kPolygonModePoints, D3DFILL_POINT); - CHECK_CB_ENUM_MATCHES_D3D(kPolygonModeLines, D3DFILL_WIREFRAME); - CHECK_CB_ENUM_MATCHES_D3D(kPolygonModeFill, D3DFILL_SOLID); - return static_cast(fill_mode + 1); -} - -// Converts values from the FaceCullMode enum to corresponding D3D values -inline D3DCULL FaceCullModeToD3D(FaceCullMode cull_mode) { - DCHECK_LT(cull_mode, kNumFaceCullMode); - - // Check that all acceptable values translate to D3D values by adding 1. - CHECK_CB_ENUM_MATCHES_D3D(kCullNone, D3DCULL_NONE); - CHECK_CB_ENUM_MATCHES_D3D(kCullCW, D3DCULL_CW); - CHECK_CB_ENUM_MATCHES_D3D(kCullCCW, D3DCULL_CCW); - return static_cast(cull_mode + 1); -} - -// Converts values from the Comparison enum to corresponding D3D values -inline D3DCMPFUNC ComparisonToD3D(Comparison comp) { - DCHECK_LT(comp, kNumComparison); - - // Check that all acceptable values translate to D3D values by adding 1. - CHECK_CB_ENUM_MATCHES_D3D(kNever, D3DCMP_NEVER); - CHECK_CB_ENUM_MATCHES_D3D(kLess, D3DCMP_LESS); - CHECK_CB_ENUM_MATCHES_D3D(kEqual, D3DCMP_EQUAL); - CHECK_CB_ENUM_MATCHES_D3D(kLEqual, D3DCMP_LESSEQUAL); - CHECK_CB_ENUM_MATCHES_D3D(kGreater, D3DCMP_GREATER); - CHECK_CB_ENUM_MATCHES_D3D(kNotEqual, D3DCMP_NOTEQUAL); - CHECK_CB_ENUM_MATCHES_D3D(kGEqual, D3DCMP_GREATEREQUAL); - CHECK_CB_ENUM_MATCHES_D3D(kAlways, D3DCMP_ALWAYS); - return static_cast(comp + 1); -} - -// Converts values from the StencilOp enum to corresponding D3D values -inline D3DSTENCILOP StencilOpToD3D(StencilOp stencil_op) { - DCHECK_LT(stencil_op, kNumStencilOp); - - // Check that all acceptable values translate to D3D values by adding 1. - CHECK_CB_ENUM_MATCHES_D3D(kKeep, D3DSTENCILOP_KEEP); - CHECK_CB_ENUM_MATCHES_D3D(kZero, D3DSTENCILOP_ZERO); - CHECK_CB_ENUM_MATCHES_D3D(kReplace, D3DSTENCILOP_REPLACE); - CHECK_CB_ENUM_MATCHES_D3D(kIncNoWrap, D3DSTENCILOP_INCRSAT); - CHECK_CB_ENUM_MATCHES_D3D(kDecNoWrap, D3DSTENCILOP_DECRSAT); - CHECK_CB_ENUM_MATCHES_D3D(kInvert, D3DSTENCILOP_INVERT); - CHECK_CB_ENUM_MATCHES_D3D(kIncWrap, D3DSTENCILOP_INCR); - CHECK_CB_ENUM_MATCHES_D3D(kDecWrap, D3DSTENCILOP_DECR); - return static_cast(stencil_op + 1); -} - -// Converts values from the BlendEq enum to corresponding D3D values -inline D3DBLENDOP BlendEqToD3D(BlendEq blend_eq) { - DCHECK_LT(blend_eq, kNumBlendEq); - // Check that all acceptable values translate to D3D values by adding 1. - CHECK_CB_ENUM_MATCHES_D3D(kBlendEqAdd, D3DBLENDOP_ADD); - CHECK_CB_ENUM_MATCHES_D3D(kBlendEqSub, D3DBLENDOP_SUBTRACT); - CHECK_CB_ENUM_MATCHES_D3D(kBlendEqRevSub, D3DBLENDOP_REVSUBTRACT); - CHECK_CB_ENUM_MATCHES_D3D(kBlendEqMin, D3DBLENDOP_MIN); - CHECK_CB_ENUM_MATCHES_D3D(kBlendEqMax, D3DBLENDOP_MAX); - return static_cast(blend_eq + 1); -} - -// Converts values from the BlendFunc enum to corresponding D3D values -D3DBLEND BlendFuncToD3D(BlendFunc blend_func) { - // The D3DBLEND enum values don't map 1-to-1 to BlendFunc, so we use a switch - // here. - switch (blend_func) { - case kBlendFuncZero: - return D3DBLEND_ZERO; - case kBlendFuncOne: - return D3DBLEND_ONE; - case kBlendFuncSrcColor: - return D3DBLEND_SRCCOLOR; - case kBlendFuncInvSrcColor: - return D3DBLEND_INVSRCCOLOR; - case kBlendFuncSrcAlpha: - return D3DBLEND_SRCALPHA; - case kBlendFuncInvSrcAlpha: - return D3DBLEND_INVSRCALPHA; - case kBlendFuncDstAlpha: - return D3DBLEND_DESTALPHA; - case kBlendFuncInvDstAlpha: - return D3DBLEND_INVDESTALPHA; - case kBlendFuncDstColor: - return D3DBLEND_DESTCOLOR; - case kBlendFuncInvDstColor: - return D3DBLEND_INVDESTCOLOR; - case kBlendFuncSrcAlphaSaturate: - return D3DBLEND_SRCALPHASAT; - case kBlendFuncBlendColor: - return D3DBLEND_BLENDFACTOR; - case kBlendFuncInvBlendColor: - return D3DBLEND_INVBLENDFACTOR; - default: - DLOG(FATAL) << "Invalid BlendFunc"; - return D3DBLEND_ZERO; - } -} - -// Decodes stencil test function and operations from the bitfield. -void DecodeStencilFuncOps(Uint32 params, - Comparison *func, - StencilOp *pass, - StencilOp *fail, - StencilOp *zfail) { - // Sanity check. The value has already been tested in - // GAPIDecoder::DecodeSetStencilTest in gapi_decoder.cc. - DCHECK_EQ(SetStencilTest::Unused1::Get(params), 0); - // Check that the bitmask get cannot generate values outside of the allowed - // range. - COMPILE_ASSERT(SetStencilTest::CWFunc::kMask < - kNumComparison, - set_stencil_test_CWFunc_may_produce_invalid_values); - *func = static_cast(SetStencilTest::CWFunc::Get(params)); - - COMPILE_ASSERT(SetStencilTest::CWPassOp::kMask < - kNumStencilOp, - set_stencil_test_CWPassOp_may_produce_invalid_values); - *pass = static_cast(SetStencilTest::CWPassOp::Get(params)); - - COMPILE_ASSERT(SetStencilTest::CWFailOp::kMask < - kNumStencilOp, - set_stencil_test_CWFailOp_may_produce_invalid_values); - *fail = static_cast(SetStencilTest::CWFailOp::Get(params)); - - COMPILE_ASSERT(SetStencilTest::CWZFailOp::kMask < - kNumStencilOp, - set_stencil_test_CWZFailOp_may_produce_invalid_values); - *zfail = static_cast(SetStencilTest::CWZFailOp::Get(params)); -} - -} // anonymous namespace - -void GAPID3D9::SetScissor(bool enable, - unsigned int x, - unsigned int y, - unsigned int width, - unsigned int height) { - HR(d3d_device_->SetRenderState(D3DRS_SCISSORTESTENABLE, - enable ? TRUE : FALSE)); - RECT rect = {x, y, x + width, y + height}; - HR(d3d_device_->SetScissorRect(&rect)); -} - -void GAPID3D9::SetPolygonOffset(float slope_factor, float units) { - HR(d3d_device_->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, - FloatAsDWORD(slope_factor))); - // TODO: this value is hard-coded currently because we only create a - // 24-bit depth buffer. Move this to a member of GAPID3D9 if this changes. - const float kUnitScale = 1.f / (1 << 24); - HR(d3d_device_->SetRenderState(D3DRS_DEPTHBIAS, - FloatAsDWORD(units * kUnitScale))); -} - -void GAPID3D9::SetPointLineRaster(bool line_smooth, - bool point_sprite, - float point_size) { - HR(d3d_device_->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, - line_smooth ? TRUE : FALSE)); - HR(d3d_device_->SetRenderState(D3DRS_POINTSPRITEENABLE, - point_sprite ? TRUE : FALSE)); - HR(d3d_device_->SetRenderState(D3DRS_POINTSIZE, - FloatAsDWORD(point_size))); -} - -void GAPID3D9::SetPolygonRaster(PolygonMode fill_mode, - FaceCullMode cull_mode) { - HR(d3d_device_->SetRenderState(D3DRS_FILLMODE, PolygonModeToD3D(fill_mode))); - HR(d3d_device_->SetRenderState(D3DRS_CULLMODE, FaceCullModeToD3D(cull_mode))); -} - -void GAPID3D9::SetAlphaTest(bool enable, - float reference, - Comparison comp) { - HR(d3d_device_->SetRenderState(D3DRS_ALPHABLENDENABLE, - enable ? TRUE : FALSE)); - HR(d3d_device_->SetRenderState(D3DRS_ALPHAREF, - FloatToClampedByte(reference))); - HR(d3d_device_->SetRenderState(D3DRS_ALPHAFUNC, ComparisonToD3D(comp))); -} - -void GAPID3D9::SetDepthTest(bool enable, - bool write_enable, - Comparison comp) { - HR(d3d_device_->SetRenderState(D3DRS_ZENABLE, - enable ? TRUE : FALSE)); - HR(d3d_device_->SetRenderState(D3DRS_ZWRITEENABLE, - write_enable ? TRUE : FALSE)); - HR(d3d_device_->SetRenderState(D3DRS_ZFUNC, ComparisonToD3D(comp))); -} - -void GAPID3D9::SetStencilTest(bool enable, - bool separate_ccw, - unsigned int write_mask, - unsigned int compare_mask, - unsigned int ref, - Uint32 func_ops) { - HR(d3d_device_->SetRenderState(D3DRS_STENCILENABLE, - enable ? TRUE : FALSE)); - HR(d3d_device_->SetRenderState(D3DRS_STENCILWRITEMASK, write_mask)); - HR(d3d_device_->SetRenderState(D3DRS_STENCILMASK, compare_mask)); - HR(d3d_device_->SetRenderState(D3DRS_STENCILREF, ref)); - - Comparison func; - StencilOp pass; - StencilOp fail; - StencilOp zfail; - DecodeStencilFuncOps(func_ops, &func, &pass, &fail, &zfail); - HR(d3d_device_->SetRenderState(D3DRS_STENCILFUNC, - ComparisonToD3D(func))); - HR(d3d_device_->SetRenderState(D3DRS_STENCILPASS, - StencilOpToD3D(pass))); - HR(d3d_device_->SetRenderState(D3DRS_STENCILFAIL, - StencilOpToD3D(fail))); - HR(d3d_device_->SetRenderState(D3DRS_STENCILZFAIL, - StencilOpToD3D(zfail))); - - if (separate_ccw) { - HR(d3d_device_->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE)); - // Check that the definition of the counter-clockwise func/ops match the - // clockwise ones, just shifted by 16 bits, so that we can use - // DecodeStencilFuncOps on both of them. -#define CHECK_CCW_MATCHES_CW(FIELD) \ - COMPILE_ASSERT(SetStencilTest::CW ## FIELD::kLength == \ - SetStencilTest::CCW ## FIELD::kLength, \ - CCW ## FIELD ## _length_does_not_match_ ## CW ## FIELD); \ - COMPILE_ASSERT(SetStencilTest::CW ## FIELD::kShift + 16 == \ - SetStencilTest::CCW ## FIELD::kShift, \ - CCW ## FIELD ## _shift_does_not_match_ ## CW ## FIELD) - CHECK_CCW_MATCHES_CW(Func); - CHECK_CCW_MATCHES_CW(PassOp); - CHECK_CCW_MATCHES_CW(FailOp); - CHECK_CCW_MATCHES_CW(ZFailOp); -#undef CHECK_CCW_MATCHES_CW - // Extract upper 16 bits. - Uint32 ccw_func_ops = BitField<16, 16>::Get(func_ops); - - DecodeStencilFuncOps(ccw_func_ops, &func, &pass, &fail, &zfail); - HR(d3d_device_->SetRenderState(D3DRS_CCW_STENCILFUNC, - ComparisonToD3D(func))); - HR(d3d_device_->SetRenderState(D3DRS_CCW_STENCILPASS, - StencilOpToD3D(pass))); - HR(d3d_device_->SetRenderState(D3DRS_CCW_STENCILFAIL, - StencilOpToD3D(fail))); - HR(d3d_device_->SetRenderState(D3DRS_CCW_STENCILZFAIL, - StencilOpToD3D(zfail))); - } else { - HR(d3d_device_->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE)); - } -} - -void GAPID3D9::SetColorWrite(bool red, - bool green, - bool blue, - bool alpha, - bool dither) { - Uint32 mask = red ? D3DCOLORWRITEENABLE_RED : 0; - mask |= green ? D3DCOLORWRITEENABLE_GREEN : 0; - mask |= blue ? D3DCOLORWRITEENABLE_BLUE : 0; - mask |= alpha ? D3DCOLORWRITEENABLE_ALPHA : 0; - HR(d3d_device_->SetRenderState(D3DRS_COLORWRITEENABLE, mask)); - HR(d3d_device_->SetRenderState(D3DRS_DITHERENABLE, dither ? TRUE : FALSE)); -} - -void GAPID3D9::SetBlending(bool enable, - bool separate_alpha, - BlendEq color_eq, - BlendFunc color_src_func, - BlendFunc color_dst_func, - BlendEq alpha_eq, - BlendFunc alpha_src_func, - BlendFunc alpha_dst_func) { - HR(d3d_device_->SetRenderState(D3DRS_ALPHABLENDENABLE, - enable ? TRUE : FALSE)); - HR(d3d_device_->SetRenderState(D3DRS_BLENDOP, BlendEqToD3D(color_eq))); - HR(d3d_device_->SetRenderState(D3DRS_SRCBLEND, - BlendFuncToD3D(color_src_func))); - HR(d3d_device_->SetRenderState(D3DRS_DESTBLEND, - BlendFuncToD3D(color_dst_func))); - if (separate_alpha) { - HR(d3d_device_->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE)); - HR(d3d_device_->SetRenderState(D3DRS_BLENDOP, BlendEqToD3D(alpha_eq))); - HR(d3d_device_->SetRenderState(D3DRS_SRCBLEND, - BlendFuncToD3D(alpha_src_func))); - HR(d3d_device_->SetRenderState(D3DRS_DESTBLEND, - BlendFuncToD3D(alpha_dst_func))); - } else { - HR(d3d_device_->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE)); - } -} - -void GAPID3D9::SetBlendingColor(const RGBA &color) { - HR(d3d_device_->SetRenderState(D3DRS_BLENDFACTOR, RGBAToD3DCOLOR(color))); -} - -} // namespace o3d -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/service/states_gl.cc b/o3d/gpu/command_buffer/service/states_gl.cc deleted file mode 100644 index 2d6fce4..0000000 --- a/o3d/gpu/command_buffer/service/states_gl.cc +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file implements the render state-related GAPI functions on GL. - -#include "gpu/command_buffer/service/precompile.h" -#include "gpu/command_buffer/common/o3d_cmd_format.h" -#include "gpu/command_buffer/service/gapi_gl.h" - -namespace command_buffer { -namespace o3d { - -namespace { - -GLenum kGLPolygonModes[] = { - GL_POINT, - GL_LINE, - GL_FILL, -}; -COMPILE_ASSERT(o3d::kNumPolygonMode == arraysize(kGLPolygonModes), - kGLPolygonModes_does_not_match_command_buffer_PolygonMode); - -GLenum kGLComparison[] = { - GL_NEVER, - GL_LESS, - GL_EQUAL, - GL_LEQUAL, - GL_GREATER, - GL_NOTEQUAL, - GL_GEQUAL, - GL_ALWAYS, -}; -COMPILE_ASSERT(o3d::kNumComparison == arraysize(kGLComparison), - kGLComparison_does_not_match_command_buffer_Comparison); - -GLenum kGLBlendFunc[] = { - GL_ZERO, - GL_ONE, - GL_SRC_COLOR, - GL_ONE_MINUS_SRC_COLOR, - GL_SRC_ALPHA, - GL_ONE_MINUS_SRC_ALPHA, - GL_DST_ALPHA, - GL_ONE_MINUS_DST_ALPHA, - GL_DST_COLOR, - GL_ONE_MINUS_DST_COLOR, - GL_SRC_ALPHA_SATURATE, - GL_CONSTANT_COLOR, - GL_ONE_MINUS_CONSTANT_COLOR, -}; -COMPILE_ASSERT(o3d::kNumBlendFunc == arraysize(kGLBlendFunc), - kGLBlendFunc_does_not_match_command_buffer_BlendFunc); - -GLenum kGLBlendEq[] = { - GL_FUNC_ADD, - GL_FUNC_SUBTRACT, - GL_FUNC_REVERSE_SUBTRACT, - GL_MIN, - GL_MAX, -}; -COMPILE_ASSERT(o3d::kNumBlendEq == arraysize(kGLBlendEq), - kGLBlendEq_does_not_match_command_buffer_BlendEq); - -GLenum kGLStencilOp[] = { - GL_KEEP, - GL_ZERO, - GL_REPLACE, - GL_INCR, - GL_DECR, - GL_INVERT, - GL_INCR_WRAP, - GL_DECR_WRAP, -}; -COMPILE_ASSERT(o3d::kNumStencilOp == arraysize(kGLStencilOp), - kGLStencilOp_does_not_match_command_buffer_StencilOp); - -// Check that the definition of the counter-clockwise func/ops match the -// clockwise ones, just shifted by 16 bits, so that we can use -// DecodeStencilFuncOps on both of them. -#define CHECK_CCW_MATCHES_CW(FIELD) \ - COMPILE_ASSERT(o3d::SetStencilTest::CW ## FIELD::kLength == \ - o3d::SetStencilTest::CCW ## FIELD::kLength, \ - CCW ## FIELD ## _length_does_not_match_ ## CW ## FIELD); \ - COMPILE_ASSERT(o3d::SetStencilTest::CW ## FIELD::kShift + 16 == \ - o3d::SetStencilTest::CCW ## FIELD::kShift, \ - CCW ## FIELD ## _shift_does_not_match_ ## CW ## FIELD) - -CHECK_CCW_MATCHES_CW(Func); -CHECK_CCW_MATCHES_CW(PassOp); -CHECK_CCW_MATCHES_CW(FailOp); -CHECK_CCW_MATCHES_CW(ZFailOp); - -#undef CHECK_CCW_MATCHES_CW - -// Decodes stencil test function and operations from the bitfield. -void DecodeStencilFuncOps(Uint32 params, - GLenum *func, - GLenum *pass, - GLenum *fail, - GLenum *zfail) { - // Sanity check. The value has already been tested in - // GAPIDecoder::DecodeSetStencilTest in gapi_decoder.cc. - DCHECK_EQ(o3d::SetStencilTest::Unused1::Get(params), 0); - // Check that the bitmask get cannot generate values outside of the allowed - // range. - COMPILE_ASSERT(o3d::SetStencilTest::CWFunc::kMask < - o3d::kNumComparison, - set_stencil_test_CWFunc_may_produce_invalid_values); - *func = kGLComparison[o3d::SetStencilTest::CWFunc::Get(params)]; - - COMPILE_ASSERT(o3d::SetStencilTest::CWPassOp::kMask < - o3d::kNumStencilOp, - set_stencil_test_CWPassOp_may_produce_invalid_values); - *pass = kGLStencilOp[o3d::SetStencilTest::CWPassOp::Get(params)]; - - COMPILE_ASSERT(o3d::SetStencilTest::CWFailOp::kMask < - o3d::kNumStencilOp, - set_stencil_test_CWFailOp_may_produce_invalid_values); - *fail = kGLStencilOp[o3d::SetStencilTest::CWFailOp::Get(params)]; - - COMPILE_ASSERT(o3d::SetStencilTest::CWZFailOp::kMask < - o3d::kNumStencilOp, - set_stencil_test_CWZFailOp_may_produce_invalid_values); - *zfail = kGLStencilOp[o3d::SetStencilTest::CWZFailOp::Get(params)]; -} - -} // anonymous namespace - -void GAPIGL::SetViewport(unsigned int x, - unsigned int y, - unsigned int width, - unsigned int height, - float z_min, - float z_max) { - glViewport(x, y, width, height); - glDepthRange(z_min, z_max); - // Update the helper constant used for the D3D -> GL remapping. - // See effect_gl.cc for details. - glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 0, - 1.f / width, 1.f / height, 2.f, 0.f); - CHECK_GL_ERROR(); -} - -void GAPIGL::SetScissor(bool enable, - unsigned int x, - unsigned int y, - unsigned int width, - unsigned int height) { - if (enable) { - glEnable(GL_SCISSOR_TEST); - glScissor(x, y, width, height); - } else { - glDisable(GL_SCISSOR_TEST); - } -} - -void GAPIGL::SetPointLineRaster(bool line_smooth, - bool point_sprite, - float point_size) { - if (line_smooth) { - glEnable(GL_LINE_SMOOTH); - } else { - glDisable(GL_LINE_SMOOTH); - } - if (point_sprite) { - glEnable(GL_POINT_SPRITE); - // TODO: check which TC gets affected by point sprites in D3D. - glActiveTextureARB(GL_TEXTURE0); - glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); - } else { - glActiveTextureARB(GL_TEXTURE0); - glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_FALSE); - glDisable(GL_POINT_SPRITE); - } - glPointSize(point_size); -} - -void GAPIGL::SetPolygonOffset(float slope_factor, float units) { - glPolygonOffset(slope_factor, units); -} - -void GAPIGL::SetPolygonRaster(o3d::PolygonMode fill_mode, - o3d::FaceCullMode cull_mode) { - DCHECK_LT(fill_mode, kNumPolygonMode); - glPolygonMode(GL_FRONT_AND_BACK, kGLPolygonModes[fill_mode]); - DCHECK_LT(cull_mode, kNumFaceCullMode); - switch (cull_mode) { - case kCullCW: - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - break; - case kCullCCW: - glEnable(GL_CULL_FACE); - glCullFace(GL_FRONT); - break; - default: - glDisable(GL_CULL_FACE); - break; - } -} - -void GAPIGL::SetAlphaTest(bool enable, - float reference, - o3d::Comparison comp) { - DCHECK_LT(comp, kNumComparison); - if (enable) { - glEnable(GL_ALPHA_TEST); - glAlphaFunc(kGLComparison[comp], reference); - } else { - glDisable(GL_ALPHA_TEST); - } -} - -void GAPIGL::SetDepthTest(bool enable, - bool write_enable, - o3d::Comparison comp) { - DCHECK_LT(comp, kNumComparison); - if (enable) { - glEnable(GL_DEPTH_TEST); - glDepthFunc(kGLComparison[comp]); - } else { - glDisable(GL_DEPTH_TEST); - } - glDepthMask(write_enable); -} - -void GAPIGL::SetStencilTest(bool enable, - bool separate_ccw, - unsigned int write_mask, - unsigned int compare_mask, - unsigned int ref, - Uint32 func_ops) { - if (enable) { - glEnable(GL_STENCIL_TEST); - glStencilMask(write_mask); - - GLenum func; - GLenum pass; - GLenum fail; - GLenum zfail; - DecodeStencilFuncOps(func_ops, &func, &pass, &fail, &zfail); - if (separate_ccw) { - glStencilFuncSeparate(GL_FRONT, func, ref, compare_mask); - glStencilOpSeparate(GL_FRONT, pass, fail, zfail); - // Extract upper 16 bits. - Uint32 ccw_func_ops = BitField<16, 16>::Get(func_ops); - GLenum ccw_func; - GLenum ccw_pass; - GLenum ccw_fail; - GLenum ccw_zfail; - DecodeStencilFuncOps(ccw_func_ops, &ccw_func, &ccw_pass, &ccw_fail, - &ccw_zfail); - glStencilFuncSeparate(GL_BACK, ccw_func, ref, compare_mask); - glStencilOpSeparate(GL_BACK, ccw_pass, ccw_fail, ccw_zfail); - } else { - glStencilFunc(func, ref, compare_mask); - glStencilOp(pass, fail, zfail); - } - } else { - glDisable(GL_STENCIL_TEST); - } -} - -void GAPIGL::SetColorWrite(bool red, - bool green, - bool blue, - bool alpha, - bool dither) { - glColorMask(red, green, blue, alpha); - if (dither) { - glEnable(GL_DITHER); - } else { - glDisable(GL_DITHER); - } -} - -void GAPIGL::SetBlending(bool enable, - bool separate_alpha, - BlendEq color_eq, - BlendFunc color_src_func, - BlendFunc color_dst_func, - BlendEq alpha_eq, - BlendFunc alpha_src_func, - BlendFunc alpha_dst_func) { - DCHECK_LT(color_eq, kNumBlendEq); - DCHECK_LT(color_src_func, kNumBlendFunc); - DCHECK_LT(color_dst_func, kNumBlendFunc); - DCHECK_LT(alpha_eq, kNumBlendEq); - DCHECK_LT(alpha_src_func, kNumBlendFunc); - DCHECK_LT(alpha_dst_func, kNumBlendFunc); - if (enable) { - glEnable(GL_BLEND); - GLenum gl_color_eq = kGLBlendEq[color_eq]; - GLenum gl_color_src_func = kGLBlendFunc[color_src_func]; - GLenum gl_color_dst_func = kGLBlendFunc[color_dst_func]; - if (separate_alpha) { - GLenum gl_alpha_eq = kGLBlendEq[alpha_eq]; - GLenum gl_alpha_src_func = kGLBlendFunc[alpha_src_func]; - GLenum gl_alpha_dst_func = kGLBlendFunc[alpha_dst_func]; - glBlendFuncSeparate(gl_color_src_func, gl_color_dst_func, - gl_alpha_src_func, gl_alpha_dst_func); - glBlendEquationSeparate(gl_color_eq, gl_alpha_eq); - } else { - glBlendFunc(gl_color_src_func, gl_color_dst_func); - glBlendEquation(gl_color_eq); - } - } else { - glDisable(GL_BLEND); - } -} - -void GAPIGL::SetBlendingColor(const RGBA &color) { - glBlendColor(color.red, color.green, color.blue, color.alpha); -} - -} // namespace o3d -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/service/texture_d3d9.cc b/o3d/gpu/command_buffer/service/texture_d3d9.cc deleted file mode 100644 index 9f25ff0..0000000 --- a/o3d/gpu/command_buffer/service/texture_d3d9.cc +++ /dev/null @@ -1,731 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file implements the D3D9 versions of the texture resources, as well as -// the related GAPID3D9 function implementations. - -#include "gpu/command_buffer/service/precompile.h" -#include "gpu/command_buffer/service/gapi_d3d9.h" -#include "gpu/command_buffer/service/texture_d3d9.h" - -namespace command_buffer { -namespace o3d { - -// Converts a texture format to a D3D texture format. -D3DFORMAT TextureD3D9::D3DFormat(texture::Format format) { - switch (format) { - case texture::kXRGB8: return D3DFMT_X8R8G8B8; - case texture::kARGB8: return D3DFMT_A8R8G8B8; - case texture::kABGR16F: return D3DFMT_A16B16G16R16F; - case texture::kR32F: return D3DFMT_R32F; - case texture::kABGR32F: return D3DFMT_A32B32G32R32F; - case texture::kDXT1: return D3DFMT_DXT1; - // TODO(petersont): Add DXT3/5 support. - default: return D3DFMT_UNKNOWN; - }; -} - -// Converts a cube map face to a D3D face. -D3DCUBEMAP_FACES TextureD3D9::D3DFace(texture::Face face) { - switch (face) { - case texture::kFacePositiveX: - return D3DCUBEMAP_FACE_POSITIVE_X; - case texture::kFaceNegativeX: - return D3DCUBEMAP_FACE_NEGATIVE_X; - case texture::kFacePositiveY: - return D3DCUBEMAP_FACE_POSITIVE_Y; - case texture::kFaceNegativeY: - return D3DCUBEMAP_FACE_NEGATIVE_Y; - case texture::kFacePositiveZ: - return D3DCUBEMAP_FACE_POSITIVE_Z; - case texture::kFaceNegativeZ: - return D3DCUBEMAP_FACE_NEGATIVE_Z; - } - LOG(FATAL) << "Not reached."; - return D3DCUBEMAP_FACE_POSITIVE_X; -} - -// Texture 2D functions - -// Destroys the 2D texture, releasing the D3D texture, and its shadow if any. -Texture2DD3D9::~Texture2DD3D9() { - DCHECK(d3d_texture_); - d3d_texture_ = NULL; - if (d3d_shadow_) { - d3d_shadow_->Release(); - d3d_shadow_ = NULL; - } -} - -// Creates a 2D texture. For dynamic textures, create it in the default pool, -// and a shadow version in the system memory pool (that we can lock). For -// regular texture, simply create one in the managed pool. -Texture2DD3D9 *Texture2DD3D9::Create(GAPID3D9 *gapi, - unsigned int width, - unsigned int height, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces) { - DCHECK_GT(width, 0U); - DCHECK_GT(height, 0U); - DCHECK_GT(levels, 0U); - D3DFORMAT d3d_format = D3DFormat(format); - IDirect3DDevice9 *device = gapi->d3d_device(); - if (enable_render_surfaces) { - CComPtr d3d_texture = NULL; - HRESULT result = device->CreateTexture(width, height, levels, - D3DUSAGE_RENDERTARGET, d3d_format, - D3DPOOL_DEFAULT, &d3d_texture, - NULL); - if (result != D3D_OK) { - LOG(ERROR) << "DirectX error when calling CreateTexture: " - << DXGetErrorStringA(result); - return NULL; - } - return new Texture2DD3D9(levels, format, flags, width, height, d3d_texture, - NULL, enable_render_surfaces); - } else if (flags & texture::kDynamic) { - CComPtr d3d_texture = NULL; - HRESULT result = device->CreateTexture(width, height, levels, - D3DUSAGE_DYNAMIC, d3d_format, - D3DPOOL_DEFAULT, &d3d_texture, - NULL); - if (result != D3D_OK) { - LOG(ERROR) << "DirectX error when calling CreateTexture: " - << DXGetErrorStringA(result); - return NULL; - } - CComPtr d3d_shadow = NULL; - result = device->CreateTexture(width, height, levels, D3DUSAGE_DYNAMIC, - d3d_format, D3DPOOL_SYSTEMMEM, &d3d_shadow, - NULL); - if (result != D3D_OK) { - LOG(ERROR) << "DirectX error when calling CreateTexture: " - << DXGetErrorStringA(result); - return NULL; - } - return new Texture2DD3D9(levels, format, flags, width, height, d3d_texture, - d3d_shadow, enable_render_surfaces); - } else { - CComPtr d3d_texture = NULL; - HRESULT result = device->CreateTexture(width, height, levels, 0, d3d_format, - D3DPOOL_MANAGED, &d3d_texture, NULL); - if (result != D3D_OK) { - LOG(ERROR) << "DirectX error when calling CreateTexture: " - << DXGetErrorStringA(result); - return NULL; - } - return new Texture2DD3D9(levels, format, flags, width, height, d3d_texture, - NULL, enable_render_surfaces); - } -} - -// Sets the data in the texture, using LockRect()/UnlockRect(). For dynamic -// textures, it copies the data to the shadow texture, then updates the actual -// texture. For regular texture, it directly modifies the actual texture. -bool Texture2DD3D9::SetData(GAPID3D9 *gapi, - const Volume &volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - const void *data) { - DCHECK(d3d_texture_); - IDirect3DTexture9 *lock_texture = d3d_shadow_ ? d3d_shadow_ : d3d_texture_; - - MipLevelInfo mip_info; - MakeMipLevelInfo(&mip_info, format(), width_, height_, 1, level); - TransferInfo src_transfer_info; - MakeTransferInfo(&src_transfer_info, mip_info, volume, row_pitch, - slice_pitch); - if (!CheckVolume(mip_info, volume) || level >= levels() || - size < src_transfer_info.total_size) - return false; - - bool full_rect = IsFullVolume(mip_info, volume); - D3DLOCKED_RECT locked_rect; - RECT rect = {volume.x, volume.y, volume.x+volume.width, - volume.y+volume.height}; - DWORD lock_flags = - full_rect && (flags() & texture::kDynamic) ? D3DLOCK_DISCARD : 0; - HR(lock_texture->LockRect(level, &locked_rect, full_rect ? NULL : &rect, - lock_flags)); - - TransferInfo dst_transfer_info; - MakeTransferInfo(&dst_transfer_info, mip_info, volume, locked_rect.Pitch, - slice_pitch); - TransferVolume(volume, mip_info, dst_transfer_info, locked_rect.pBits, - src_transfer_info, data); - - HR(lock_texture->UnlockRect(level)); - if (d3d_shadow_) { - HR(gapi->d3d_device()->UpdateTexture(d3d_shadow_, d3d_texture_)); - } - return true; -} - -// Gets the data from the texture, using LockRect()/UnlockRect(). For dynamic -// textures, it gets the data from the shadow texture, For regular texture, it -// gets it directly from the actual texture. -bool Texture2DD3D9::GetData(GAPID3D9 *gapi, - const Volume &volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - void *data) { - DCHECK(d3d_texture_); - IDirect3DTexture9 *lock_texture = d3d_shadow_ ? d3d_shadow_ : d3d_texture_; - - MipLevelInfo mip_info; - MakeMipLevelInfo(&mip_info, format(), width_, height_, 1, level); - TransferInfo dst_transfer_info; - MakeTransferInfo(&dst_transfer_info, mip_info, volume, row_pitch, - slice_pitch); - if (!CheckVolume(mip_info, volume) || level >= levels() || - size < dst_transfer_info.total_size) - return false; - - bool full_rect = IsFullVolume(mip_info, volume); - D3DLOCKED_RECT locked_rect; - RECT rect = {volume.x, volume.y, volume.x+volume.width, - volume.y+volume.height}; - DWORD lock_flags = D3DLOCK_READONLY; - HR(lock_texture->LockRect(level, &locked_rect, full_rect ? NULL : &rect, - lock_flags)); - TransferInfo src_transfer_info; - MakeTransferInfo(&src_transfer_info, mip_info, volume, locked_rect.Pitch, - slice_pitch); - TransferVolume(volume, mip_info, dst_transfer_info, data, - src_transfer_info, locked_rect.pBits); - HR(lock_texture->UnlockRect(level)); - return true; -} - -bool Texture2DD3D9::CreateRenderSurface(int width, - int height, - int mip_level, - int side, - IDirect3DSurface9** direct3d_surface) { - IDirect3DTexture9* d3d_texture = - static_cast(d3d_base_texture()); - D3DSURFACE_DESC surface_desc; - d3d_texture->GetLevelDesc(mip_level, &surface_desc); - if (width != surface_desc.Width || height != surface_desc.Height) { - return false; - } - HR(d3d_texture->GetSurfaceLevel(mip_level, direct3d_surface)); - return true; -} - -// Texture 3D functions - -// Destroys the 3D texture. -Texture3DD3D9::~Texture3DD3D9() { - DCHECK(d3d_texture_); - d3d_texture_ = NULL; - if (d3d_shadow_) { - d3d_shadow_->Release(); - d3d_shadow_ = NULL; - } -} - -// Creates a 3D texture. For dynamic textures, create it in the default pool, -// and a shadow version in the system memory pool (that we can lock). For -// regular texture, simply create one in the managed pool. -Texture3DD3D9 *Texture3DD3D9::Create(GAPID3D9 *gapi, - unsigned int width, - unsigned int height, - unsigned int depth, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces) { - DCHECK_GT(width, 0U); - DCHECK_GT(height, 0U); - DCHECK_GT(depth, 0U); - DCHECK_GT(levels, 0U); - D3DFORMAT d3d_format = D3DFormat(format); - IDirect3DDevice9 *device = gapi->d3d_device(); - if (enable_render_surfaces) { - CComPtr d3d_texture = NULL; - HRESULT result = device->CreateVolumeTexture(width, height, depth, levels, - D3DUSAGE_RENDERTARGET, - d3d_format, D3DPOOL_DEFAULT, - &d3d_texture, NULL); - if (result != D3D_OK) { - LOG(ERROR) << "DirectX error when calling CreateTexture: " - << DXGetErrorStringA(result); - return NULL; - } - return new Texture3DD3D9(levels, format, flags, width, height, depth, - d3d_texture, NULL, enable_render_surfaces); - } else if (flags & texture::kDynamic) { - CComPtr d3d_texture = NULL; - HRESULT result = device->CreateVolumeTexture(width, height, depth, levels, - D3DUSAGE_DYNAMIC, d3d_format, - D3DPOOL_DEFAULT, &d3d_texture, - NULL); - if (result != D3D_OK) { - LOG(ERROR) << "DirectX error when calling CreateTexture: " - << DXGetErrorStringA(result); - return NULL; - } - CComPtr d3d_shadow = NULL; - result = device->CreateVolumeTexture(width, height, depth, levels, - D3DUSAGE_DYNAMIC, d3d_format, - D3DPOOL_SYSTEMMEM, &d3d_shadow, NULL); - if (result != D3D_OK) { - LOG(ERROR) << "DirectX error when calling CreateTexture: " - << DXGetErrorStringA(result); - return NULL; - } - return new Texture3DD3D9(levels, format, flags, width, height, depth, - d3d_texture, d3d_shadow, enable_render_surfaces); - } else { - CComPtr d3d_texture = NULL; - HRESULT result = device->CreateVolumeTexture(width, height, depth, levels, - D3DUSAGE_DYNAMIC, d3d_format, - D3DPOOL_MANAGED, &d3d_texture, - NULL); - if (result != D3D_OK) { - LOG(ERROR) << "DirectX error when calling CreateTexture: " - << DXGetErrorStringA(result); - return NULL; - } - return new Texture3DD3D9(levels, format, flags, width, height, depth, - d3d_texture, NULL, enable_render_surfaces); - } -} - -// Sets the data in the texture, using LockBox()/UnlockBox(). For dynamic -// textures, it copies the data to the shadow texture, then updates the actual -// texture. For regular texture, it directly modifies the actual texture. -bool Texture3DD3D9::SetData(GAPID3D9 *gapi, - const Volume &volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - const void *data) { - DCHECK(d3d_texture_); - IDirect3DVolumeTexture9 *lock_texture = - d3d_shadow_ ? d3d_shadow_ : d3d_texture_; - - MipLevelInfo mip_info; - MakeMipLevelInfo(&mip_info, format(), width_, height_, depth_, level); - TransferInfo src_transfer_info; - MakeTransferInfo(&src_transfer_info, mip_info, volume, row_pitch, - slice_pitch); - if (!CheckVolume(mip_info, volume) || level >= levels() || - size < src_transfer_info.total_size) - return false; - - bool full_box = IsFullVolume(mip_info, volume); - D3DLOCKED_BOX locked_box; - D3DBOX box = {volume.x, volume.y, volume.z, volume.x+volume.width, - volume.y+volume.height, volume.z+volume.depth}; - DWORD lock_flags = - full_box && (flags() & texture::kDynamic) ? D3DLOCK_DISCARD : 0; - HR(lock_texture->LockBox(level, &locked_box, full_box ? NULL : &box, - lock_flags)); - - TransferInfo dst_transfer_info; - MakeTransferInfo(&dst_transfer_info, mip_info, volume, locked_box.RowPitch, - locked_box.SlicePitch); - TransferVolume(volume, mip_info, dst_transfer_info, locked_box.pBits, - src_transfer_info, data); - - HR(lock_texture->UnlockBox(level)); - if (d3d_shadow_) { - HR(gapi->d3d_device()->UpdateTexture(d3d_shadow_, d3d_texture_)); - } - return true; -} - -// Gets the data from the texture, using LockBox()/UnlockBox(). For dynamic -// textures, it gets the data from the shadow texture, For regular texture, it -// gets it directly from the actual texture. -bool Texture3DD3D9::GetData(GAPID3D9 *gapi, - const Volume &volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - void *data) { - DCHECK(d3d_texture_); - IDirect3DVolumeTexture9 *lock_texture = - d3d_shadow_ ? d3d_shadow_ : d3d_texture_; - - MipLevelInfo mip_info; - MakeMipLevelInfo(&mip_info, format(), width_, height_, depth_, level); - TransferInfo dst_transfer_info; - MakeTransferInfo(&dst_transfer_info, mip_info, volume, row_pitch, - slice_pitch); - if (!CheckVolume(mip_info, volume) || level >= levels() || - size < dst_transfer_info.total_size) - return false; - - bool full_box = IsFullVolume(mip_info, volume); - D3DLOCKED_BOX locked_box; - D3DBOX box = {volume.x, volume.y, volume.z, volume.x+volume.width, - volume.y+volume.height, volume.z+volume.depth}; - DWORD lock_flags = D3DLOCK_READONLY; - HR(lock_texture->LockBox(level, &locked_box, full_box ? NULL : &box, - lock_flags)); - TransferInfo src_transfer_info; - MakeTransferInfo(&src_transfer_info, mip_info, volume, locked_box.RowPitch, - locked_box.SlicePitch); - TransferVolume(volume, mip_info, dst_transfer_info, data, - src_transfer_info, locked_box.pBits); - HR(lock_texture->UnlockBox(level)); - return true; -} - -bool Texture3DD3D9::CreateRenderSurface(int width, - int height, - int mip_level, - int side, - IDirect3DSurface9** direct3d_surface) { - // TODO(rlp): Currently unsupported. - DCHECK(false); - return false; -} - -// Texture Cube functions. - -// Destroys the cube map texture, releasing the D3D texture, and its shadow if -// any. -TextureCubeD3D9::~TextureCubeD3D9() { - DCHECK(d3d_texture_); - d3d_texture_ = NULL; - if (d3d_shadow_) { - d3d_shadow_->Release(); - d3d_shadow_ = NULL; - } -} - -// Creates a cube map texture. For dynamic textures, create it in the default -// pool, and a shadow version in the system memory pool (that we can lock). For -// regular texture, simply create one in the managed pool. -TextureCubeD3D9 *TextureCubeD3D9::Create(GAPID3D9 *gapi, - unsigned int side, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces) { - DCHECK_GT(side, 0U); - DCHECK_GT(levels, 0U); - D3DFORMAT d3d_format = D3DFormat(format); - IDirect3DDevice9 *device = gapi->d3d_device(); - if (enable_render_surfaces) { - CComPtr d3d_texture = NULL; - HRESULT result = device->CreateCubeTexture(side, levels, - D3DUSAGE_RENDERTARGET, - d3d_format, D3DPOOL_DEFAULT, - &d3d_texture, NULL); - if (result != D3D_OK) { - LOG(ERROR) << "DirectX error when calling CreateTexture: " - << DXGetErrorStringA(result); - return NULL; - } - return new TextureCubeD3D9(levels, format, flags, side, d3d_texture, NULL, - enable_render_surfaces); - } else if (flags & texture::kDynamic) { - CComPtr d3d_texture = NULL; - HRESULT result = device->CreateCubeTexture(side, levels, D3DUSAGE_DYNAMIC, - d3d_format, D3DPOOL_DEFAULT, - &d3d_texture, NULL); - if (result != D3D_OK) { - LOG(ERROR) << "DirectX error when calling CreateTexture: " - << DXGetErrorStringA(result); - return NULL; - } - CComPtr d3d_shadow = NULL; - result = device->CreateCubeTexture(side, levels, D3DUSAGE_DYNAMIC, - d3d_format, D3DPOOL_SYSTEMMEM, - &d3d_shadow, NULL); - if (result != D3D_OK) { - LOG(ERROR) << "DirectX error when calling CreateTexture: " - << DXGetErrorStringA(result); - return NULL; - } - return new TextureCubeD3D9(levels, format, flags, side, d3d_texture, - d3d_shadow, enable_render_surfaces); - } else { - CComPtr d3d_texture = NULL; - HRESULT result = device->CreateCubeTexture(side, levels, 0, d3d_format, - D3DPOOL_MANAGED, &d3d_texture, - NULL); - if (result != D3D_OK) { - LOG(ERROR) << "DirectX error when calling CreateTexture: " - << DXGetErrorStringA(result); - return NULL; - } - return new TextureCubeD3D9(levels, format, flags, side, d3d_texture, NULL, - enable_render_surfaces); - } -} - -// Sets the data in the texture, using LockRect()/UnlockRect(). For dynamic -// textures, it copies the data to the shadow texture, then updates the actual -// texture. For regular texture, it directly modifies the actual texture. -bool TextureCubeD3D9::SetData(GAPID3D9 *gapi, - const Volume &volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - const void *data) { - DCHECK(d3d_texture_); - IDirect3DCubeTexture9 *lock_texture = - d3d_shadow_ ? d3d_shadow_ : d3d_texture_; - MipLevelInfo mip_info; - MakeMipLevelInfo(&mip_info, format(), side_, side_, 1, level); - TransferInfo src_transfer_info; - MakeTransferInfo(&src_transfer_info, mip_info, volume, row_pitch, - slice_pitch); - if (!CheckVolume(mip_info, volume) || level >= levels() || - size < src_transfer_info.total_size) - return false; - - D3DCUBEMAP_FACES d3d_face = D3DFace(face); - bool full_rect = IsFullVolume(mip_info, volume); - D3DLOCKED_RECT locked_rect; - RECT rect = {volume.x, volume.y, volume.x+volume.width, - volume.y+volume.height}; - DWORD lock_flags = - full_rect && (flags() & texture::kDynamic) ? D3DLOCK_DISCARD : 0; - HR(lock_texture->LockRect(d3d_face, level, &locked_rect, - full_rect ? NULL : &rect, lock_flags)); - - TransferInfo dst_transfer_info; - MakeTransferInfo(&dst_transfer_info, mip_info, volume, locked_rect.Pitch, - slice_pitch); - TransferVolume(volume, mip_info, dst_transfer_info, locked_rect.pBits, - src_transfer_info, data); - - HR(lock_texture->UnlockRect(d3d_face, level)); - if (d3d_shadow_) { - HR(gapi->d3d_device()->UpdateTexture(d3d_shadow_, d3d_texture_)); - } - return true; -} - -// Gets the data from the texture, using LockRect()/UnlockRect(). For dynamic -// textures, it gets the data from the shadow texture, For regular texture, it -// gets it directly from the actual texture. -bool TextureCubeD3D9::GetData(GAPID3D9 *gapi, - const Volume &volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - void *data) { - DCHECK(d3d_texture_); - IDirect3DCubeTexture9 *lock_texture = - d3d_shadow_ ? d3d_shadow_ : d3d_texture_; - - MipLevelInfo mip_info; - MakeMipLevelInfo(&mip_info, format(), side_, side_, 1, level); - TransferInfo dst_transfer_info; - MakeTransferInfo(&dst_transfer_info, mip_info, volume, row_pitch, - slice_pitch); - if (!CheckVolume(mip_info, volume) || level >= levels() || - size < dst_transfer_info.total_size) - return false; - - D3DCUBEMAP_FACES d3d_face = D3DFace(face); - bool full_rect = IsFullVolume(mip_info, volume); - D3DLOCKED_RECT locked_rect; - RECT rect = {volume.x, volume.y, volume.x+volume.width, - volume.y+volume.height}; - DWORD lock_flags = D3DLOCK_READONLY; - HR(lock_texture->LockRect(d3d_face, level, &locked_rect, - full_rect ? NULL : &rect, lock_flags)); - TransferInfo src_transfer_info; - MakeTransferInfo(&src_transfer_info, mip_info, volume, locked_rect.Pitch, - slice_pitch); - TransferVolume(volume, mip_info, dst_transfer_info, data, - src_transfer_info, locked_rect.pBits); - HR(lock_texture->UnlockRect(d3d_face, level)); - return true; -} - -bool TextureCubeD3D9::CreateRenderSurface( - int width, - int height, - int mip_level, - int side, - IDirect3DSurface9** direct3d_surface) { - IDirect3DCubeTexture9* d3d_cube_texture = - static_cast(d3d_base_texture()); - D3DSURFACE_DESC surface_desc; - d3d_cube_texture->GetLevelDesc(mip_level, &surface_desc); - if (width != surface_desc.Width || height != surface_desc.Height || - side < 0 || side > 5) { - return false; - } - HR(d3d_cube_texture->GetCubeMapSurface( - D3DFace(static_cast(side)), - mip_level, - direct3d_surface)); - return true; -} - -// GAPID3D9 functions. - -// Destroys a texture resource. -parse_error::ParseError GAPID3D9::DestroyTexture(ResourceId id) { - // Dirty effect, because this texture id may be used - DirtyEffect(); - return textures_.Destroy(id) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -// Creates a 2D texture resource. -parse_error::ParseError GAPID3D9::CreateTexture2D( - ResourceId id, - unsigned int width, - unsigned int height, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces) { - Texture2DD3D9 *texture = Texture2DD3D9::Create(this, width, height, levels, - format, flags, - enable_render_surfaces); - if (!texture) return parse_error::kParseInvalidArguments; - // Dirty effect, because this texture id may be used - DirtyEffect(); - textures_.Assign(id, texture); - return parse_error::kParseNoError; -} - -// Creates a 3D texture resource. -parse_error::ParseError GAPID3D9::CreateTexture3D( - ResourceId id, - unsigned int width, - unsigned int height, - unsigned int depth, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces) { - Texture3DD3D9 *texture = Texture3DD3D9::Create(this, width, height, depth, - levels, format, flags, - enable_render_surfaces); - if (!texture) return parse_error::kParseInvalidArguments; - // Dirty effect, because this texture id may be used - DirtyEffect(); - textures_.Assign(id, texture); - return parse_error::kParseNoError; -} - -// Creates a cube map texture resource. -parse_error::ParseError GAPID3D9::CreateTextureCube( - ResourceId id, - unsigned int side, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces) { - TextureCubeD3D9 *texture = TextureCubeD3D9::Create(this, side, levels, - format, flags, - enable_render_surfaces); - if (!texture) return parse_error::kParseInvalidArguments; - // Dirty effect, because this texture id may be used - DirtyEffect(); - textures_.Assign(id, texture); - return parse_error::kParseNoError; -} - -// Copies the data into a texture resource. -parse_error::ParseError GAPID3D9::SetTextureData( - ResourceId id, - unsigned int x, - unsigned int y, - unsigned int z, - unsigned int width, - unsigned int height, - unsigned int depth, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - const void *data) { - TextureD3D9 *texture = textures_.Get(id); - if (!texture) - return parse_error::kParseInvalidArguments; - Volume volume = {x, y, z, width, height, depth}; - return texture->SetData(this, volume, level, face, row_pitch, slice_pitch, - size, data) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -// Copies the data from a texture resource. -parse_error::ParseError GAPID3D9::GetTextureData( - ResourceId id, - unsigned int x, - unsigned int y, - unsigned int z, - unsigned int width, - unsigned int height, - unsigned int depth, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - void *data) { - TextureD3D9 *texture = textures_.Get(id); - if (!texture) - return parse_error::kParseInvalidArguments; - Volume volume = {x, y, z, width, height, depth}; - return texture->GetData(this, volume, level, face, row_pitch, slice_pitch, - size, data) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -} // namespace o3d -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/service/texture_d3d9.h b/o3d/gpu/command_buffer/service/texture_d3d9.h deleted file mode 100644 index de913a8..0000000 --- a/o3d/gpu/command_buffer/service/texture_d3d9.h +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -#ifndef GPU_COMMAND_BUFFER_SERVICE_TEXTURE_D3D9_H_ -#define GPU_COMMAND_BUFFER_SERVICE_TEXTURE_D3D9_H_ - -// This file contains the definition of the D3D9 versions of texture-related -// resource classes. -#include - -#include "gpu/command_buffer/common/gapi_interface.h" -#include "gpu/command_buffer/service/d3d9_utils.h" -#include "gpu/command_buffer/service/resource.h" -#include "gpu/command_buffer/service/texture_utils.h" - -namespace command_buffer { -namespace o3d { - -class GAPID3D9; - -// The base class for a D3D texture resource, providing access to the base D3D -// texture that can be assigned to an effect parameter or a sampler unit. -class TextureD3D9 : public Texture { - public: - TextureD3D9(texture::Type type, - unsigned int levels, - texture::Format format, - bool enable_render_surfaces, - unsigned int flags) - : Texture(type, levels, format, enable_render_surfaces, flags) {} - // Gets the D3D base texture. - virtual IDirect3DBaseTexture9 *d3d_base_texture() const = 0; - // Sets data into a texture resource. - virtual bool SetData(GAPID3D9 *gapi, - const Volume& volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - const void *data) = 0; - // Gets data from a texture resource. - virtual bool GetData(GAPID3D9 *gapi, - const Volume& volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - void *data) = 0; - // Creates the render surface, returning false if unable to. - virtual bool CreateRenderSurface(int width, - int height, - int mip_level, - int side, - IDirect3DSurface9** direct3d_surface) = 0; - static D3DFORMAT D3DFormat(texture::Format format); - static D3DCUBEMAP_FACES D3DFace(texture::Face face); - private: - DISALLOW_COPY_AND_ASSIGN(TextureD3D9); -}; - -// A 2D texture resource for D3D. -class Texture2DD3D9 : public TextureD3D9 { - public: - Texture2DD3D9(unsigned int levels, - texture::Format format, - unsigned int flags, - unsigned int width, - unsigned int height, - IDirect3DTexture9 *texture, - IDirect3DTexture9 *shadow, - bool enable_render_surfaces) - : TextureD3D9(texture::kTexture2d, levels, format, - enable_render_surfaces, flags), - width_(width), - height_(height), - d3d_texture_(texture), - d3d_shadow_(shadow) {} - virtual ~Texture2DD3D9(); - - // Creates a 2D texture resource. - static Texture2DD3D9 *Create(GAPID3D9 *gapi, - unsigned int width, - unsigned int height, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces); - // Sets data into a 2D texture resource. - virtual bool SetData(GAPID3D9 *gapi, - const Volume& volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - const void *data); - // Gets data from a 2D texture resource. - virtual bool GetData(GAPID3D9 *gapi, - const Volume& volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - void *data); - // Create a render surface which matches this texture type. - virtual bool CreateRenderSurface(int width, - int height, - int mip_level, - int side, - IDirect3DSurface9** direct3d_surface); - // Gets the D3D base texture. - virtual IDirect3DBaseTexture9 *d3d_base_texture() const { - return d3d_texture_; - } - private: - unsigned int width_; - unsigned int height_; - CComPtr d3d_texture_; - IDirect3DTexture9 *d3d_shadow_; - DISALLOW_COPY_AND_ASSIGN(Texture2DD3D9); -}; - -// A 3D texture resource for D3D. -class Texture3DD3D9 : public TextureD3D9 { - public: - Texture3DD3D9(unsigned int levels, - texture::Format format, - unsigned int flags, - unsigned int width, - unsigned int height, - unsigned int depth, - IDirect3DVolumeTexture9 *texture, - IDirect3DVolumeTexture9 *shadow, - bool enable_render_surfaces) - : TextureD3D9(texture::kTexture3d, levels, format, - enable_render_surfaces, flags), - width_(width), - height_(height), - depth_(depth), - d3d_texture_(texture), - d3d_shadow_(shadow) {} - virtual ~Texture3DD3D9(); - // Creates a 3D texture resource. - static Texture3DD3D9 *Create(GAPID3D9 *gapi, - unsigned int width, - unsigned int height, - unsigned int depth, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces); - // Sets data into a 3D texture resource. - virtual bool SetData(GAPID3D9 *gapi, - const Volume& volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - const void *data); - // Gets data from a 3D texture resource. - virtual bool GetData(GAPID3D9 *gapi, - const Volume& volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - void *data); - // Create a render surface which matches this texture type. - virtual bool CreateRenderSurface(int width, - int height, - int mip_level, - int side, - IDirect3DSurface9** direct3d_surface); - // Gets the D3D base texture. - virtual IDirect3DBaseTexture9 *d3d_base_texture() const { - return d3d_texture_; - } - private: - unsigned int width_; - unsigned int height_; - unsigned int depth_; - CComPtr d3d_texture_; - IDirect3DVolumeTexture9 *d3d_shadow_; - DISALLOW_COPY_AND_ASSIGN(Texture3DD3D9); -}; - -// A cube map texture resource for D3D. -class TextureCubeD3D9 : public TextureD3D9 { - public: - TextureCubeD3D9(unsigned int levels, - texture::Format format, - unsigned int flags, - unsigned int side, - IDirect3DCubeTexture9 *texture, - IDirect3DCubeTexture9 *shadow, - bool enable_render_surfaces) - : TextureD3D9(texture::kTextureCube, levels, format, - enable_render_surfaces, flags), - side_(side), - d3d_texture_(texture), - d3d_shadow_(shadow) {} - virtual ~TextureCubeD3D9(); - // Creates a cube map texture resource. - static TextureCubeD3D9 *Create(GAPID3D9 *gapi, - unsigned int side, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces); - // Sets data into a cube map texture resource. - virtual bool SetData(GAPID3D9 *gapi, - const Volume& volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - const void *data); - // Gets data from a cube map texture resource. - virtual bool GetData(GAPID3D9 *gapi, - const Volume& volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - void *data); - // Create a render surface which matches this texture type. - virtual bool CreateRenderSurface(int width, - int height, - int mip_level, - int side, - IDirect3DSurface9** direct3d_surface); - // Gets the D3D base texture. - virtual IDirect3DBaseTexture9 *d3d_base_texture() const { - return d3d_texture_; - } - private: - unsigned int side_; - CComPtr d3d_texture_; - IDirect3DCubeTexture9 *d3d_shadow_; - DISALLOW_COPY_AND_ASSIGN(TextureCubeD3D9); -}; - -} // namespace o3d -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_SERVICE_TEXTURE_D3D9_H_ diff --git a/o3d/gpu/command_buffer/service/texture_gl.cc b/o3d/gpu/command_buffer/service/texture_gl.cc deleted file mode 100644 index 386c5ec..0000000 --- a/o3d/gpu/command_buffer/service/texture_gl.cc +++ /dev/null @@ -1,767 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file implements the texture-related GAPI functions on GL. - -#include "gpu/command_buffer/service/precompile.h" -#include "gpu/command_buffer/service/gapi_gl.h" -#include "gpu/command_buffer/service/texture_gl.h" - -namespace command_buffer { -namespace o3d { - -namespace { - -// Gets the GL internal format, format and type corresponding to a command -// buffer texture format. -bool GetGLFormatType(texture::Format format, - GLenum *internal_format, - GLenum *gl_format, - GLenum *gl_type) { - switch (format) { - case texture::kXRGB8: { - *internal_format = GL_RGB; - *gl_format = GL_BGRA; - *gl_type = GL_UNSIGNED_BYTE; - break; - } - case texture::kARGB8: { - *internal_format = GL_RGBA; - *gl_format = GL_BGRA; - *gl_type = GL_UNSIGNED_BYTE; - break; - } - case texture::kABGR16F: { - *internal_format = GL_RGBA16F_ARB; - *gl_format = GL_RGBA; - *gl_type = GL_HALF_FLOAT_ARB; - break; - } - case texture::kR32F: { - *internal_format = GL_LUMINANCE32F_ARB; - *gl_format = GL_LUMINANCE; - *gl_type = GL_FLOAT; - break; - } - case texture::kABGR32F: { - *internal_format = GL_RGBA32F_ARB; - *gl_format = GL_BGRA; - *gl_type = GL_FLOAT; - break; - } - case texture::kDXT1: { - *internal_format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; - *gl_format = 0; - *gl_type = 0; - break; - } - // TODO(petersont): Add DXT3/5 support. - default: - return false; - } - - return true; -} - -// Helper class used to prepare image data to match the layout that -// glTexImage* and glCompressedTexImage* expect. -class SetImageHelper { - public: - SetImageHelper() - : buffer_(NULL), - image_data_(NULL), - image_size_(0) { - } - - // Initializes the helper with the input data, re-using the input buffer if - // possible, or copying it into a temporary one. - bool Initialize(const MipLevelInfo &mip_info, - const Volume& volume, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int src_size, - const void *data) { - TransferInfo src_transfer_info; - MakeTransferInfo(&src_transfer_info, mip_info, volume, row_pitch, - slice_pitch); - if (!CheckVolume(mip_info, volume) || - src_size < src_transfer_info.total_size) - return false; - if (!src_transfer_info.packed) { - TransferInfo dst_transfer_info; - MakePackedTransferInfo(&dst_transfer_info, mip_info, volume); - buffer_.reset(new unsigned char[dst_transfer_info.total_size]); - TransferVolume(volume, mip_info, dst_transfer_info, buffer_.get(), - src_transfer_info, data); - image_data_ = buffer_.get(); - image_size_ = dst_transfer_info.total_size; - } else { - image_data_ = data; - image_size_ = src_transfer_info.total_size; - } - return true; - } - - // Gets the buffer that contains the data in the GL format. - const void *image_data() { return image_data_; } - // Gets the size of the buffer as GL expects it. - unsigned int image_size() { return image_size_; } - - private: - scoped_array buffer_; - const void *image_data_; - unsigned int image_size_; - DISALLOW_COPY_AND_ASSIGN(SetImageHelper); -}; - -// Helper class used to retrieve image data to match the layout that -// glGetTexImage and glGetCompressedTexImage expect. -class GetImageHelper { - public: - GetImageHelper() - : dst_data_(NULL), - buffer_(NULL), - image_data_(NULL) { - memset(&mip_info_, 0, sizeof(mip_info_)); - memset(&volume_, 0, sizeof(volume_)); - memset(&dst_transfer_info_, 0, sizeof(dst_transfer_info_)); - memset(&src_transfer_info_, 0, sizeof(src_transfer_info_)); - } - - // Initialize the helper to make available a buffer to get the data from GL. - // It will re-use the passed in buffer if the layout matches GL, or allocate - // a temporary one. - bool Initialize(const MipLevelInfo &mip_info, - const Volume& volume, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int dst_size, - void *dst_data) { - mip_info_ = mip_info; - volume_ = volume; - dst_data_ = dst_data; - MakeTransferInfo(&dst_transfer_info_, mip_info, volume, row_pitch, - slice_pitch); - if (!CheckVolume(mip_info, volume) || - dst_size < dst_transfer_info_.total_size) - return false; - - if (!IsFullVolume(mip_info, volume) || !dst_transfer_info_.packed) { - // We can only retrieve the full image from GL. - Volume full_volume = { - 0, 0, 0, - mip_info.width, mip_info.height, mip_info.depth - }; - MakePackedTransferInfo(&src_transfer_info_, mip_info, full_volume); - buffer_.reset(new unsigned char[src_transfer_info_.total_size]); - image_data_ = buffer_.get(); - } else { - image_data_ = dst_data; - } - return true; - } - - // Finalize the helper, copying the data into the final buffer if needed. - void Finalize() { - if (!buffer_.get()) return; - unsigned int offset = - volume_.x / mip_info_.block_size_x * mip_info_.block_bpp + - volume_.y / mip_info_.block_size_y * src_transfer_info_.row_pitch + - volume_.z * src_transfer_info_.slice_pitch; - src_transfer_info_.row_size = dst_transfer_info_.row_size; - TransferVolume(volume_, mip_info_, dst_transfer_info_, dst_data_, - src_transfer_info_, buffer_.get() + offset); - } - - // Gets the buffer that can receive the data from GL. - void *image_data() { return image_data_; } - - private: - MipLevelInfo mip_info_; - Volume volume_; - TransferInfo dst_transfer_info_; - TransferInfo src_transfer_info_; - void *dst_data_; - scoped_array buffer_; - void *image_data_; - DISALLOW_COPY_AND_ASSIGN(GetImageHelper); -}; - -} // anonymous namespace - -TextureGL::~TextureGL() { - glDeleteTextures(1, &gl_texture_); - CHECK_GL_ERROR(); -} - -Texture2DGL *Texture2DGL::Create(unsigned int width, - unsigned int height, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces) { - DCHECK_GT(width, 0U); - DCHECK_GT(height, 0U); - DCHECK_GT(levels, 0U); - GLenum gl_internal_format = 0; - GLenum gl_format = 0; - GLenum gl_type = 0; - bool r = GetGLFormatType(format, &gl_internal_format, &gl_format, &gl_type); - DCHECK(r); // Was checked in the decoder. - GLuint gl_texture = 0; - glGenTextures(1, &gl_texture); - glBindTexture(GL_TEXTURE_2D, gl_texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, levels - 1); - // glCompressedTexImage2D does't accept NULL as a parameter, so we need - // to pass in some data. - scoped_array buffer; - MipLevelInfo mip_info; - MakeMipLevelInfo(&mip_info, format, width, height, 1, 0); - unsigned int size = GetMipLevelSize(mip_info); - buffer.reset(new unsigned char[size]); - memset(buffer.get(), 0, size); - - unsigned int mip_width = width; - unsigned int mip_height = height; - - for (unsigned int i = 0; i < levels; ++i) { - if (gl_format) { - glTexImage2D(GL_TEXTURE_2D, i, gl_internal_format, mip_width, mip_height, - 0, gl_format, gl_type, buffer.get()); - } else { - MipLevelInfo mip_info; - MakeMipLevelInfo(&mip_info, format, width, height, 1, i); - unsigned int size = GetMipLevelSize(mip_info); - glCompressedTexImage2D(GL_TEXTURE_2D, i, gl_internal_format, mip_width, - mip_height, 0, size, buffer.get()); - } - mip_width = std::max(1U, mip_width >> 1); - mip_height = std::max(1U, mip_height >> 1); - } - return new Texture2DGL( - levels, format, enable_render_surfaces, flags, width, height, gl_texture); -} - -// Sets data into a 2D texture resource. -bool Texture2DGL::SetData(const Volume& volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - const void *data) { - if (level >= levels()) - return false; - MipLevelInfo mip_info; - MakeMipLevelInfo(&mip_info, format(), width_, height_, 1, level); - SetImageHelper helper; - if (!helper.Initialize(mip_info, volume, row_pitch, slice_pitch, size, data)) - return false; - - GLenum gl_internal_format = 0; - GLenum gl_format = 0; - GLenum gl_type = 0; - bool r = GetGLFormatType(format(), &gl_internal_format, &gl_format, &gl_type); - DCHECK(r); - glBindTexture(GL_TEXTURE_2D, gl_texture_); - if (gl_format) { - glTexSubImage2D(GL_TEXTURE_2D, level, volume.x, volume.y, volume.width, - volume.height, gl_format, gl_type, helper.image_data()); - } else { - glCompressedTexSubImage2D(GL_TEXTURE_2D, level, volume.x, volume.y, - volume.width, volume.height, gl_internal_format, - helper.image_size(), helper.image_data()); - } - return true; -} - -bool Texture2DGL::GetData(const Volume& volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - void *data) { - if (level >= levels()) - return false; - MipLevelInfo mip_info; - MakeMipLevelInfo(&mip_info, format(), width_, height_, 1, level); - GetImageHelper helper; - if (!helper.Initialize(mip_info, volume, row_pitch, slice_pitch, size, data)) - return false; - - GLenum gl_internal_format = 0; - GLenum gl_format = 0; - GLenum gl_type = 0; - bool r = GetGLFormatType(format(), &gl_internal_format, &gl_format, &gl_type); - DCHECK(r); - glBindTexture(GL_TEXTURE_2D, gl_texture_); - if (gl_format) { - glGetTexImage(GL_TEXTURE_2D, level, gl_format, gl_type, - helper.image_data()); - } else { - glGetCompressedTexImage(GL_TEXTURE_2D, level, helper.image_data()); - } - - helper.Finalize(); - return true; -} - -bool Texture2DGL::CreateRenderSurface(int width, - int height, - int mip_level, - int side) { - return false; -} - -bool Texture2DGL::InstallFrameBufferObjects( - RenderSurfaceGL *gl_surface) { - ::glFramebufferTexture2DEXT( - GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - GL_TEXTURE_2D, - gl_texture_, - gl_surface->mip_level()); - - GLenum framebuffer_status = ::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - if (GL_FRAMEBUFFER_COMPLETE_EXT != framebuffer_status) { - return false; - } - - return true; -} - -Texture3DGL *Texture3DGL::Create(unsigned int width, - unsigned int height, - unsigned int depth, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces) { - DCHECK_GT(width, 0U); - DCHECK_GT(height, 0U); - DCHECK_GT(depth, 0U); - DCHECK_GT(levels, 0U); - GLenum gl_internal_format = 0; - GLenum gl_format = 0; - GLenum gl_type = 0; - bool r = GetGLFormatType(format, &gl_internal_format, &gl_format, &gl_type); - DCHECK(r); // Was checked in the decoder. - GLuint gl_texture = 0; - glGenTextures(1, &gl_texture); - glBindTexture(GL_TEXTURE_3D, gl_texture); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, levels - 1); - // glCompressedTexImage3D does't accept NULL as a parameter, so we need - // to pass in some data. - scoped_array buffer; - MipLevelInfo mip_info; - MakeMipLevelInfo(&mip_info, format, width, height, depth, 0); - unsigned int size = GetMipLevelSize(mip_info); - buffer.reset(new unsigned char[size]); - memset(buffer.get(), 0, size); - - unsigned int mip_width = width; - unsigned int mip_height = height; - unsigned int mip_depth = depth; - for (unsigned int i = 0; i < levels; ++i) { - if (gl_format) { - glTexImage3D(GL_TEXTURE_3D, i, gl_internal_format, mip_width, mip_height, - mip_depth, 0, gl_format, gl_type, buffer.get()); - } else { - MipLevelInfo mip_info; - MakeMipLevelInfo(&mip_info, format, width, height, depth, i); - unsigned int size = GetMipLevelSize(mip_info); - glCompressedTexImage3D(GL_TEXTURE_3D, i, gl_internal_format, mip_width, - mip_height, mip_depth, 0, size, buffer.get()); - } - mip_width = std::max(1U, mip_width >> 1); - mip_height = std::max(1U, mip_height >> 1); - mip_depth = std::max(1U, mip_depth >> 1); - } - return new Texture3DGL(levels, format, enable_render_surfaces, flags, width, - height, depth, gl_texture); -} - -bool Texture3DGL::SetData(const Volume& volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - const void *data) { - if (level >= levels()) - return false; - MipLevelInfo mip_info; - MakeMipLevelInfo(&mip_info, format(), width_, height_, depth_, level); - SetImageHelper helper; - if (!helper.Initialize(mip_info, volume, row_pitch, slice_pitch, size, data)) - return false; - - GLenum gl_internal_format = 0; - GLenum gl_format = 0; - GLenum gl_type = 0; - bool r = GetGLFormatType(format(), &gl_internal_format, &gl_format, &gl_type); - DCHECK(r); - glBindTexture(GL_TEXTURE_3D, gl_texture_); - if (gl_format) { - glTexSubImage3D(GL_TEXTURE_3D, level, volume.x, volume.y, volume.z, - volume.width, volume.height, volume.depth, - gl_format, gl_type, helper.image_data()); - } else { - glCompressedTexSubImage3D(GL_TEXTURE_3D, level, volume.x, volume.y, - volume.z, volume.width, volume.height, - volume.depth, gl_internal_format, - helper.image_size(), helper.image_data()); - } - return true; -} - -bool Texture3DGL::GetData(const Volume& volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - void *data) { - if (level >= levels()) - return false; - MipLevelInfo mip_info; - MakeMipLevelInfo(&mip_info, format(), width_, height_, depth_, level); - GetImageHelper helper; - if (!helper.Initialize(mip_info, volume, row_pitch, slice_pitch, size, data)) - return false; - - GLenum gl_internal_format = 0; - GLenum gl_format = 0; - GLenum gl_type = 0; - bool r = GetGLFormatType(format(), &gl_internal_format, &gl_format, &gl_type); - DCHECK(r); - glBindTexture(GL_TEXTURE_3D, gl_texture_); - if (gl_format) { - glGetTexImage(GL_TEXTURE_3D, level, gl_format, gl_type, - helper.image_data()); - } else { - glGetCompressedTexImage(GL_TEXTURE_3D, level, helper.image_data()); - } - - helper.Finalize(); - return true; -} - -bool Texture3DGL::CreateRenderSurface(int width, - int height, - int mip_level, - int side) { - return false; -} - -bool Texture3DGL::InstallFrameBufferObjects( - RenderSurfaceGL *gl_surface) { - return false; -} - -TextureCubeGL *TextureCubeGL::Create(unsigned int side, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces) { - DCHECK_GT(side, 0U); - DCHECK_GT(levels, 0U); - GLenum gl_internal_format = 0; - GLenum gl_format = 0; - GLenum gl_type = 0; - bool r = GetGLFormatType(format, &gl_internal_format, &gl_format, &gl_type); - DCHECK(r); // Was checked in the decoder. - GLuint gl_texture = 0; - glGenTextures(1, &gl_texture); - glBindTexture(GL_TEXTURE_CUBE_MAP, gl_texture); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, - levels-1); - // glCompressedTexImage2D does't accept NULL as a parameter, so we need - // to pass in some data. - scoped_array buffer; - MipLevelInfo mip_info; - MakeMipLevelInfo(&mip_info, format, side, side, 1, 0); - unsigned int size = GetMipLevelSize(mip_info); - buffer.reset(new unsigned char[size]); - memset(buffer.get(), 0, size); - - unsigned int mip_side = side; - for (unsigned int i = 0; i < levels; ++i) { - if (gl_format) { - for (unsigned int face = 0; face < 6; ++face) { - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, i, - gl_internal_format, mip_side, mip_side, - 0, gl_format, gl_type, buffer.get()); - } - } else { - MipLevelInfo mip_info; - MakeMipLevelInfo(&mip_info, format, side, side, 1, i); - unsigned int size = GetMipLevelSize(mip_info); - for (unsigned int face = 0; face < 6; ++face) { - glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, i, - gl_internal_format, mip_side, mip_side, 0, size, - buffer.get()); - } - } - mip_side = std::max(1U, mip_side >> 1); - } - return new TextureCubeGL( - levels, format, enable_render_surfaces, flags, side, gl_texture); -} - -// Check that GL_TEXTURE_CUBE_MAP_POSITIVE_X + face yields the correct GLenum. -COMPILE_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_X + texture::kFacePositiveX == - GL_TEXTURE_CUBE_MAP_POSITIVE_X, POSITIVE_X_ENUMS_DO_NOT_MATCH); -COMPILE_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_X + texture::kFaceNegativeX == - GL_TEXTURE_CUBE_MAP_NEGATIVE_X, NEGATIVE_X_ENUMS_DO_NOT_MATCH); -COMPILE_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_X + texture::kFacePositiveY == - GL_TEXTURE_CUBE_MAP_POSITIVE_Y, POSITIVE_Y_ENUMS_DO_NOT_MATCH); -COMPILE_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_X + texture::kFaceNegativeY == - GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, NEGATIVE_Y_ENUMS_DO_NOT_MATCH); -COMPILE_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_X + texture::kFacePositiveZ == - GL_TEXTURE_CUBE_MAP_POSITIVE_Z, POSITIVE_Z_ENUMS_DO_NOT_MATCH); -COMPILE_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_X + texture::kFaceNegativeZ == - GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, NEGATIVE_Z_ENUMS_DO_NOT_MATCH); - -bool TextureCubeGL::SetData(const Volume& volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - const void *data) { - if (level >= levels()) - return false; - MipLevelInfo mip_info; - MakeMipLevelInfo(&mip_info, format(), side_, side_, 1, level); - SetImageHelper helper; - if (!helper.Initialize(mip_info, volume, row_pitch, slice_pitch, size, data)) - return false; - - GLenum gl_internal_format = 0; - GLenum gl_format = 0; - GLenum gl_type = 0; - bool r = GetGLFormatType(format(), &gl_internal_format, &gl_format, &gl_type); - DCHECK(r); - glBindTexture(GL_TEXTURE_CUBE_MAP, gl_texture_); - GLenum face_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face; - if (gl_format) { - glTexSubImage2D(face_target, level, volume.x, volume.y, volume.width, - volume.height, gl_format, gl_type, helper.image_data()); - } else { - glCompressedTexSubImage2D(face_target, level, volume.x, volume.y, - volume.width, volume.height, gl_internal_format, - helper.image_size(), helper.image_data()); - } - return true; -} - -bool TextureCubeGL::GetData(const Volume& volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - void *data) { - if (level >= levels()) - return false; - MipLevelInfo mip_info; - MakeMipLevelInfo(&mip_info, format(), side_, side_, 1, level); - GetImageHelper helper; - if (!helper.Initialize(mip_info, volume, row_pitch, slice_pitch, size, data)) - return false; - - GLenum gl_internal_format = 0; - GLenum gl_format = 0; - GLenum gl_type = 0; - bool r = GetGLFormatType(format(), &gl_internal_format, &gl_format, &gl_type); - DCHECK(r); - glBindTexture(GL_TEXTURE_CUBE_MAP, gl_texture_); - GLenum face_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face; - if (gl_format) { - glGetTexImage(face_target, level, gl_format, gl_type, - helper.image_data()); - } else { - glGetCompressedTexImage(face_target, level, helper.image_data()); - } - - helper.Finalize(); - return true; -} - -bool TextureCubeGL::CreateRenderSurface(int width, - int height, - int mip_level, - int side) { - return false; -} - -bool TextureCubeGL::InstallFrameBufferObjects( - RenderSurfaceGL *gl_surface) { - ::glFramebufferTexture2DEXT( - GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - gl_surface->side(), - gl_texture_, - gl_surface->mip_level()); - - GLenum framebuffer_status = ::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - if (GL_FRAMEBUFFER_COMPLETE_EXT != framebuffer_status) { - return false; - } - - return true; -} - - -// Destroys a texture resource. -parse_error::ParseError GAPIGL::DestroyTexture(ResourceId id) { - // Dirty effect, because this texture id may be used. - DirtyEffect(); - return textures_.Destroy(id) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -// Creates a 2D texture resource. -parse_error::ParseError GAPIGL::CreateTexture2D( - ResourceId id, - unsigned int width, - unsigned int height, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces) { - Texture2DGL *texture = Texture2DGL::Create( - width, height, levels, format, flags, enable_render_surfaces); - if (!texture) return parse_error::kParseInvalidArguments; - // Dirty effect, because this texture id may be used. - DirtyEffect(); - textures_.Assign(id, texture); - return parse_error::kParseNoError; -} - -// Creates a 3D texture resource. -parse_error::ParseError GAPIGL::CreateTexture3D( - ResourceId id, - unsigned int width, - unsigned int height, - unsigned int depth, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces) { - Texture3DGL *texture = Texture3DGL::Create( - width, height, depth, levels, format, flags, enable_render_surfaces); - if (!texture) return parse_error::kParseInvalidArguments; - // Dirty effect, because this texture id may be used. - DirtyEffect(); - textures_.Assign(id, texture); - return parse_error::kParseNoError; -} - -// Creates a cube map texture resource. -parse_error::ParseError GAPIGL::CreateTextureCube( - ResourceId id, - unsigned int side, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces) { - TextureCubeGL *texture = TextureCubeGL::Create( - side, levels, format, flags, enable_render_surfaces); - if (!texture) return parse_error::kParseInvalidArguments; - // Dirty effect, because this texture id may be used. - DirtyEffect(); - textures_.Assign(id, texture); - return parse_error::kParseNoError; -} - -// Copies the data into a texture resource. -parse_error::ParseError GAPIGL::SetTextureData( - ResourceId id, - unsigned int x, - unsigned int y, - unsigned int z, - unsigned int width, - unsigned int height, - unsigned int depth, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - const void *data) { - TextureGL *texture = textures_.Get(id); - if (!texture) - return parse_error::kParseInvalidArguments; - Volume volume = {x, y, z, width, height, depth}; - // Dirty effect: SetData may need to call glBindTexture which will mess up the - // sampler parameters. - DirtyEffect(); - return texture->SetData(volume, level, face, row_pitch, slice_pitch, - size, data) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -// Copies the data from a texture resource. -parse_error::ParseError GAPIGL::GetTextureData( - ResourceId id, - unsigned int x, - unsigned int y, - unsigned int z, - unsigned int width, - unsigned int height, - unsigned int depth, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - void *data) { - TextureGL *texture = textures_.Get(id); - if (!texture) - return parse_error::kParseInvalidArguments; - Volume volume = {x, y, z, width, height, depth}; - // Dirty effect: GetData may need to call glBindTexture which will mess up the - // sampler parameters. - DirtyEffect(); - return texture->GetData(volume, level, face, row_pitch, slice_pitch, - size, data) ? - parse_error::kParseNoError : - parse_error::kParseInvalidArguments; -} - -} // namespace o3d -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/service/texture_gl.h b/o3d/gpu/command_buffer/service/texture_gl.h deleted file mode 100644 index d3e774c..0000000 --- a/o3d/gpu/command_buffer/service/texture_gl.h +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file declares the TextureGL, Texture2DGL, Texture3DGL and TextureCubeGL -// classes. - -#ifndef GPU_COMMAND_BUFFER_SERVICE_TEXTURE_GL_H_ -#define GPU_COMMAND_BUFFER_SERVICE_TEXTURE_GL_H_ - -#include "gpu/command_buffer/common/gapi_interface.h" -#include "gpu/command_buffer/service/gl_utils.h" -#include "gpu/command_buffer/service/resource.h" -#include "gpu/command_buffer/service/texture_utils.h" - -namespace command_buffer { -namespace o3d { - -class RenderDepthStencilSurfaceGL; -class RenderSurfaceGL; - -// The base class for a GL texture resource, providing access to the base GL -// texture that can be assigned to an effect parameter or a sampler unit. -class TextureGL : public Texture { - public: - TextureGL(texture::Type type, - unsigned int levels, - texture::Format format, - bool enable_render_surfaces, - unsigned int flags, - GLuint gl_texture) - : Texture(type, levels, format, enable_render_surfaces, flags), - gl_texture_(gl_texture) {} - virtual ~TextureGL(); - - // Gets the GL texture object. - GLuint gl_texture() const { return gl_texture_; } - - // Sets data into a texture resource. - virtual bool SetData(const Volume& volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - const void *data) = 0; - - // Gets data from a texture resource. - virtual bool GetData(const Volume& volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - void *data) = 0; - - // Creates the render surface, returning false if unable to. - virtual bool CreateRenderSurface(int width, - int height, - int mip_level, - int side) = 0; - - virtual bool InstallFrameBufferObjects( - RenderSurfaceGL *gl_surface) = 0; - - protected: - const GLuint gl_texture_; - - private: - DISALLOW_COPY_AND_ASSIGN(TextureGL); -}; - -// A 2D texture resource for GL. -class Texture2DGL : public TextureGL { - public: - Texture2DGL(unsigned int levels, - texture::Format format, - bool enable_render_surfaces, - unsigned int flags, - unsigned int width, - unsigned int height, - GLuint gl_texture) - : TextureGL(texture::kTexture2d, - levels, - format, - enable_render_surfaces, - flags, - gl_texture), - width_(width), - height_(height) {} - - // Creates a 2D texture resource. - static Texture2DGL *Create(unsigned int width, - unsigned int height, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces); - - // Sets data into a 2D texture resource. - virtual bool SetData(const Volume& volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - const void *data); - - // Gets data from a 2D texture resource. - virtual bool GetData(const Volume& volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - void *data); - - // Create a render surface which matches this texture type. - virtual bool CreateRenderSurface(int width, - int height, - int mip_level, - int side); - - virtual bool InstallFrameBufferObjects( - RenderSurfaceGL *gl_surface); - - private: - unsigned int width_; - unsigned int height_; - DISALLOW_COPY_AND_ASSIGN(Texture2DGL); -}; - -// A 3D texture resource for GL. -class Texture3DGL : public TextureGL { - public: - Texture3DGL(unsigned int levels, - texture::Format format, - bool enable_render_surfaces, - unsigned int flags, - unsigned int width, - unsigned int height, - unsigned int depth, - GLuint gl_texture) - : TextureGL(texture::kTexture3d, - levels, - format, - enable_render_surfaces, - flags, - gl_texture), - width_(width), - height_(height), - depth_(depth) {} - - // Creates a 3D texture resource. - static Texture3DGL *Create(unsigned int width, - unsigned int height, - unsigned int depth, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces); - - // Sets data into a 3D texture resource. - virtual bool SetData(const Volume& volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - const void *data); - - // Gets data from a 3D texture resource. - virtual bool GetData(const Volume& volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - void *data); - - // Create a render surface which matches this texture type. - virtual bool CreateRenderSurface(int width, - int height, - int mip_level, - int side); - - virtual bool InstallFrameBufferObjects( - RenderSurfaceGL *gl_surface); - - private: - unsigned int width_; - unsigned int height_; - unsigned int depth_; - DISALLOW_COPY_AND_ASSIGN(Texture3DGL); -}; - -// A cube map texture resource for GL. -class TextureCubeGL : public TextureGL { - public: - TextureCubeGL(unsigned int levels, - texture::Format format, - bool render_surface_enabled, - unsigned int flags, - unsigned int side, - GLuint gl_texture) - : TextureGL(texture::kTextureCube, - levels, - format, - render_surface_enabled, - flags, - gl_texture), - side_(side) {} - - // Creates a cube map texture resource. - static TextureCubeGL *Create(unsigned int side, - unsigned int levels, - texture::Format format, - unsigned int flags, - bool enable_render_surfaces); - - // Sets data into a cube map texture resource. - virtual bool SetData(const Volume& volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - const void *data); - - // Gets data from a cube map texture resource. - virtual bool GetData(const Volume& volume, - unsigned int level, - texture::Face face, - unsigned int row_pitch, - unsigned int slice_pitch, - unsigned int size, - void *data); - - // Create a render surface which matches this texture type. - virtual bool CreateRenderSurface(int width, - int height, - int mip_level, - int side); - - virtual bool InstallFrameBufferObjects( - RenderSurfaceGL *gl_surface); - - private: - unsigned int side_; - DISALLOW_COPY_AND_ASSIGN(TextureCubeGL); -}; - -} // namespace o3d -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_SERVICE_TEXTURE_GL_H_ diff --git a/o3d/gpu/command_buffer/service/texture_utils.cc b/o3d/gpu/command_buffer/service/texture_utils.cc deleted file mode 100644 index 4aac8fa..0000000 --- a/o3d/gpu/command_buffer/service/texture_utils.cc +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file contains the implementation of some utilities for textures. - -#include "gpu/command_buffer/service/precompile.h" - -#include - -#include "gpu/command_buffer/service/texture_utils.h" - -namespace command_buffer { - -void MakeTransferInfo(TransferInfo *transfer_info, - const MipLevelInfo &mip_level, - const Volume &volume, - unsigned int row_pitch, - unsigned int slice_pitch) { - transfer_info->row_pitch = row_pitch; - transfer_info->slice_pitch = slice_pitch; - transfer_info->row_size = - volume.width / mip_level.block_size_x * mip_level.block_bpp; - transfer_info->slice_size = transfer_info->row_size + - (volume.height / mip_level.block_size_y - 1) * row_pitch; - transfer_info->total_size = transfer_info->slice_size + - (volume.depth - 1) * slice_pitch; - transfer_info->packed = (transfer_info->row_size == row_pitch) && - (volume.depth == 1 || transfer_info->slice_size == slice_pitch); -} - -void MakePackedTransferInfo(TransferInfo *transfer_info, - const MipLevelInfo &mip_level, - const Volume &volume) { - transfer_info->row_size = - volume.width / mip_level.block_size_x * mip_level.block_bpp; - transfer_info->row_pitch = transfer_info->row_size; - transfer_info->slice_size = - volume.height / mip_level.block_size_y * transfer_info->row_pitch; - transfer_info->slice_pitch = transfer_info->slice_size; - transfer_info->total_size = volume.depth * transfer_info->slice_pitch; - transfer_info->packed = true; -} - -// Transfers a volume of texels. -void TransferVolume(const Volume &volume, - const MipLevelInfo &mip_level, - const TransferInfo &dst_transfer_info, - void *dst_data, - const TransferInfo &src_transfer_info, - const void *src_data) { - DCHECK_EQ(src_transfer_info.row_size, dst_transfer_info.row_size); - if (src_transfer_info.packed && dst_transfer_info.packed) { - // fast path - DCHECK_EQ(src_transfer_info.total_size, dst_transfer_info.total_size); - DCHECK_EQ(src_transfer_info.row_pitch, dst_transfer_info.row_pitch); - DCHECK_EQ(src_transfer_info.slice_pitch, dst_transfer_info.slice_pitch); - memcpy(dst_data, src_data, src_transfer_info.total_size); - } else { - const char *src = static_cast(src_data); - char *dst = static_cast(dst_data); - for (unsigned int slice = 0; slice < volume.depth; ++slice) { - const char *row_src = src; - char *row_dst = dst; - for (unsigned int row = 0; row < volume.height; - row += mip_level.block_size_y) { - memcpy(row_dst, row_src, src_transfer_info.row_size); - row_src += src_transfer_info.row_pitch; - row_dst += dst_transfer_info.row_pitch; - } - src += src_transfer_info.slice_pitch; - dst += dst_transfer_info.slice_pitch; - } - } -} - -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/service/texture_utils.h b/o3d/gpu/command_buffer/service/texture_utils.h deleted file mode 100644 index 0ace181..0000000 --- a/o3d/gpu/command_buffer/service/texture_utils.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file declares some utilities for textures, in particular to deal with -// in-memory texture data and layout. - -#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_TEXTURE_UTILS_H_ -#define GPU_COMMAND_BUFFER_SERVICE_CROSS_TEXTURE_UTILS_H_ - -#include "gpu/command_buffer/common/logging.h" -#include "gpu/command_buffer/common/resource.h" - -namespace command_buffer { - -// Structure describing a volume of pixels. -struct Volume { - unsigned int x; - unsigned int y; - unsigned int z; - unsigned int width; - unsigned int height; - unsigned int depth; -}; - -// Structure describing the dimensions and structure of a mip level. -struct MipLevelInfo { - unsigned int block_bpp; - unsigned int block_size_x; - unsigned int block_size_y; - unsigned int width; - unsigned int height; - unsigned int depth; -}; - -// Structure describing a memory layout for transfers. -struct TransferInfo { - unsigned int row_size; // size in bytes of a row of blocks. - unsigned int row_pitch; // number of bytes between 2 successive rows. - unsigned int slice_size; // size in bytes of a slice of data. - unsigned int slice_pitch; // number of bytes between 2 successive slices. - unsigned int total_size; // total size of the data. - bool packed; // indicates whether the data is tightly packed. -}; - -// Round a value up, so that it is divisible by the block size. -static inline unsigned int RoundToBlockSize(unsigned int base, - unsigned int block) { - DCHECK_GT(base, 0U); - DCHECK_GT(block, 0U); - return block + base - 1 - (base - 1) % block; -} - -// Fills a MipLevelInfo structure from the base texture dimensions. -static inline void MakeMipLevelInfo(MipLevelInfo *mip_info, - texture::Format format, - unsigned int base_width, - unsigned int base_height, - unsigned int base_depth, - unsigned int level) { - mip_info->block_bpp = texture::GetBytesPerBlock(format); - mip_info->block_size_x = texture::GetBlockSizeX(format); - mip_info->block_size_y = texture::GetBlockSizeY(format); - mip_info->width = RoundToBlockSize( - texture::GetMipMapDimension(base_width, level), mip_info->block_size_x); - mip_info->height = RoundToBlockSize( - texture::GetMipMapDimension(base_height, level), mip_info->block_size_y); - mip_info->depth = texture::GetMipMapDimension(base_depth, level); -} - -// Gets the size in bytes of a mip level. -static inline unsigned int GetMipLevelSize(const MipLevelInfo &mip_info) { - return mip_info.block_bpp * mip_info.width / mip_info.block_size_x * - mip_info.height / mip_info.block_size_y * mip_info.depth; -} - -// Checks that [x .. x+width] is contained in [0 .. mip_width], and that both x -// and width are divisible by block_size, and that width is positive. -static inline bool CheckDimension(unsigned int x, - unsigned int width, - unsigned int mip_width, - unsigned int block_size) { - return x < mip_width && x+width <= mip_width && x % block_size == 0 && - width % block_size == 0 && width > 0; -} - -// Checks that given volume fits into a mip level. -static inline bool CheckVolume(const MipLevelInfo &mip_info, - const Volume &volume) { - return CheckDimension(volume.x, volume.width, mip_info.width, - mip_info.block_size_x) && - CheckDimension(volume.y, volume.height, mip_info.height, - mip_info.block_size_y) && - CheckDimension(volume.z, volume.depth, mip_info.depth, 1); -} - -// Checks whether a volume fully maps a mip level. -static inline bool IsFullVolume(const MipLevelInfo &mip_info, - const Volume &volume) { - return (volume.x == 0) && (volume.y == 0) && (volume.z == 0) && - (volume.width == mip_info.width) && - (volume.height == mip_info.height) && - (volume.depth == mip_info.depth); -} - -// Makes a transfer info from a mip level, a volume and row/slice pitches. -void MakeTransferInfo(TransferInfo *transfer_info, - const MipLevelInfo &mip_level, - const Volume &volume, - unsigned int row_pitch, - unsigned int slice_pitch); - -// Makes a transfer info from a mip level and a volume, considering packed data. -void MakePackedTransferInfo(TransferInfo *transfer_info, - const MipLevelInfo &mip_level, - const Volume &volume); - -// Transfers a volume of texels. -void TransferVolume(const Volume &volume, - const MipLevelInfo &mip_level, - const TransferInfo &dst_transfer_info, - void *dst_data, - const TransferInfo &src_transfer_info, - const void *src_data); - -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_TEXTURE_UTILS_H_ diff --git a/o3d/gpu/command_buffer/service/x_utils.cc b/o3d/gpu/command_buffer/service/x_utils.cc deleted file mode 100644 index b9eb9d9..0000000 --- a/o3d/gpu/command_buffer/service/x_utils.cc +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This class implements the XWindowWrapper class. - -#include "gpu/command_buffer/service/precompile.h" -#include "gpu/command_buffer/common/cross/logging.h" -#include "gpu/command_buffer/service/linux/x_utils.h" - -namespace command_buffer { - -bool XWindowWrapper::Initialize() { - XWindowAttributes attributes; - XGetWindowAttributes(display_, window_, &attributes); - XVisualInfo visual_info_template; - visual_info_template.visualid = XVisualIDFromVisual(attributes.visual); - int visual_info_count = 0; - XVisualInfo *visual_info_list = XGetVisualInfo(display_, VisualIDMask, - &visual_info_template, - &visual_info_count); - DCHECK(visual_info_list); - DCHECK_GT(visual_info_count, 0); - context_ = 0; - for (int i = 0; i < visual_info_count; ++i) { - context_ = glXCreateContext(display_, visual_info_list + i, 0, - True); - if (context_) break; - } - XFree(visual_info_list); - if (!context_) { - DLOG(ERROR) << "Couldn't create GL context."; - return false; - } - return true; -} - -bool XWindowWrapper::MakeCurrent() { - if (glXMakeCurrent(display_, window_, context_) != True) { - glXDestroyContext(display_, context_); - context_ = 0; - DLOG(ERROR) << "Couldn't make context current."; - return false; - } - return true; -} - -void XWindowWrapper::Destroy() { - Bool result = glXMakeCurrent(display_, 0, 0); - // glXMakeCurrent isn't supposed to fail when unsetting the context, unless - // we have pending draws on an invalid window - which shouldn't be the case - // here. - DCHECK(result); - if (context_) { - glXDestroyContext(display_, context_); - context_ = 0; - } -} - -void XWindowWrapper::SwapBuffers() { - glXSwapBuffers(display_, window_); -} - -} // namespace command_buffer diff --git a/o3d/gpu/command_buffer/service/x_utils.h b/o3d/gpu/command_buffer/service/x_utils.h deleted file mode 100644 index 0d8c26a..0000000 --- a/o3d/gpu/command_buffer/service/x_utils.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2009, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -// This file declares the XWindowWrapper class. - -#ifndef GPU_COMMAND_BUFFER_SERVICE_X_UTILS_H_ -#define GPU_COMMAND_BUFFER_SERVICE_X_UTILS_H_ - -#include -#include "base/basictypes.h" -#include "gpu/command_buffer/common/cross/logging.h" - -namespace command_buffer { - -// This class is a wrapper around an X Window and associated GL context. It is -// useful to isolate intrusive X headers, since it can be forward declared -// (Window and GLXContext can't). -class XWindowWrapper { - public: - XWindowWrapper(Display *display, Window window) - : display_(display), - window_(window) { - DCHECK(display_); - DCHECK(window_); - } - // Initializes the GL context. - bool Initialize(); - - // Destroys the GL context. - void Destroy(); - - // Makes the GL context current on the current thread. - bool MakeCurrent(); - - // Swaps front and back buffers. - void SwapBuffers(); - - private: - Display *display_; - Window window_; - GLXContext context_; - DISALLOW_COPY_AND_ASSIGN(XWindowWrapper); -}; - -} // namespace command_buffer - -#endif // GPU_COMMAND_BUFFER_SERVICE_X_UTILS_H_ diff --git a/o3d/gpu/gpu.gyp b/o3d/gpu/gpu.gyp deleted file mode 100644 index 60b56b8..0000000 --- a/o3d/gpu/gpu.gyp +++ /dev/null @@ -1,351 +0,0 @@ -# Copyright (c) 2009 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. - -{ - 'variables': { - 'chromium_code': 1, - }, - 'includes': [ - '../build/common.gypi', - ], - 'targets': [ - { - 'target_name': 'command_buffer_common', - 'type': 'static_library', - 'include_dirs': [ - '..', - '../..', - ], - 'all_dependent_settings': { - 'include_dirs': [ - '..', - '../..', - ], - }, # 'all_dependent_settings' - 'sources': [ - 'command_buffer/common/bitfield_helpers.h', - 'command_buffer/common/cmd_buffer_common.h', - 'command_buffer/common/cmd_buffer_common.cc', - 'command_buffer/common/o3d_cmd_format.h', - 'command_buffer/common/o3d_cmd_format.cc', - 'command_buffer/common/gapi_interface.h', - 'command_buffer/common/logging.h', - 'command_buffer/common/mocks.h', - 'command_buffer/common/resource.cc', - 'command_buffer/common/resource.h', - 'command_buffer/common/types.h', - ], - }, - { - 'target_name': 'command_buffer_common_test', - 'type': 'none', - 'direct_dependent_settings': { - 'sources': [ - 'command_buffer/common/bitfield_helpers_test.cc', - ], - }, - }, - { - 'target_name': 'command_buffer_client', - 'type': 'static_library', - 'dependencies': [ - 'command_buffer_common', - 'np_utils', - ], - 'sources': [ - 'command_buffer/client/cmd_buffer_helper.cc', - 'command_buffer/client/cmd_buffer_helper.h', - 'command_buffer/client/effect_helper.cc', - 'command_buffer/client/effect_helper.h', - 'command_buffer/client/fenced_allocator.cc', - 'command_buffer/client/fenced_allocator.h', - 'command_buffer/client/id_allocator.cc', - 'command_buffer/client/id_allocator.h', - 'command_buffer/client/o3d_cmd_helper.cc', - 'command_buffer/client/o3d_cmd_helper.h', - ], - }, - { - 'target_name': 'command_buffer_client_test', - 'type': 'none', - 'direct_dependent_settings': { - 'sources': [ - 'command_buffer/client/cmd_buffer_helper_test.cc', - 'command_buffer/client/fenced_allocator_test.cc', - 'command_buffer/client/id_allocator_test.cc', - ], - }, - }, - { - 'target_name': 'command_buffer_service', - 'type': 'static_library', - 'all_dependent_settings': { - 'include_dirs': [ - '..', - ], - 'conditions': [ - ['OS == "win" and (renderer == "gl" or cb_service == "gl")', - { - 'include_dirs': [ - '../../<(glewdir)/include', - '../../<(cgdir)/include', - ], - }, - ], - ], - }, # 'all_dependent_settings' - 'dependencies': [ - 'command_buffer_common', - ], - 'sources': [ - 'command_buffer/service/common_decoder.cc', - 'command_buffer/service/common_decoder.h', - 'command_buffer/service/cmd_buffer_engine.h', - 'command_buffer/service/cmd_parser.cc', - 'command_buffer/service/cmd_parser.h', - 'command_buffer/service/effect_utils.cc', - 'command_buffer/service/effect_utils.h', - 'command_buffer/service/gapi_decoder.cc', - 'command_buffer/service/gapi_decoder.h', - 'command_buffer/service/mocks.h', - 'command_buffer/service/precompile.cc', - 'command_buffer/service/precompile.h', - 'command_buffer/service/resource.cc', - 'command_buffer/service/resource.h', - 'command_buffer/service/texture_utils.cc', - 'command_buffer/service/texture_utils.h', - ], - 'conditions': [ - ['cb_service == "d3d9"', - { - 'include_dirs': [ - '$(DXSDK_DIR)/Include', - ], - 'all_dependent_settings': { - 'include_dirs': [ - '$(DXSDK_DIR)/Include', - ], - 'link_settings': { - 'libraries': [ - '"$(DXSDK_DIR)/Lib/x86/DxErr.lib"', - ], - }, - }, # 'all_dependent_settings' - 'sources': [ - 'command_buffer/service/d3d9_utils.h', - 'command_buffer/service/effect_d3d9.cc', - 'command_buffer/service/effect_d3d9.h', - 'command_buffer/service/gapi_d3d9.cc', - 'command_buffer/service/gapi_d3d9.h', - 'command_buffer/service/geometry_d3d9.cc', - 'command_buffer/service/geometry_d3d9.h', - 'command_buffer/service/render_surface_d3d9.cc', - 'command_buffer/service/render_surface_d3d9.h', - 'command_buffer/service/sampler_d3d9.cc', - 'command_buffer/service/sampler_d3d9.h', - 'command_buffer/service/states_d3d9.cc', - 'command_buffer/service/texture_d3d9.cc', - 'command_buffer/service/texture_d3d9.h', - ], # 'sources' - }, - ], - ['cb_service == "gl"', - { - 'dependencies': [ - '../build/libs.gyp:gl_libs', - '../build/libs.gyp:cg_libs', - ], - 'sources': [ - 'command_buffer/service/effect_gl.cc', - 'command_buffer/service/effect_gl.h', - 'command_buffer/service/gapi_gl.cc', - 'command_buffer/service/gapi_gl.h', - 'command_buffer/service/geometry_gl.cc', - 'command_buffer/service/geometry_gl.h', - 'command_buffer/service/gl_utils.h', - 'command_buffer/service/render_surface_gl.cc', - 'command_buffer/service/render_surface_gl.h', - 'command_buffer/service/sampler_gl.cc', - 'command_buffer/service/sampler_gl.h', - 'command_buffer/service/states_gl.cc', - 'command_buffer/service/texture_gl.cc', - 'command_buffer/service/texture_gl.h', - ], # 'sources' - }, - ], - ['OS == "linux"', - { - 'sources': [ - 'command_buffer/service/linux/x_utils.cc', - 'command_buffer/service/linux/x_utils.h', - ], - }, - ], - ], # 'conditions' - }, - { - 'target_name': 'command_buffer_service_test', - 'type': 'none', - 'direct_dependent_settings': { - 'sources': [ - 'command_buffer/service/cmd_parser_test.cc', - 'command_buffer/service/resource_test.cc', - ], - }, - }, - { - 'target_name': 'np_utils', - 'type': '<(library)', - 'dependencies': [ - '../../base/base.gyp:base', - '../build/o3d_in_chrome.gyp:o3d_in_chrome', - ], - 'include_dirs': [ - '..', - '../..', - '../../third_party/npapi', - ], - 'all_dependent_settings': { - 'include_dirs': [ - '..', - '../..', - '../../third_party/npapi', - ], - }, # 'all_dependent_settings' - 'sources': [ - 'np_utils/default_np_object.h', - 'np_utils/dynamic_np_object.cc', - 'np_utils/dynamic_np_object.h', - 'np_utils/np_browser.cc', - 'np_utils/np_browser.h', - 'np_utils/np_browser_mock.h', - 'np_utils/np_browser_stub.cc', - 'np_utils/np_browser_stub.h', - 'np_utils/np_class.h', - 'np_utils/np_dispatcher.cc', - 'np_utils/np_dispatcher.h', - 'np_utils/np_dispatcher_specializations.h', - 'np_utils/np_headers.h', - 'np_utils/np_object_mock.h', - 'np_utils/np_object_pointer.h', - 'np_utils/np_plugin_object.h', - 'np_utils/np_plugin_object_mock.h', - 'np_utils/np_plugin_object_factory.cc', - 'np_utils/np_plugin_object_factory.h', - 'np_utils/np_plugin_object_factory_mock.h', - 'np_utils/np_utils.cc', - 'np_utils/np_utils.h', - 'np_utils/webkit_browser.h', - ], - }, - - # This is a standalone executable until O3D is fully moved over to using - # gyp. At that point these can become part of the regular O3D unit tests. - { - 'target_name': 'np_utils_unittests', - 'type': 'executable', - 'dependencies': [ - 'np_utils', - '../../testing/gmock.gyp:gmock', - '../../testing/gmock.gyp:gmockmain', - '../../testing/gtest.gyp:gtest', - ], - 'include_dirs': [ - '../..', - ], - 'all_dependent_settings': { - 'include_dirs': [ - '../..', - ], - }, # 'all_dependent_settings' - 'sources': [ - 'np_utils/dispatched_np_object_unittest.cc', - 'np_utils/dynamic_np_object_unittest.cc', - 'np_utils/np_class_unittest.cc', - 'np_utils/np_object_pointer_unittest.cc', - 'np_utils/np_utils_unittest.cc', - ], - }, - - # These can eventually be merged back into the gpu_plugin target. There - # separated for now so O3D can statically link against them and use command - # buffers in-process without the GPU plugin. - { - 'target_name': 'command_buffer', - 'type': '<(library)', - 'dependencies': [ - '../../base/base.gyp:base', - 'command_buffer_service', - 'np_utils', - ], - 'all_dependent_settings': { - 'include_dirs': [ - '../..', - ], - }, # 'all_dependent_settings' - 'sources': [ - 'gpu_plugin/command_buffer.cc', - 'gpu_plugin/command_buffer.h', - 'gpu_plugin/command_buffer_mock.h', - 'gpu_plugin/gpu_processor.h', - 'gpu_plugin/gpu_processor.cc', - 'gpu_plugin/gpu_processor_mock.h', - 'gpu_plugin/gpu_processor_win.cc', - ], - }, - - { - 'target_name': 'gpu_plugin', - 'type': '<(library)', - 'dependencies': [ - '../../base/base.gyp:base', - 'command_buffer', - 'np_utils', - ], - 'include_dirs': [ - '../..', - ], - 'sources': [ - 'gpu_plugin/gpu_plugin.cc', - 'gpu_plugin/gpu_plugin.h', - 'gpu_plugin/gpu_plugin_object.cc', - 'gpu_plugin/gpu_plugin_object.h', - 'gpu_plugin/gpu_plugin_object_win.cc', - 'gpu_plugin/gpu_plugin_object_factory.cc', - 'gpu_plugin/gpu_plugin_object_factory.h', - ], - }, - - # This is a standalone executable until O3D is fully moved over to using - # gyp. At that point these can become part of the regular O3D unit tests. - { - 'target_name': 'gpu_plugin_unittests', - 'type': 'executable', - 'dependencies': [ - 'command_buffer_service', - 'gpu_plugin', - 'np_utils', - '../../testing/gmock.gyp:gmock', - '../../testing/gmock.gyp:gmockmain', - '../../testing/gtest.gyp:gtest', - ], - 'include_dirs': [ - '../..', - ], - 'sources': [ - 'gpu_plugin/command_buffer_unittest.cc', - 'gpu_plugin/gpu_plugin_unittest.cc', - 'gpu_plugin/gpu_plugin_object_unittest.cc', - 'gpu_plugin/gpu_plugin_object_factory_unittest.cc', - 'gpu_plugin/gpu_processor_unittest.cc', - ], - }, - ] -} - -# Local Variables: -# tab-width:2 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=2 shiftwidth=2: diff --git a/o3d/gpu/gpu_plugin/command_buffer.cc b/o3d/gpu/gpu_plugin/command_buffer.cc deleted file mode 100644 index b293693..0000000 --- a/o3d/gpu/gpu_plugin/command_buffer.cc +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include "gpu/gpu_plugin/command_buffer.h" - -using ::base::SharedMemory; - -namespace gpu_plugin { - -CommandBuffer::CommandBuffer(NPP npp) - : npp_(npp), - size_(0), - get_offset_(0), - put_offset_(0), - token_(0), - parse_error_(0), - error_status_(false) { - // Element zero is always NULL. - registered_objects_.push_back(linked_ptr()); -} - -CommandBuffer::~CommandBuffer() { -} - -bool CommandBuffer::Initialize(::base::SharedMemory* ring_buffer) { - DCHECK(ring_buffer); - - // Fail if already initialized. - if (ring_buffer_.get()) - return false; - - size_t size_in_bytes = ring_buffer->max_size(); - size_ = size_in_bytes / sizeof(int32); - ring_buffer_.reset(ring_buffer); - - return true; -} - -SharedMemory* CommandBuffer::GetRingBuffer() { - return ring_buffer_.get(); -} - -int32 CommandBuffer::GetSize() { - return size_; -} - -int32 CommandBuffer::SyncOffsets(int32 put_offset) { - if (put_offset < 0 || put_offset >= size_) - return -1; - - put_offset_ = put_offset; - - if (put_offset_change_callback_.get()) { - put_offset_change_callback_->Run(); - } - - return get_offset_; -} - -int32 CommandBuffer::GetGetOffset() { - return get_offset_; -} - -void CommandBuffer::SetGetOffset(int32 get_offset) { - DCHECK(get_offset >= 0 && get_offset < size_); - get_offset_ = get_offset; -} - -int32 CommandBuffer::GetPutOffset() { - return put_offset_; -} - -void CommandBuffer::SetPutOffsetChangeCallback(Callback0::Type* callback) { - put_offset_change_callback_.reset(callback); -} - -int32 CommandBuffer::CreateTransferBuffer(size_t size) { - linked_ptr buffer(new SharedMemory); - if (!buffer->Create(std::wstring(), false, false, size)) - return -1; - - if (unused_registered_object_elements_.empty()) { - // Check we haven't exceeded the range that fits in a 32-bit integer. - int32 handle = static_cast(registered_objects_.size()); - if (handle != registered_objects_.size()) - return -1; - - registered_objects_.push_back(buffer); - return handle; - } - - int32 handle = *unused_registered_object_elements_.begin(); - unused_registered_object_elements_.erase( - unused_registered_object_elements_.begin()); - DCHECK(!registered_objects_[handle].get()); - registered_objects_[handle] = buffer; - return handle; -} - -void CommandBuffer::DestroyTransferBuffer(int32 handle) { - if (handle <= 0) - return; - - if (static_cast(handle) >= registered_objects_.size()) - return; - - registered_objects_[handle].reset(); - unused_registered_object_elements_.insert(handle); - - // Remove all null objects from the end of the vector. This allows the vector - // to shrink when, for example, all objects are unregistered. Note that this - // loop never removes element zero, which is always NULL. - while (registered_objects_.size() > 1 && !registered_objects_.back().get()) { - registered_objects_.pop_back(); - unused_registered_object_elements_.erase( - static_cast(registered_objects_.size())); - } -} - -::base::SharedMemory* CommandBuffer::GetTransferBuffer(int32 handle) { - if (handle < 0) - return NULL; - - if (static_cast(handle) >= registered_objects_.size()) - return NULL; - - return registered_objects_[handle].get(); -} - -int32 CommandBuffer::ResetParseError() { - int32 last_error = parse_error_; - parse_error_ = 0; - return last_error; -} - -void CommandBuffer::SetParseError(int32 parse_error) { - if (parse_error_ == 0) { - parse_error_ = parse_error; - } -} - -} // namespace gpu_plugin diff --git a/o3d/gpu/gpu_plugin/command_buffer.h b/o3d/gpu/gpu_plugin/command_buffer.h deleted file mode 100644 index c92e0f3..0000000 --- a/o3d/gpu/gpu_plugin/command_buffer.h +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) 2006-2008 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 GPU_GPU_PLUGIN_COMMAND_BUFFER_H_ -#define GPU_GPU_PLUGIN_COMMAND_BUFFER_H_ - -#include -#include - -#include "base/linked_ptr.h" -#include "base/scoped_ptr.h" -#include "base/shared_memory.h" -#include "base/task.h" -#include "gpu/np_utils/default_np_object.h" -#include "gpu/np_utils/np_dispatcher.h" - -namespace gpu_plugin { - -// An NPObject that implements a shared memory command buffer and a synchronous -// API to manage the put and get pointers. -class CommandBuffer : public DefaultNPObject { - public: - explicit CommandBuffer(NPP npp); - virtual ~CommandBuffer(); - - // Initialize the command buffer with the given ring buffer. Takes ownership - // of ring buffer. - virtual bool Initialize(::base::SharedMemory* ring_buffer); - - // Gets the shared memory ring buffer object for the command buffer. - virtual ::base::SharedMemory* GetRingBuffer(); - - virtual int32 GetSize(); - - // The writer calls this to update its put offset. This function returns the - // reader's most recent get offset. Does not return until after the put offset - // change callback has been invoked. Returns -1 if the put offset is invalid. - virtual int32 SyncOffsets(int32 put_offset); - - // Returns the current get offset. This can be called from any thread. - virtual int32 GetGetOffset(); - - // Sets the current get offset. This can be called from any thread. - virtual void SetGetOffset(int32 get_offset); - - // Returns the current put offset. This can be called from any thread. - virtual int32 GetPutOffset(); - - // Sets a callback that should be posted on another thread whenever the put - // offset is changed. The callback must not return until some progress has - // been made (unless the command buffer is empty), i.e. the - // get offset must have changed. It need not process the entire command - // buffer though. This allows concurrency between the writer and the reader - // while giving the writer a means of waiting for the reader to make some - // progress before attempting to write more to the command buffer. Avoiding - // the use of a synchronization primitive like a condition variable to - // synchronize reader and writer reduces the risk of deadlock. - // Takes ownership of callback. The callback is invoked on the plugin thread. - virtual void SetPutOffsetChangeCallback(Callback0::Type* callback); - - // Create a shared memory transfer buffer and return a handle that uniquely - // identifies it or -1 on error. - virtual int32 CreateTransferBuffer(size_t size); - - // Destroy a shared memory transfer buffer and recycle the handle. - virtual void DestroyTransferBuffer(int32 id); - - // Get the shared memory associated with a handle. - virtual ::base::SharedMemory* GetTransferBuffer(int32 handle); - - // Get the current token value. This is used for by the writer to defer - // changes to shared memory objects until the reader has reached a certain - // point in the command buffer. The reader is responsible for updating the - // token value, for example in response to an asynchronous set token command - // embedded in the command buffer. The default token value is zero. - int32 GetToken() { - return token_; - } - - // Allows the reader to update the current token value. - void SetToken(int32 token) { - token_ = token; - } - - // Get the current parse error and reset it to zero. Zero means no error. Non- - // zero means error. The default error status is zero. - int32 ResetParseError(); - - // Allows the reader to set the current parse error. - void SetParseError(int32 parse_error); - - // Returns whether the command buffer is in the error state. - bool GetErrorStatus() { - return error_status_; - } - - // Allows the reader to set the error status. Once in an error state, the - // command buffer cannot recover and ceases to process commands. - void RaiseErrorStatus() { - error_status_ = true; - } - - NP_UTILS_BEGIN_DISPATCHER_CHAIN(CommandBuffer, DefaultNPObject) - NP_UTILS_DISPATCHER(GetSize, int32()) - NP_UTILS_DISPATCHER(SyncOffsets, int32(int32 get_offset)) - NP_UTILS_DISPATCHER(GetGetOffset, int32()); - NP_UTILS_DISPATCHER(GetPutOffset, int32()); - NP_UTILS_DISPATCHER(GetToken, int32()); - NP_UTILS_DISPATCHER(ResetParseError, int32()); - NP_UTILS_DISPATCHER(GetErrorStatus, bool()); - NP_UTILS_END_DISPATCHER_CHAIN - - private: - NPP npp_; - scoped_ptr< ::base::SharedMemory> ring_buffer_; - int32 size_; - int32 get_offset_; - int32 put_offset_; - scoped_ptr put_offset_change_callback_; - std::vector > registered_objects_; - std::set unused_registered_object_elements_; - int32 token_; - int32 parse_error_; - bool error_status_; -}; - -} // namespace gpu_plugin - -#endif // GPU_GPU_PLUGIN_COMMAND_BUFFER_H_ diff --git a/o3d/gpu/gpu_plugin/command_buffer_mock.h b/o3d/gpu/gpu_plugin/command_buffer_mock.h deleted file mode 100644 index bb55f52..0000000 --- a/o3d/gpu/gpu_plugin/command_buffer_mock.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2006-2008 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 GPU_GPU_PLUGIN_COMMAND_BUFFER_MOCK_H_ -#define GPU_GPU_PLUGIN_COMMAND_BUFFER_MOCK_H_ - -#include "gpu/gpu_plugin/command_buffer.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace gpu_plugin { - -// An NPObject that implements a shared memory command buffer and a synchronous -// API to manage the put and get pointers. -class MockCommandBuffer : public CommandBuffer { - public: - explicit MockCommandBuffer(NPP npp) : CommandBuffer(npp) { - ON_CALL(*this, GetRingBuffer()) - .WillByDefault(testing::Return(static_cast<::base::SharedMemory*>(NULL))); - ON_CALL(*this, GetTransferBuffer(testing::_)) - .WillByDefault(testing::Return(static_cast<::base::SharedMemory*>(NULL))); - } - - MOCK_METHOD1(Initialize, bool(::base::SharedMemory* ring_buffer)); - MOCK_METHOD0(GetRingBuffer, ::base::SharedMemory*()); - MOCK_METHOD0(GetSize, int32()); - MOCK_METHOD1(SyncOffsets, int32(int32 put_offset)); - MOCK_METHOD0(GetGetOffset, int32()); - MOCK_METHOD1(SetGetOffset, void(int32 get_offset)); - MOCK_METHOD0(GetPutOffset, int32()); - MOCK_METHOD1(SetPutOffsetChangeCallback, void(Callback0::Type* callback)); - MOCK_METHOD1(CreateTransferBuffer, int32(size_t size)); - MOCK_METHOD1(DestroyTransferBuffer, void(int32 handle)); - MOCK_METHOD1(GetTransferBuffer, ::base::SharedMemory*(int32 handle)); - - private: - DISALLOW_COPY_AND_ASSIGN(MockCommandBuffer); -}; - -} // namespace gpu_plugin - -#endif // GPU_GPU_PLUGIN_COMMAND_BUFFER_MOCK_H_ diff --git a/o3d/gpu/gpu_plugin/command_buffer_unittest.cc b/o3d/gpu/gpu_plugin/command_buffer_unittest.cc deleted file mode 100644 index 00e5640..0000000 --- a/o3d/gpu/gpu_plugin/command_buffer_unittest.cc +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include "base/thread.h" -#include "gpu/gpu_plugin/command_buffer.h" -#include "gpu/np_utils/np_browser_mock.h" -#include "gpu/np_utils/dynamic_np_object.h" -#include "gpu/np_utils/np_object_mock.h" -#include "gpu/np_utils/np_object_pointer.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/gmock/include/gmock/gmock.h" - -using base::SharedMemory; -using testing::_; -using testing::DoAll; -using testing::Return; -using testing::SetArgumentPointee; -using testing::StrictMock; - -namespace gpu_plugin { - -class CommandBufferTest : public testing::Test { - protected: - virtual void SetUp() { - command_buffer_ = NPCreateObject(NULL); - } - - MockNPBrowser mock_browser_; - NPObjectPointer command_buffer_; -}; - -TEST_F(CommandBufferTest, NullRingBufferByDefault) { - EXPECT_TRUE(NULL == command_buffer_->GetRingBuffer()); -} - -TEST_F(CommandBufferTest, InitializesCommandBuffer) { - SharedMemory* ring_buffer = new SharedMemory; - EXPECT_TRUE(ring_buffer->Create(std::wstring(), false, false, 1024)); - EXPECT_TRUE(command_buffer_->Initialize(ring_buffer)); - EXPECT_TRUE(ring_buffer == command_buffer_->GetRingBuffer()); - EXPECT_EQ(256, command_buffer_->GetSize()); -} - -TEST_F(CommandBufferTest, InitializeFailsSecondTime) { - SharedMemory* ring_buffer = new SharedMemory; - EXPECT_TRUE(command_buffer_->Initialize(ring_buffer)); - EXPECT_FALSE(command_buffer_->Initialize(ring_buffer)); -} - -TEST_F(CommandBufferTest, GetAndPutOffsetsDefaultToZero) { - EXPECT_EQ(0, command_buffer_->GetGetOffset()); - EXPECT_EQ(0, command_buffer_->GetPutOffset()); -} - -class MockCallback : public CallbackRunner { - public: - MOCK_METHOD1(RunWithParams, void(const Tuple0&)); -}; - -TEST_F(CommandBufferTest, CanSyncGetAndPutOffset) { - SharedMemory* ring_buffer = new SharedMemory; - ring_buffer->Create(std::wstring(), false, false, 1024); - - EXPECT_TRUE(command_buffer_->Initialize(ring_buffer)); - - StrictMock* put_offset_change_callback = - new StrictMock; - command_buffer_->SetPutOffsetChangeCallback(put_offset_change_callback); - - EXPECT_CALL(*put_offset_change_callback, RunWithParams(_)); - EXPECT_EQ(0, command_buffer_->SyncOffsets(2)); - EXPECT_EQ(2, command_buffer_->GetPutOffset()); - - EXPECT_CALL(*put_offset_change_callback, RunWithParams(_)); - EXPECT_EQ(0, command_buffer_->SyncOffsets(4)); - EXPECT_EQ(4, command_buffer_->GetPutOffset()); - - command_buffer_->SetGetOffset(2); - EXPECT_EQ(2, command_buffer_->GetGetOffset()); - EXPECT_CALL(*put_offset_change_callback, RunWithParams(_)); - EXPECT_EQ(2, command_buffer_->SyncOffsets(6)); - - EXPECT_EQ(-1, command_buffer_->SyncOffsets(-1)); - EXPECT_EQ(-1, command_buffer_->SyncOffsets(1024)); -} - -TEST_F(CommandBufferTest, ZeroHandleMapsToNull) { - EXPECT_TRUE(NULL == command_buffer_->GetTransferBuffer(0)); -} - -TEST_F(CommandBufferTest, NegativeHandleMapsToNull) { - EXPECT_TRUE(NULL == command_buffer_->GetTransferBuffer(-1)); -} - -TEST_F(CommandBufferTest, OutOfRangeHandleMapsToNull) { - EXPECT_TRUE(NULL == command_buffer_->GetTransferBuffer(1)); -} - -TEST_F(CommandBufferTest, CanCreateTransferBuffers) { - int32 handle = command_buffer_->CreateTransferBuffer(1024); - EXPECT_EQ(1, handle); - SharedMemory* buffer = command_buffer_->GetTransferBuffer(handle); - ASSERT_TRUE(NULL != buffer); - EXPECT_EQ(1024, buffer->max_size()); -} - -TEST_F(CommandBufferTest, CreateTransferBufferReturnsDistinctHandles) { - EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); -} - -TEST_F(CommandBufferTest, CreateTransferBufferReusesUnregisteredHandles) { - EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); - EXPECT_EQ(2, command_buffer_->CreateTransferBuffer(1024)); - command_buffer_->DestroyTransferBuffer(1); - EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); - EXPECT_EQ(3, command_buffer_->CreateTransferBuffer(1024)); -} - -TEST_F(CommandBufferTest, CannotUnregisterHandleZero) { - command_buffer_->DestroyTransferBuffer(0); - EXPECT_TRUE(NULL == command_buffer_->GetTransferBuffer(0)); - EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); -} - -TEST_F(CommandBufferTest, CannotUnregisterNegativeHandles) { - command_buffer_->DestroyTransferBuffer(-1); - EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); -} - -TEST_F(CommandBufferTest, CannotUnregisterUnregisteredHandles) { - command_buffer_->DestroyTransferBuffer(1); - EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); -} - -// Testing this case specifically because there is an optimization that takes -// a different code path in this case. -TEST_F(CommandBufferTest, UnregistersLastRegisteredHandle) { - EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); - command_buffer_->DestroyTransferBuffer(1); - EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); -} - -// Testing this case specifically because there is an optimization that takes -// a different code path in this case. -TEST_F(CommandBufferTest, UnregistersTwoLastRegisteredHandles) { - EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); - EXPECT_EQ(2, command_buffer_->CreateTransferBuffer(1024)); - command_buffer_->DestroyTransferBuffer(2); - command_buffer_->DestroyTransferBuffer(1); - EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); -} - -TEST_F(CommandBufferTest, DefaultTokenIsZero) { - EXPECT_EQ(0, command_buffer_->GetToken()); -} - -TEST_F(CommandBufferTest, CanSetToken) { - command_buffer_->SetToken(7); - EXPECT_EQ(7, command_buffer_->GetToken()); -} - -TEST_F(CommandBufferTest, DefaultParseErrorIsNoError) { - EXPECT_EQ(0, command_buffer_->ResetParseError()); -} - -TEST_F(CommandBufferTest, CanSetAndResetParseError) { - command_buffer_->SetParseError(1); - EXPECT_EQ(1, command_buffer_->ResetParseError()); - EXPECT_EQ(0, command_buffer_->ResetParseError()); -} - -TEST_F(CommandBufferTest, DefaultErrorStatusIsFalse) { - EXPECT_FALSE(command_buffer_->GetErrorStatus()); -} - -TEST_F(CommandBufferTest, CanRaiseErrorStatus) { - command_buffer_->RaiseErrorStatus(); - EXPECT_TRUE(command_buffer_->GetErrorStatus()); -} - -} // namespace gpu_plugin diff --git a/o3d/gpu/gpu_plugin/gpu_plugin.cc b/o3d/gpu/gpu_plugin/gpu_plugin.cc deleted file mode 100644 index d8cfb58..0000000 --- a/o3d/gpu/gpu_plugin/gpu_plugin.cc +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include "gpu/gpu_plugin/gpu_plugin.h" -#include "gpu/gpu_plugin/gpu_plugin_object_factory.h" -#include "gpu/np_utils/np_browser.h" -#include "gpu/np_utils/np_plugin_object.h" -#include "gpu/np_utils/np_plugin_object_factory.h" - -#if defined(O3D_IN_CHROME) -#include "webkit/glue/plugins/nphostapi.h" -#else -#include "o3d/third_party/npapi/include/npfunctions.h" -#endif - -namespace gpu_plugin { - -// Definitions of NPAPI plugin entry points. - -namespace { -NPBrowser* g_browser; -GPUPluginObjectFactory g_plugin_object_factory; - -NPError NPP_New(NPMIMEType plugin_type, NPP instance, - uint16 mode, int16 argc, char* argn[], - char* argv[], NPSavedData* saved) { - if (!instance) - return NPERR_INVALID_INSTANCE_ERROR; - - PluginObject* plugin_object = - NPPluginObjectFactory::get()->CreatePluginObject(instance, plugin_type); - if (!plugin_object) - return NPERR_GENERIC_ERROR; - - instance->pdata = plugin_object; - - NPError error = plugin_object->New(plugin_type, argc, argn, argv, saved); - if (error != NPERR_NO_ERROR) { - plugin_object->Release(); - } - - return error; -} - -NPError NPP_Destroy(NPP instance, NPSavedData** saved) { - if (!instance) - return NPERR_INVALID_INSTANCE_ERROR; - - PluginObject* plugin_object = static_cast(instance->pdata); - NPError error = plugin_object->Destroy(saved); - - if (error == NPERR_NO_ERROR) { - plugin_object->Release(); - } - - return error; -} - -NPError NPP_SetWindow(NPP instance, NPWindow* window) { - if (!instance) - return NPERR_INVALID_INSTANCE_ERROR; - - PluginObject* plugin_object = static_cast(instance->pdata); - return plugin_object->SetWindow(window); -} - -int16 NPP_HandleEvent(NPP instance, void* event) { - if (!instance) - return 0; - - PluginObject* plugin_object = static_cast(instance->pdata); - return plugin_object->HandleEvent(static_cast(event)); -} - -NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value) { - if (!instance) - return NPERR_INVALID_INSTANCE_ERROR; - - PluginObject* plugin_object = static_cast(instance->pdata); - switch (variable) { - case NPPVpluginScriptableNPObject: - *reinterpret_cast(value) = - plugin_object->GetScriptableNPObject(); - return NPERR_NO_ERROR; - default: - return NPERR_GENERIC_ERROR; - } -} - -NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value) { - return NPERR_NO_ERROR; -} -} - -NPError NP_GetEntryPoints(NPPluginFuncs* funcs) { - funcs->newp = NPP_New; - funcs->destroy = NPP_Destroy; - funcs->setwindow = NPP_SetWindow; - funcs->event = NPP_HandleEvent; - funcs->getvalue = NPP_GetValue; - funcs->setvalue = NPP_SetValue; - return NPERR_NO_ERROR; -} - -#if defined(OS_LINUX) -NPError API_CALL NP_Initialize(NPNetscapeFuncs *browser_funcs, - NPPluginFuncs* plugin_funcs) { -#else -NPError NP_Initialize(NPNetscapeFuncs *browser_funcs) { -#endif - if (!browser_funcs) - return NPERR_INVALID_FUNCTABLE_ERROR; - - if (g_browser) - return NPERR_GENERIC_ERROR; - -#if defined(OS_LINUX) - NP_GetEntryPoints(plugin_funcs); -#endif - - g_browser = new NPBrowser(browser_funcs); - - return NPERR_NO_ERROR; -} - -NPError NP_Shutdown() { - if (!g_browser) - return NPERR_GENERIC_ERROR; - - delete g_browser; - g_browser = NULL; - - return NPERR_NO_ERROR; -} -} // namespace gpu_plugin diff --git a/o3d/gpu/gpu_plugin/gpu_plugin.h b/o3d/gpu/gpu_plugin/gpu_plugin.h deleted file mode 100644 index 0f90f77..0000000 --- a/o3d/gpu/gpu_plugin/gpu_plugin.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2006-2008 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 GPU_GPU_PLUGIN_GPU_PLUGIN_H_ -#define GPU_GPU_PLUGIN_GPU_PLUGIN_H_ - -#include "gpu/np_utils/np_headers.h" - -typedef struct _NPPluginFuncs NPPluginFuncs; -typedef struct _NPNetscapeFuncs NPNetscapeFuncs; - -namespace gpu_plugin { - -// Declarations of NPAPI plugin entry points. - -NPError NP_GetEntryPoints(NPPluginFuncs* funcs); - -#if defined(OS_LINUX) -NPError NP_Initialize(NPNetscapeFuncs *browser_funcs, - NPPluginFuncs* plugin_funcs); -#else -NPError NP_Initialize(NPNetscapeFuncs* browser_funcs); -#endif - -NPError NP_Shutdown(); - -} // namespace gpu_plugin - -#endif // GPU_GPU_PLUGIN_GPU_PLUGIN_H_ diff --git a/o3d/gpu/gpu_plugin/gpu_plugin_object.cc b/o3d/gpu/gpu_plugin/gpu_plugin_object.cc deleted file mode 100644 index 6a2bd6c..0000000 --- a/o3d/gpu/gpu_plugin/gpu_plugin_object.cc +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include - -#include "base/logging.h" -#include "gpu/np_utils/np_utils.h" -#include "gpu/gpu_plugin/gpu_plugin_object.h" -#include "gpu/gpu_plugin/gpu_processor.h" - -using ::base::SharedMemory; - -namespace gpu_plugin { - -const NPUTF8 GPUPluginObject::kPluginType[] = - "application/vnd.google.chrome.gpu-plugin"; - -GPUPluginObject::GPUPluginObject(NPP npp) - : npp_(npp), - status_(kWaitingForNew), - command_buffer_(NPCreateObject(npp)), - processor_(new GPUProcessor(npp, command_buffer_.Get())) { - memset(&window_, 0, sizeof(window_)); -} - -NPError GPUPluginObject::New(NPMIMEType plugin_type, - int16 argc, - char* argn[], - char* argv[], - NPSavedData* saved) { - if (status_ != kWaitingForNew) - return NPERR_GENERIC_ERROR; - - status_ = kWaitingForSetWindow; - - return NPERR_NO_ERROR; -} - -NPError GPUPluginObject::SetWindow(NPWindow* new_window) { - if (status_ == kWaitingForNew || status_ == kDestroyed) - return NPERR_GENERIC_ERROR; - - // PlatformSpecificSetWindow advances the status depending on what happens. - NPError error = PlatformSpecificSetWindow(new_window); - if (error == NPERR_NO_ERROR) { - window_ = *new_window; - - if (event_sync_.Get()) { - NPInvokeVoid(npp_, - event_sync_, - "resize", - static_cast(window_.width), - static_cast(window_.height)); - } - } else { - memset(&window_, 0, sizeof(window_)); - } - - return error; -} - -int16 GPUPluginObject::HandleEvent(NPEvent* event) { - return 0; -} - -NPError GPUPluginObject::Destroy(NPSavedData** saved) { - if (status_ == kWaitingForNew || status_ == kDestroyed) - return NPERR_GENERIC_ERROR; - - if (command_buffer_.Get()) { - command_buffer_->SetPutOffsetChangeCallback(NULL); - } - - status_ = kDestroyed; - - return NPERR_NO_ERROR; -} - -void GPUPluginObject::Release() { - DCHECK(status_ == kWaitingForNew || status_ == kDestroyed); - NPBrowser::get()->ReleaseObject(this); -} - -NPObject*GPUPluginObject::GetScriptableNPObject() { - NPBrowser::get()->RetainObject(this); - return this; -} - -NPObjectPointer GPUPluginObject::OpenCommandBuffer() { - if (status_ == kInitializationSuccessful) - return command_buffer_; - - // SetWindow must have been called before OpenCommandBuffer. - // PlatformSpecificSetWindow advances the status to - // kWaitingForOpenCommandBuffer. - if (status_ != kWaitingForOpenCommandBuffer) - return NPObjectPointer(); - - scoped_ptr ring_buffer(new SharedMemory); - if (!ring_buffer->Create(std::wstring(), false, false, kCommandBufferSize)) - return NPObjectPointer(); - - if (command_buffer_->Initialize(ring_buffer.release())) { - if (processor_->Initialize(static_cast(window_.window))) { - command_buffer_->SetPutOffsetChangeCallback( - NewCallback(processor_.get(), - &GPUProcessor::ProcessCommands)); - status_ = kInitializationSuccessful; - return command_buffer_; - } - } - - return NPObjectPointer(); -} - -} // namespace gpu_plugin diff --git a/o3d/gpu/gpu_plugin/gpu_plugin_object.h b/o3d/gpu/gpu_plugin/gpu_plugin_object.h deleted file mode 100644 index 09f612d..0000000 --- a/o3d/gpu/gpu_plugin/gpu_plugin_object.h +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (c) 2006-2008 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 GPU_GPU_PLUGIN_GPU_PLUGIN_OBJECT_H_ -#define GPU_GPU_PLUGIN_GPU_PLUGIN_OBJECT_H_ - -#include - -#include "base/ref_counted.h" -#include "base/thread.h" -#include "gpu/gpu_plugin/command_buffer.h" -#include "gpu/gpu_plugin/gpu_processor.h" -#include "gpu/np_utils/default_np_object.h" -#include "gpu/np_utils/np_dispatcher.h" -#include "gpu/np_utils/np_headers.h" -#include "gpu/np_utils/np_plugin_object.h" -#include "gpu/np_utils/np_utils.h" - -namespace gpu_plugin { - -// The scriptable object for the GPU plugin. -class GPUPluginObject : public DefaultNPObject, - public PluginObject { - public: - static const int32 kCommandBufferSize = 1024 * 1024; - - enum Status { - // In the state of waiting for the named function to be called to continue - // the initialization sequence. - kWaitingForNew, - kWaitingForSetWindow, - kWaitingForOpenCommandBuffer, - - // Initialization either succeeded or failed. - kInitializationSuccessful, - kInitializationFailed, - - // Destroy has now been called and the plugin object cannot be used. - kDestroyed, - }; - - static const NPUTF8 kPluginType[]; - - explicit GPUPluginObject(NPP npp); - - virtual NPError New(NPMIMEType plugin_type, - int16 argc, - char* argn[], - char* argv[], - NPSavedData* saved); - - virtual NPError SetWindow(NPWindow* new_window); - const NPWindow& GetWindow() { return window_; } - - virtual int16 HandleEvent(NPEvent* event); - - virtual NPError Destroy(NPSavedData** saved); - - virtual void Release(); - - virtual NPObject* GetScriptableNPObject(); - - // Returns the current initialization status. See Status enum. - int32 GetStatus() { - return status_; - } - - // Get the width of the plugin window. - int32 GetWidth() { - return window_.width; - } - - // Get the height of the plugin window. - int32 GetHeight() { - return window_.height; - } - - // Set the object that receives notifications of GPU plugin object events - // such as resize and keyboard and mouse input. - void SetEventSync(NPObjectPointer event_sync) { - event_sync_ = event_sync; - } - - NPObjectPointer GetEventSync() { - return event_sync_; - } - - // Initializes and returns the command buffer object. Returns NULL if the - // command buffer cannot be initialized, for example if the plugin does not - // yet have a window handle. - NPObjectPointer OpenCommandBuffer(); - - // Set the status for testing. - void set_status(Status status) { - status_ = status; - } - - // Replace the default command buffer for testing. - void set_command_buffer( - const NPObjectPointer& command_buffer) { - command_buffer_ = command_buffer; - } - - // Replace the default GPU processor for testing. - void set_gpu_processor(const scoped_refptr& processor) { - processor_ = processor; - } - - NP_UTILS_BEGIN_DISPATCHER_CHAIN(GPUPluginObject, DefaultNPObject) - NP_UTILS_DISPATCHER(GetStatus, int32()); - NP_UTILS_DISPATCHER(GetWidth, int32()); - NP_UTILS_DISPATCHER(GetHeight, int32()); - NP_UTILS_DISPATCHER(SetEventSync, void(NPObjectPointer sync)); - NP_UTILS_DISPATCHER(GetEventSync, NPObjectPointer()); - NP_UTILS_DISPATCHER(OpenCommandBuffer, NPObjectPointer()) - NP_UTILS_END_DISPATCHER_CHAIN - - private: - NPError PlatformSpecificSetWindow(NPWindow* new_window); - - NPP npp_; - Status status_; - NPWindow window_; - NPObjectPointer command_buffer_; - scoped_refptr processor_; - NPObjectPointer event_sync_; -}; - -} // namespace gpu_plugin - -#endif // GPU_GPU_PLUGIN_GPU_PLUGIN_OBJECT_H_ diff --git a/o3d/gpu/gpu_plugin/gpu_plugin_object_factory.cc b/o3d/gpu/gpu_plugin/gpu_plugin_object_factory.cc deleted file mode 100644 index cfdced8..0000000 --- a/o3d/gpu/gpu_plugin/gpu_plugin_object_factory.cc +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include "gpu/gpu_plugin/gpu_plugin_object.h" -#include "gpu/gpu_plugin/gpu_plugin_object_factory.h" -#include "gpu/np_utils/np_utils.h" - -namespace gpu_plugin { - -GPUPluginObjectFactory::GPUPluginObjectFactory() { -} - -GPUPluginObjectFactory::~GPUPluginObjectFactory() { -} - -PluginObject* GPUPluginObjectFactory::CreatePluginObject( - NPP npp, - NPMIMEType plugin_type) { - if (strcmp(plugin_type, GPUPluginObject::kPluginType) == 0) { - return NPCreateObject(npp).ToReturned(); - } - - return NULL; -} - -} // namespace gpu_plugin diff --git a/o3d/gpu/gpu_plugin/gpu_plugin_object_factory.h b/o3d/gpu/gpu_plugin/gpu_plugin_object_factory.h deleted file mode 100644 index 1a73baf..0000000 --- a/o3d/gpu/gpu_plugin/gpu_plugin_object_factory.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2006-2008 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 GPU_GPU_PLUGIN_GPU_PLUGIN_OBJECT_FACTORY_H_ -#define GPU_GPU_PLUGIN_GPU_PLUGIN_OBJECT_FACTORY_H_ - -#include "gpu/np_utils/np_plugin_object_factory.h" - -namespace gpu_plugin { - -// Plugin object factory for creating the GPUPluginObject. -class GPUPluginObjectFactory : public NPPluginObjectFactory { - public: - GPUPluginObjectFactory(); - virtual ~GPUPluginObjectFactory(); - - virtual PluginObject* CreatePluginObject(NPP npp, NPMIMEType plugin_type); - - private: - DISALLOW_COPY_AND_ASSIGN(GPUPluginObjectFactory); -}; - -} // namespace gpu_plugin - -#endif // GPU_GPU_PLUGIN_GPU_PLUGIN_OBJECT_FACTORY_H_ diff --git a/o3d/gpu/gpu_plugin/gpu_plugin_object_factory_unittest.cc b/o3d/gpu/gpu_plugin/gpu_plugin_object_factory_unittest.cc deleted file mode 100644 index 7b006c2..0000000 --- a/o3d/gpu/gpu_plugin/gpu_plugin_object_factory_unittest.cc +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include "gpu/gpu_plugin/gpu_plugin_object.h" -#include "gpu/gpu_plugin/gpu_plugin_object_factory.h" -#include "gpu/np_utils/np_browser_stub.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace gpu_plugin { - -class PluginObjectFactoryTest : public testing::Test { - protected: - virtual void SetUp() { - factory_ = new GPUPluginObjectFactory; - } - - virtual void TearDown() { - delete factory_; - } - - StubNPBrowser stub_browser_; - GPUPluginObjectFactory* factory_; -}; - -TEST_F(PluginObjectFactoryTest, ReturnsNullForUnknownMimeType) { - PluginObject* plugin_object = factory_->CreatePluginObject( - NULL, "application/unknown"); - EXPECT_TRUE(NULL == plugin_object); -} - -TEST_F(PluginObjectFactoryTest, CreatesGPUPlugin) { - PluginObject* plugin_object = factory_->CreatePluginObject( - NULL, const_cast(GPUPluginObject::kPluginType)); - EXPECT_TRUE(NULL != plugin_object); -} - -} // namespace gpu_plugin diff --git a/o3d/gpu/gpu_plugin/gpu_plugin_object_unittest.cc b/o3d/gpu/gpu_plugin/gpu_plugin_object_unittest.cc deleted file mode 100644 index 2f91225..0000000 --- a/o3d/gpu/gpu_plugin/gpu_plugin_object_unittest.cc +++ /dev/null @@ -1,346 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include "gpu/gpu_plugin/command_buffer_mock.h" -#include "gpu/gpu_plugin/gpu_plugin_object.h" -#include "gpu/gpu_plugin/gpu_processor_mock.h" -#include "gpu/np_utils/np_browser_mock.h" -#include "gpu/np_utils/dynamic_np_object.h" -#include "gpu/np_utils/np_object_mock.h" -#include "gpu/np_utils/np_object_pointer.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/gmock/include/gmock/gmock.h" - -#if defined(O3D_IN_CHROME) -#include "webkit/glue/plugins/nphostapi.h" -#else -#include "o3d/third_party/npapi/include/npfunctions.h" -#endif - -using ::base::SharedMemory; - -using testing::_; -using testing::DoAll; -using testing::Invoke; -using testing::NotNull; -using testing::Return; -using testing::SetArgumentPointee; -using testing::StrictMock; - -namespace gpu_plugin { - -class MockSystemNPObject : public DefaultNPObject { - public: - explicit MockSystemNPObject(NPP npp) { - } - - MOCK_METHOD1(CreateSharedMemory, NPObjectPointer(int32 size)); - - NP_UTILS_BEGIN_DISPATCHER_CHAIN(MockSystemNPObject, DefaultNPObject) - NP_UTILS_DISPATCHER(CreateSharedMemory, - NPObjectPointer(int32 size)) - NP_UTILS_END_DISPATCHER_CHAIN - - private: - DISALLOW_COPY_AND_ASSIGN(MockSystemNPObject); -}; - -class GPUPluginObjectTest : public testing::Test { - protected: - virtual void SetUp() { - plugin_object_ = NPCreateObject(NULL); - - command_buffer_ = NPCreateObject(NULL); - plugin_object_->set_command_buffer(command_buffer_); - - processor_ = new MockGPUProcessor(NULL, command_buffer_.Get()); - plugin_object_->set_gpu_processor(processor_.get()); - - window_object_ = NPCreateObject(NULL); - ON_CALL(mock_browser_, GetWindowNPObject(NULL)) - .WillByDefault(Return(window_object_.ToReturned())); - - chromium_object_ = NPCreateObject(NULL); - NPSetProperty(NULL, window_object_, "chromium", chromium_object_); - - system_object_ = NPCreateObject >(NULL); - NPSetProperty(NULL, chromium_object_, "system", system_object_); - } - - MockNPBrowser mock_browser_; - NPObjectPointer plugin_object_; - NPObjectPointer command_buffer_; - scoped_refptr processor_; - NPObjectPointer window_object_; - NPObjectPointer chromium_object_; - NPObjectPointer system_object_; -}; - -namespace { -template -void DeleteObject(T* object) { - delete object; -} -} // namespace anonymous - - -TEST_F(GPUPluginObjectTest, CanInstantiateAndDestroyPluginObject) { - EXPECT_EQ(GPUPluginObject::kWaitingForNew, plugin_object_->GetStatus()); - - EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", - 0, - NULL, - NULL, - NULL)); - - EXPECT_EQ(GPUPluginObject::kWaitingForSetWindow, plugin_object_->GetStatus()); - - EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); - - EXPECT_EQ(GPUPluginObject::kDestroyed, plugin_object_->GetStatus()); -} - -TEST_F(GPUPluginObjectTest, DestroyFailsIfNotInitialized) { - EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_object_->Destroy(NULL)); -} - -TEST_F(GPUPluginObjectTest, NewFailsIfAlreadyInitialized) { - EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", - 0, - NULL, - NULL, - NULL)); - - EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_object_->New("application/foo", - 0, - NULL, - NULL, - NULL)); - - EXPECT_EQ(GPUPluginObject::kWaitingForSetWindow, plugin_object_->GetStatus()); - - EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); - - EXPECT_EQ(GPUPluginObject::kDestroyed, plugin_object_->GetStatus()); -} - -TEST_F(GPUPluginObjectTest, NewFailsIfObjectHasPreviouslyBeenDestroyed) { - EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", - 0, - NULL, - NULL, - NULL)); - - EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); - - EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_object_->New("application/foo", - 0, - NULL, - NULL, - NULL)); - - EXPECT_EQ(GPUPluginObject::kDestroyed, plugin_object_->GetStatus()); -} - -TEST_F(GPUPluginObjectTest, WindowIsNullBeforeSetWindowCalled) { - NPWindow window = plugin_object_->GetWindow(); - EXPECT_EQ(NULL, window.window); -} - -TEST_F(GPUPluginObjectTest, CanSetWindow) { - EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", - 0, - NULL, - NULL, - NULL)); - - NPWindow window = {0}; - window.window = &window; - window.x = 7; - - EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->SetWindow(&window)); - EXPECT_EQ(0, memcmp(&window, &plugin_object_->GetWindow(), sizeof(window))); - EXPECT_EQ(GPUPluginObject::kWaitingForOpenCommandBuffer, - plugin_object_->GetStatus()); - - EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); -} - -TEST_F(GPUPluginObjectTest, CanGetWindowSize) { - EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", - 0, - NULL, - NULL, - NULL)); - - NPWindow window = {0}; - window.window = &window; - window.x = 10; - window.y = 10; - window.width = 100; - window.height = 200; - - EXPECT_EQ(0, plugin_object_->GetWidth()); - EXPECT_EQ(0, plugin_object_->GetHeight()); - EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->SetWindow(&window)); - EXPECT_EQ(100, plugin_object_->GetWidth()); - EXPECT_EQ(200, plugin_object_->GetHeight()); - - EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); -} - -TEST_F(GPUPluginObjectTest, SetWindowFailsIfNotInitialized) { - NPWindow window = {0}; - EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_object_->SetWindow(&window)); - EXPECT_EQ(GPUPluginObject::kWaitingForNew, plugin_object_->GetStatus()); -} - -TEST_F(GPUPluginObjectTest, CanGetScriptableNPObject) { - NPObject* scriptable_object = plugin_object_->GetScriptableNPObject(); - EXPECT_EQ(plugin_object_.Get(), scriptable_object); - NPBrowser::get()->ReleaseObject(scriptable_object); -} - -TEST_F(GPUPluginObjectTest, OpenCommandBufferReturnsInitializedCommandBuffer) { - EXPECT_CALL(*command_buffer_.Get(), Initialize(NotNull())) - .WillOnce(DoAll(Invoke(DeleteObject), - Return(true))); - - EXPECT_CALL(*processor_.get(), Initialize(NULL)) - .WillOnce(Return(true)); - - EXPECT_CALL(*command_buffer_.Get(), SetPutOffsetChangeCallback(NotNull())) - .WillOnce(Invoke(DeleteObject)); - - EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", - 0, - NULL, - NULL, - NULL)); - - // Set status as though SetWindow has been called. Avoids having to create a - // valid window handle to pass to SetWindow in tests. - plugin_object_->set_status(GPUPluginObject::kWaitingForOpenCommandBuffer); - - EXPECT_EQ(command_buffer_, plugin_object_->OpenCommandBuffer()); - - // Calling OpenCommandBuffer again just returns the existing command buffer. - EXPECT_EQ(command_buffer_, plugin_object_->OpenCommandBuffer()); - - EXPECT_EQ(GPUPluginObject::kInitializationSuccessful, - plugin_object_->GetStatus()); - - EXPECT_CALL(*command_buffer_.Get(), SetPutOffsetChangeCallback(NULL)); - - EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); -} - -TEST_F(GPUPluginObjectTest, OpenCommandBufferReturnsNullIfWindowNotReady) { - EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", - 0, - NULL, - NULL, - NULL)); - - // Set status as though SetWindow has not been called. - plugin_object_->set_status(GPUPluginObject::kWaitingForSetWindow); - - EXPECT_EQ(NPObjectPointer(), plugin_object_->OpenCommandBuffer()); - - EXPECT_EQ(GPUPluginObject::kWaitingForSetWindow, plugin_object_->GetStatus()); -} - - -TEST_F(GPUPluginObjectTest, - OpenCommandBufferReturnsNullIfCommandBufferCannotInitialize) { - EXPECT_CALL(*command_buffer_.Get(), Initialize(NotNull())) - .WillOnce(DoAll(Invoke(DeleteObject), - Return(false))); - - EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", - 0, - NULL, - NULL, - NULL)); - - // Set status as though SetWindow has been called. Avoids having to create a - // valid window handle to pass to SetWindow in tests. - plugin_object_->set_status(GPUPluginObject::kWaitingForOpenCommandBuffer); - - EXPECT_EQ(NPObjectPointer(), plugin_object_->OpenCommandBuffer()); - - EXPECT_EQ(GPUPluginObject::kWaitingForOpenCommandBuffer, - plugin_object_->GetStatus()); - - EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); -} - -TEST_F(GPUPluginObjectTest, - OpenCommandBufferReturnsNullIGPUProcessorCannotInitialize) { - EXPECT_CALL(*command_buffer_.Get(), Initialize(NotNull())) - .WillOnce(DoAll(Invoke(DeleteObject), - Return(true))); - - EXPECT_CALL(*processor_.get(), Initialize(NULL)) - .WillOnce(Return(false)); - - EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", - 0, - NULL, - NULL, - NULL)); - - // Set status as though SetWindow has been called. Avoids having to create a - // valid window handle to pass to SetWindow in tests. - plugin_object_->set_status(GPUPluginObject::kWaitingForOpenCommandBuffer); - - EXPECT_EQ(NPObjectPointer(), plugin_object_->OpenCommandBuffer()); - - EXPECT_EQ(GPUPluginObject::kWaitingForOpenCommandBuffer, - plugin_object_->GetStatus()); - - EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); -} - -class MockEventSync : public DefaultNPObject { - public: - explicit MockEventSync(NPP npp) { - } - - MOCK_METHOD2(Resize, void(int32 width, int32 height)); - - NP_UTILS_BEGIN_DISPATCHER_CHAIN(MockEventSync, DefaultNPObject) - NP_UTILS_DISPATCHER(Resize, void(int32 width, int32 height)) - NP_UTILS_END_DISPATCHER_CHAIN - - private: - DISALLOW_COPY_AND_ASSIGN(MockEventSync); -}; - -TEST_F(GPUPluginObjectTest, SendsResizeEventOnSetWindow) { - EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", - 0, - NULL, - NULL, - NULL)); - - NPObjectPointer event_sync = - NPCreateObject(NULL); - plugin_object_->SetEventSync(event_sync); - - EXPECT_CALL(*event_sync.Get(), Resize(100, 200)); - - NPWindow window = {0}; - window.window = &window; - window.x = 10; - window.y = 10; - window.width = 100; - window.height = 200; - - plugin_object_->SetWindow(&window); - - EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); -} - -} // namespace gpu_plugin diff --git a/o3d/gpu/gpu_plugin/gpu_plugin_object_win.cc b/o3d/gpu/gpu_plugin/gpu_plugin_object_win.cc deleted file mode 100644 index 7108a09..0000000 --- a/o3d/gpu/gpu_plugin/gpu_plugin_object_win.cc +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include - -#include "gpu/gpu_plugin/gpu_plugin_object.h" -#include "gpu/gpu_plugin/gpu_processor.h" - -namespace gpu_plugin { - -namespace { -const LPCTSTR kPluginObjectProperty = TEXT("GPUPluginObject"); -const LPCTSTR kOriginalWindowProc = TEXT("GPUPluginObjectOriginalWindowProc"); - -LRESULT CALLBACK WindowProc(HWND handle, - UINT message, - WPARAM w_param, - LPARAM l_param) { - return ::DefWindowProc(handle, message, w_param, l_param); -} -} // namespace anonymous - -NPError GPUPluginObject::PlatformSpecificSetWindow(NPWindow* new_window) { - // Detach properties from old window and restore the original window proc. - if (window_.window) { - HWND handle = reinterpret_cast(window_.window); - ::RemoveProp(handle, kPluginObjectProperty); - - LONG original_window_proc = reinterpret_cast( - ::GetProp(handle, kOriginalWindowProc)); - ::SetWindowLong(handle, GWL_WNDPROC, - original_window_proc); - ::RemoveProp(handle, kOriginalWindowProc); - } - - // Attach properties to new window and set a new window proc. - if (new_window->window) { - HWND handle = reinterpret_cast(new_window->window); - ::SetProp(handle, - kPluginObjectProperty, - reinterpret_cast(this)); - - LONG original_window_proc = ::GetWindowLong(handle, GWL_WNDPROC); - ::SetProp(handle, - kOriginalWindowProc, - reinterpret_cast(original_window_proc)); - ::SetWindowLong(handle, GWL_WNDPROC, - reinterpret_cast(WindowProc)); - - status_ = kWaitingForOpenCommandBuffer; - } else { - status_ = kWaitingForSetWindow; - if (processor_) { - processor_->Destroy(); - } - } - - return NPERR_NO_ERROR; -} - -} // namespace gpu_plugin diff --git a/o3d/gpu/gpu_plugin/gpu_plugin_unittest.cc b/o3d/gpu/gpu_plugin/gpu_plugin_unittest.cc deleted file mode 100644 index 7d9ae86..0000000 --- a/o3d/gpu/gpu_plugin/gpu_plugin_unittest.cc +++ /dev/null @@ -1,305 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include "gpu/gpu_plugin/gpu_plugin.h" -#include "gpu/gpu_plugin/gpu_plugin_object.h" -#include "gpu/np_utils/np_object_mock.h" -#include "gpu/np_utils/np_plugin_object_factory_mock.h" -#include "gpu/np_utils/np_plugin_object_mock.h" -#include "testing/gtest/include/gtest/gtest.h" - -#if defined(O3D_IN_CHROME) -#include "webkit/glue/plugins/nphostapi.h" -#else -#include "o3d/third_party/npapi/include/npfunctions.h" -#endif - -#if defined(OS_LINUX) -#define INITIALIZE_PLUGIN_FUNCS , &plugin_funcs_ -#else -#define INITIALIZE_PLUGIN_FUNCS -#endif - -using testing::_; -using testing::DoAll; -using testing::NiceMock; -using testing::Return; -using testing::SetArgumentPointee; -using testing::StrictMock; - -namespace gpu_plugin { - -class GPUPluginTest : public testing::Test { - protected: - virtual void SetUp() { - memset(&npp_, 0, sizeof(npp_)); - memset(&browser_funcs_, 0, sizeof(browser_funcs_)); - memset(&plugin_funcs_, 0, sizeof(plugin_funcs_)); - - plugin_object_factory_ = new StrictMock; - - np_class_ = NPGetClass >(); - } - - virtual void TearDown() { - delete plugin_object_factory_; - } - - NPP_t npp_; - NPNetscapeFuncs browser_funcs_; - NPPluginFuncs plugin_funcs_; - MockPluginObjectFactory* plugin_object_factory_; - const NPClass* np_class_; -}; - -TEST_F(GPUPluginTest, GetEntryPointsSetsNeededFunctionPointers) { -#if defined(OS_LINUX) - NPError error = gpu_plugin::NP_Initialize(&browser_funcs_, - &plugin_funcs_); - gpu_plugin::NP_Shutdown(); -#else - NPError error = gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); -#endif - - EXPECT_EQ(NPERR_NO_ERROR, error); - EXPECT_TRUE(NULL != plugin_funcs_.newp); - EXPECT_TRUE(NULL != plugin_funcs_.destroy); - EXPECT_TRUE(NULL != plugin_funcs_.setwindow); - EXPECT_TRUE(NULL != plugin_funcs_.event); - EXPECT_TRUE(NULL != plugin_funcs_.getvalue); - EXPECT_TRUE(NULL != plugin_funcs_.setvalue); -} - -TEST_F(GPUPluginTest, CanInitializeAndShutdownPlugin) { - EXPECT_EQ(NPERR_NO_ERROR, - gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS)); - EXPECT_EQ(NPERR_NO_ERROR, gpu_plugin::NP_Shutdown()); -} - -TEST_F(GPUPluginTest, InitializeFailsIfBrowserFuncsIsNull) { - EXPECT_EQ(NPERR_INVALID_FUNCTABLE_ERROR, - gpu_plugin::NP_Initialize(NULL INITIALIZE_PLUGIN_FUNCS)); -} - -TEST_F(GPUPluginTest, InitializeFailsIfAlreadyInitialized) { - EXPECT_EQ(NPERR_NO_ERROR, - gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS)); - EXPECT_EQ(NPERR_GENERIC_ERROR, - gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS)); - EXPECT_EQ(NPERR_NO_ERROR, gpu_plugin::NP_Shutdown()); -} - -TEST_F(GPUPluginTest, ShutdownFailsIfNotInitialized) { - EXPECT_EQ(NPERR_GENERIC_ERROR, gpu_plugin::NP_Shutdown()); -} - -TEST_F(GPUPluginTest, NewReturnsErrorForInvalidInstance) { - gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); - gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); - - EXPECT_EQ(NPERR_INVALID_INSTANCE_ERROR, plugin_funcs_.newp( - const_cast(GPUPluginObject::kPluginType), - NULL, 0, 0, NULL, NULL, NULL)); - - gpu_plugin::NP_Shutdown(); -} - -TEST_F(GPUPluginTest, GetValueReturnsErrorForInvalidInstance) { - gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); - gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); - - int* result = NULL; - EXPECT_EQ(NPERR_INVALID_INSTANCE_ERROR, plugin_funcs_.getvalue( - NULL, NPPVjavaClass, &result)); - - gpu_plugin::NP_Shutdown(); -} - -TEST_F(GPUPluginTest, DestroyReturnsErrorForInvalidInstance) { - gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); - gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); - - EXPECT_EQ(NPERR_INVALID_INSTANCE_ERROR, plugin_funcs_.destroy(NULL, NULL)); - - gpu_plugin::NP_Shutdown(); -} - -TEST_F(GPUPluginTest, SetWindowReturnsErrorForInvalidInstance) { - gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); - gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); - - EXPECT_EQ(NPERR_INVALID_INSTANCE_ERROR, plugin_funcs_.setwindow(NULL, NULL)); - - gpu_plugin::NP_Shutdown(); -} - -TEST_F(GPUPluginTest, HandleEventReturnsFalseForInvalidInstance) { - gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); - gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); - - EXPECT_EQ(0, plugin_funcs_.event(NULL, NULL)); - - gpu_plugin::NP_Shutdown(); -} - -TEST_F(GPUPluginTest, NewCreatesAPluginObjectAndInitializesIt) { - StrictMock plugin_object; - - EXPECT_CALL(*plugin_object_factory_, CreatePluginObject( - &npp_, const_cast(GPUPluginObject::kPluginType))) - .WillOnce(Return(&plugin_object)); - - NPObject scriptable_object; - - EXPECT_CALL(plugin_object, New( - const_cast(GPUPluginObject::kPluginType), - 0, NULL, NULL, NULL)) - .WillOnce(Return(NPERR_NO_ERROR)); - - EXPECT_CALL(plugin_object, GetScriptableNPObject()) - .WillOnce(Return(&scriptable_object)); - - EXPECT_CALL(plugin_object, Destroy(static_cast(NULL))) - .WillOnce(Return(NPERR_NO_ERROR)); - - EXPECT_CALL(plugin_object, Release()); - - gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); - gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); - - EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.newp( - const_cast(GPUPluginObject::kPluginType), - &npp_, 0, 0, NULL, NULL, NULL)); - - NPObject* result; - EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.getvalue( - &npp_, NPPVpluginScriptableNPObject, &result)); - EXPECT_EQ(&scriptable_object, result); - - EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.destroy(&npp_, NULL)); - - gpu_plugin::NP_Shutdown(); -} - -TEST_F(GPUPluginTest, NewFailsIfPluginObjectFactoryFails) { - EXPECT_CALL(*plugin_object_factory_, CreatePluginObject( - &npp_, const_cast(GPUPluginObject::kPluginType))) - .WillOnce(Return(static_cast(NULL))); - - gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); - gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); - - EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_funcs_.newp( - const_cast(GPUPluginObject::kPluginType), - &npp_, 0, 0, NULL, NULL, NULL)); - - gpu_plugin::NP_Shutdown(); -} - -TEST_F(GPUPluginTest, SetWindowForwardsToPluginObject) { - StrictMock plugin_object; - - EXPECT_CALL(*plugin_object_factory_, CreatePluginObject( - &npp_, const_cast(GPUPluginObject::kPluginType))) - .WillOnce(Return(&plugin_object)); - - EXPECT_CALL(plugin_object, New( - const_cast(GPUPluginObject::kPluginType), - 0, NULL, NULL, NULL)) - .WillOnce(Return(NPERR_NO_ERROR)); - - NPWindow window = {0}; - - EXPECT_CALL(plugin_object, SetWindow(&window)) - .WillOnce(Return(NPERR_NO_ERROR)); - - EXPECT_CALL(plugin_object, Destroy(static_cast(NULL))) - .WillOnce(Return(NPERR_NO_ERROR)); - - EXPECT_CALL(plugin_object, Release()); - - gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); - gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); - - EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.newp( - const_cast(GPUPluginObject::kPluginType), - &npp_, 0, 0, NULL, NULL, NULL)); - - EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.setwindow(&npp_, &window)); - - EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.destroy(&npp_, NULL)); - - gpu_plugin::NP_Shutdown(); -} - -TEST_F(GPUPluginTest, HandleEventForwardsToPluginObject) { - StrictMock plugin_object; - - EXPECT_CALL(*plugin_object_factory_, CreatePluginObject( - &npp_, const_cast(GPUPluginObject::kPluginType))) - .WillOnce(Return(&plugin_object)); - - EXPECT_CALL(plugin_object, New( - const_cast(GPUPluginObject::kPluginType), - 0, NULL, NULL, NULL)) - .WillOnce(Return(NPERR_NO_ERROR)); - - NPEvent event = {0}; - - EXPECT_CALL(plugin_object, HandleEvent(&event)) - .WillOnce(Return(7)); - - EXPECT_CALL(plugin_object, Destroy(static_cast(NULL))) - .WillOnce(Return(NPERR_NO_ERROR)); - - EXPECT_CALL(plugin_object, Release()); - - gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); - gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); - - EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.newp( - const_cast(GPUPluginObject::kPluginType), - &npp_, 0, 0, NULL, NULL, NULL)); - - EXPECT_EQ(7, plugin_funcs_.event(&npp_, &event)); - - EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.destroy(&npp_, NULL)); - - gpu_plugin::NP_Shutdown(); -} - -TEST_F(GPUPluginTest, GetValueReturnsErrorForUnknownVariable) { - StrictMock plugin_object; - - EXPECT_CALL(*plugin_object_factory_, CreatePluginObject( - &npp_, const_cast(GPUPluginObject::kPluginType))) - .WillOnce(Return(&plugin_object)); - - EXPECT_CALL(plugin_object, New( - const_cast(GPUPluginObject::kPluginType), - 0, NULL, NULL, NULL)) - .WillOnce(Return(NPERR_NO_ERROR)); - - EXPECT_CALL(plugin_object, Destroy(static_cast(NULL))) - .WillOnce(Return(NPERR_NO_ERROR)); - - EXPECT_CALL(plugin_object, Release()); - - gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); - gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); - - EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.newp( - const_cast(GPUPluginObject::kPluginType), - &npp_, 0, 0, NULL, NULL, NULL)); - - int* result = NULL; - EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_funcs_.getvalue( - &npp_, NPPVjavaClass, &result)); - - EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.destroy(&npp_, NULL)); - - gpu_plugin::NP_Shutdown(); -} - -} // namespace gpu_plugin diff --git a/o3d/gpu/gpu_plugin/gpu_processor.cc b/o3d/gpu/gpu_plugin/gpu_processor.cc deleted file mode 100644 index 7b97917..0000000 --- a/o3d/gpu/gpu_plugin/gpu_processor.cc +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include "gpu/gpu_plugin/gpu_processor.h" - -using ::base::SharedMemory; - -namespace gpu_plugin { - -GPUProcessor::~GPUProcessor() { -} - -namespace { -void InvokeProcessCommands(void* data) { - static_cast(data)->ProcessCommands(); -} -} // namespace anonymous - -void GPUProcessor::ProcessCommands() { - if (command_buffer_->GetErrorStatus()) - return; - - parser_->set_put(command_buffer_->GetPutOffset()); - - int commands_processed = 0; - while (commands_processed < commands_per_update_ && !parser_->IsEmpty()) { - command_buffer::parse_error::ParseError parse_error = - parser_->ProcessCommand(); - switch (parse_error) { - case command_buffer::parse_error::kParseUnknownCommand: - case command_buffer::parse_error::kParseInvalidArguments: - command_buffer_->SetParseError(parse_error); - break; - - case command_buffer::parse_error::kParseInvalidSize: - case command_buffer::parse_error::kParseOutOfBounds: - command_buffer_->SetParseError(parse_error); - command_buffer_->RaiseErrorStatus(); - return; - } - - ++commands_processed; - } - - command_buffer_->SetGetOffset(static_cast(parser_->get())); - - if (!parser_->IsEmpty()) { - NPBrowser::get()->PluginThreadAsyncCall(npp_, InvokeProcessCommands, this); - } -} - -void *GPUProcessor::GetSharedMemoryAddress(int32 shm_id) { - SharedMemory* shared_memory = command_buffer_->GetTransferBuffer(shm_id); - if (!shared_memory) - return NULL; - - if (!shared_memory->memory()) { - if (!shared_memory->Map(shared_memory->max_size())) - return NULL; - } - - return shared_memory->memory(); -} - -// TODO(apatrick): Consolidate this with the above and return both the address -// and size. -size_t GPUProcessor::GetSharedMemorySize(int32 shm_id) { - SharedMemory* shared_memory = command_buffer_->GetTransferBuffer(shm_id); - if (!shared_memory) - return 0; - - return shared_memory->max_size(); -} - -void GPUProcessor::set_token(int32 token) { - command_buffer_->SetToken(token); -} - -} // namespace gpu_plugin diff --git a/o3d/gpu/gpu_plugin/gpu_processor.h b/o3d/gpu/gpu_plugin/gpu_processor.h deleted file mode 100644 index 31617b0..0000000 --- a/o3d/gpu/gpu_plugin/gpu_processor.h +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) 2006-2008 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 GPU_GPU_PLUGIN_GPU_PROCESSOR_H_ -#define GPU_GPU_PLUGIN_GPU_PROCESSOR_H_ - -#include "base/ref_counted.h" -#include "base/scoped_ptr.h" -#include "base/shared_memory.h" -#include "gpu/command_buffer/service/cmd_buffer_engine.h" -#include "gpu/command_buffer/service/cmd_parser.h" -#include "gpu/command_buffer/service/gapi_decoder.h" -#include "gpu/gpu_plugin/command_buffer.h" -#include "gpu/np_utils/np_object_pointer.h" - -#if defined(CB_SERVICE_D3D9) -#include "gpu/command_buffer/service/gapi_d3d9.h" -#elif defined(CB_SERVICE_GL) -#include "gpu/command_buffer/service/gapi_gl.h" -#else -#error command buffer service not defined -#endif - -namespace gpu_plugin { - -// This class processes commands in a command buffer. It is event driven and -// posts tasks to the current message loop to do additional work. -class GPUProcessor : public ::base::RefCounted, - public command_buffer::CommandBufferEngine { - public: -#if defined(CB_SERVICE_D3D9) - typedef command_buffer::o3d::GAPID3D9 GPUGAPIInterface; -#elif defined(CB_SERVICE_GL) - typedef command_buffer::o3d::GAPIGL GPUGAPIInterface; -#else -#error command buffer service not defined -#endif - - GPUProcessor(NPP npp, - CommandBuffer* command_buffer); - - // This constructor is for unit tests. - GPUProcessor(NPP npp, - CommandBuffer* command_buffer, - GPUGAPIInterface* gapi, - command_buffer::o3d::GAPIDecoder* decoder, - command_buffer::CommandParser* parser, - int commands_per_update); - - virtual bool Initialize(HWND hwnd); - - virtual ~GPUProcessor(); - - virtual void Destroy(); - - virtual void ProcessCommands(); - -#if defined(OS_WIN) - virtual bool SetWindow(HWND handle, int width, int height); -#endif - - // Implementation of CommandBufferEngine. - - // Gets the base address of a registered shared memory buffer. - // Parameters: - // shm_id: the identifier for the shared memory buffer. - virtual void *GetSharedMemoryAddress(int32 shm_id); - - // Gets the size of a registered shared memory buffer. - // Parameters: - // shm_id: the identifier for the shared memory buffer. - virtual size_t GetSharedMemorySize(int32 shm_id); - - // Sets the token value. - virtual void set_token(int32 token); - - private: - NPP npp_; - - // The GPUProcessor holds a weak reference to the CommandBuffer. The - // CommandBuffer owns the GPUProcessor and holds a strong reference to it - // through the ProcessCommands callback. - CommandBuffer* command_buffer_; - - scoped_ptr< ::base::SharedMemory> mapped_ring_buffer_; - int commands_per_update_; - - scoped_ptr gapi_; - scoped_ptr decoder_; - scoped_ptr parser_; -}; - -} // namespace gpu_plugin - -// Callbacks to the GPUProcessor hold a reference count. -template -class CallbackStorage { - public: - CallbackStorage(gpu_plugin::GPUProcessor* obj, Method method) - : obj_(obj), - meth_(method) { - DCHECK(obj_); - obj_->AddRef(); - } - - ~CallbackStorage() { - obj_->Release(); - } - - protected: - gpu_plugin::GPUProcessor* obj_; - Method meth_; - - private: - DISALLOW_COPY_AND_ASSIGN(CallbackStorage); -}; - -#endif // GPU_GPU_PLUGIN_GPU_PROCESSOR_H_ diff --git a/o3d/gpu/gpu_plugin/gpu_processor_mock.h b/o3d/gpu/gpu_plugin/gpu_processor_mock.h deleted file mode 100644 index e93c155..0000000 --- a/o3d/gpu/gpu_plugin/gpu_processor_mock.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) 2006-2008 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 GPU_GPU_PLUGIN_GPU_PROCESSOR_MOCK_H_ -#define GPU_GPU_PLUGIN_GPU_PROCESSOR_MOCK_H_ - -#include "gpu/gpu_plugin/gpu_processor.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace gpu_plugin { - -class MockGPUProcessor : public GPUProcessor { - public: - MockGPUProcessor(NPP npp, - CommandBuffer* command_buffer) - : GPUProcessor(npp, command_buffer) { - } - -#if defined(OS_WIN) - MOCK_METHOD1(Initialize, bool(HWND handle)); -#endif - - MOCK_METHOD0(Destroy, void()); - MOCK_METHOD0(ProcessCommands, void()); - -#if defined(OS_WIN) - MOCK_METHOD3(SetWindow, bool(HWND handle, int width, int height)); -#endif - - MOCK_METHOD1(GetSharedMemoryAddress, void*(int32 shm_id)); - MOCK_METHOD1(GetSharedMemorySize, size_t(int32 shm_id)); - MOCK_METHOD1(set_token, void(int32 token)); - - private: - DISALLOW_COPY_AND_ASSIGN(MockGPUProcessor); -}; - -} // namespace gpu_plugin - -#endif // GPU_GPU_PLUGIN_GPU_PROCESSOR_MOCK_H_ diff --git a/o3d/gpu/gpu_plugin/gpu_processor_unittest.cc b/o3d/gpu/gpu_plugin/gpu_processor_unittest.cc deleted file mode 100644 index 97c44b9..0000000 --- a/o3d/gpu/gpu_plugin/gpu_processor_unittest.cc +++ /dev/null @@ -1,309 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include "base/at_exit.h" -#include "base/message_loop.h" -#include "gpu/command_buffer/service/mocks.h" -#include "gpu/gpu_plugin/command_buffer_mock.h" -#include "gpu/gpu_plugin/gpu_processor.h" -#include "gpu/np_utils/np_browser_mock.h" -#include "gpu/np_utils/np_object_pointer.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/gmock/include/gmock/gmock.h" - -using ::base::SharedMemory; - -using testing::_; -using testing::DoAll; -using testing::Invoke; -using testing::NiceMock; -using testing::Return; -using testing::SetArgumentPointee; -using testing::StrictMock; - -namespace gpu_plugin { - -const size_t kRingBufferSize = 1024; -const size_t kRingBufferEntries = kRingBufferSize / sizeof(int32); - -class GPUProcessorTest : public testing::Test { - protected: - virtual void SetUp() { - shared_memory_.reset(new SharedMemory); - shared_memory_->Create(std::wstring(), false, false, kRingBufferSize); - shared_memory_->Map(kRingBufferSize); - buffer_ = static_cast(shared_memory_->memory()); - - memset(buffer_, 0, kRingBufferSize); - - // Don't mock PluginThreadAsyncCall. Have it schedule the task. - ON_CALL(mock_browser_, PluginThreadAsyncCall(_, _, _)) - .WillByDefault(Invoke(&mock_browser_, - &MockNPBrowser::ConcretePluginThreadAsyncCall)); - - command_buffer_ = NPCreateObject(NULL); - ON_CALL(*command_buffer_.Get(), GetRingBuffer()) - .WillByDefault(Return(shared_memory_.get())); - ON_CALL(*command_buffer_.Get(), GetSize()) - .WillByDefault(Return(kRingBufferEntries)); - -#if defined(OS_WIN) - gapi_ = new GPUProcessor::GPUGAPIInterface; -#endif - - async_api_.reset(new StrictMock); - - decoder_ = new command_buffer::o3d::GAPIDecoder(gapi_); - - parser_ = new command_buffer::CommandParser(buffer_, - kRingBufferEntries, - 0, - kRingBufferEntries, - 0, - async_api_.get()); - - processor_ = new GPUProcessor(NULL, - command_buffer_.Get(), - gapi_, - decoder_, - parser_, - 2); - } - - virtual void TearDown() { - // Ensure that any unexpected tasks posted by the GPU processor are executed - // in order to fail the test. - MessageLoop::current()->RunAllPending(); - } - - base::AtExitManager at_exit_manager; - MessageLoop message_loop; - MockNPBrowser mock_browser_; - NPObjectPointer command_buffer_; - scoped_ptr shared_memory_; - int32* buffer_; - command_buffer::o3d::GAPIDecoder* decoder_; - command_buffer::CommandParser* parser_; - scoped_ptr async_api_; - scoped_refptr processor_; - -#if defined(OS_WIN) - GPUProcessor::GPUGAPIInterface* gapi_; -#endif -}; - -TEST_F(GPUProcessorTest, ProcessorDoesNothingIfRingBufferIsEmpty) { - EXPECT_CALL(*command_buffer_, GetPutOffset()) - .WillOnce(Return(0)); - EXPECT_CALL(*command_buffer_, SetGetOffset(0)); - - processor_->ProcessCommands(); - - EXPECT_EQ(command_buffer::parse_error::kParseNoError, - command_buffer_->ResetParseError()); - EXPECT_FALSE(command_buffer_->GetErrorStatus()); -} - -TEST_F(GPUProcessorTest, ProcessesOneCommand) { - command_buffer::CommandHeader* header = - reinterpret_cast(&buffer_[0]); - header[0].command = 7; - header[0].size = 2; - buffer_[1] = 123; - - EXPECT_CALL(*command_buffer_, GetPutOffset()) - .WillOnce(Return(2)); - EXPECT_CALL(*command_buffer_, SetGetOffset(2)); - - EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0])) - .WillOnce(Return(command_buffer::parse_error::kParseNoError)); - - processor_->ProcessCommands(); - - EXPECT_EQ(command_buffer::parse_error::kParseNoError, - command_buffer_->ResetParseError()); - EXPECT_FALSE(command_buffer_->GetErrorStatus()); -} - -TEST_F(GPUProcessorTest, ProcessesTwoCommands) { - command_buffer::CommandHeader* header = - reinterpret_cast(&buffer_[0]); - header[0].command = 7; - header[0].size = 2; - buffer_[1] = 123; - header[2].command = 8; - header[2].size = 1; - - EXPECT_CALL(*command_buffer_, GetPutOffset()) - .WillOnce(Return(3)); - EXPECT_CALL(*command_buffer_, SetGetOffset(3)); - - EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0])) - .WillOnce(Return(command_buffer::parse_error::kParseNoError)); - - EXPECT_CALL(*async_api_, DoCommand(8, 0, &buffer_[2])) - .WillOnce(Return(command_buffer::parse_error::kParseNoError)); - - processor_->ProcessCommands(); -} - -TEST_F(GPUProcessorTest, PostsTaskToFinishRemainingCommands) { - command_buffer::CommandHeader* header = - reinterpret_cast(&buffer_[0]); - header[0].command = 7; - header[0].size = 2; - buffer_[1] = 123; - header[2].command = 8; - header[2].size = 1; - header[3].command = 9; - header[3].size = 1; - - EXPECT_CALL(*command_buffer_, GetPutOffset()) - .WillOnce(Return(4)); - - EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0])) - .WillOnce(Return(command_buffer::parse_error::kParseNoError)); - - EXPECT_CALL(*async_api_, DoCommand(8, 0, &buffer_[2])) - .WillOnce(Return(command_buffer::parse_error::kParseNoError)); - - EXPECT_CALL(*command_buffer_, SetGetOffset(3)); - - processor_->ProcessCommands(); - - // ProcessCommands is called a second time when the pending task is run. - - EXPECT_CALL(*command_buffer_, GetPutOffset()) - .WillOnce(Return(4)); - - EXPECT_CALL(*async_api_, DoCommand(9, 0, &buffer_[3])) - .WillOnce(Return(command_buffer::parse_error::kParseNoError)); - - EXPECT_CALL(*command_buffer_, SetGetOffset(4)); - - MessageLoop::current()->RunAllPending(); -} - -TEST_F(GPUProcessorTest, SetsErrorCodeOnCommandBuffer) { - command_buffer::CommandHeader* header = - reinterpret_cast(&buffer_[0]); - header[0].command = 7; - header[0].size = 1; - - EXPECT_CALL(*command_buffer_, GetPutOffset()) - .WillOnce(Return(1)); - EXPECT_CALL(*command_buffer_, SetGetOffset(1)); - - EXPECT_CALL(*async_api_, DoCommand(7, 0, &buffer_[0])) - .WillOnce(Return( - command_buffer::parse_error::kParseUnknownCommand)); - - processor_->ProcessCommands(); - - EXPECT_EQ(command_buffer::parse_error::kParseUnknownCommand, - command_buffer_->ResetParseError()); - EXPECT_FALSE(command_buffer_->GetErrorStatus()); -} - -TEST_F(GPUProcessorTest, - RecoverableParseErrorsAreNotClearedByFollowingSuccessfulCommands) { - command_buffer::CommandHeader* header = - reinterpret_cast(&buffer_[0]); - header[0].command = 7; - header[0].size = 1; - header[1].command = 8; - header[1].size = 1; - - EXPECT_CALL(*command_buffer_, GetPutOffset()) - .WillOnce(Return(2)); - EXPECT_CALL(*command_buffer_, SetGetOffset(2)); - - EXPECT_CALL(*async_api_, DoCommand(7, 0, &buffer_[0])) - .WillOnce(Return( - command_buffer::parse_error::kParseUnknownCommand)); - - EXPECT_CALL(*async_api_, DoCommand(8, 0, &buffer_[1])) - .WillOnce(Return(command_buffer::parse_error::kParseNoError)); - - processor_->ProcessCommands(); - - EXPECT_EQ(command_buffer::parse_error::kParseUnknownCommand, - command_buffer_->ResetParseError()); - EXPECT_FALSE(command_buffer_->GetErrorStatus()); -} - -TEST_F(GPUProcessorTest, UnrecoverableParseErrorsRaiseTheErrorStatus) { - command_buffer::CommandHeader* header = - reinterpret_cast(&buffer_[0]); - header[0].command = 7; - header[0].size = 1; - header[1].command = 8; - header[1].size = 1; - - EXPECT_CALL(*command_buffer_, GetPutOffset()) - .WillOnce(Return(2)); - - EXPECT_CALL(*async_api_, DoCommand(7, 0, &buffer_[0])) - .WillOnce(Return(command_buffer::parse_error::kParseInvalidSize)); - - processor_->ProcessCommands(); - - EXPECT_EQ(command_buffer::parse_error::kParseInvalidSize, - command_buffer_->ResetParseError()); - EXPECT_TRUE(command_buffer_->GetErrorStatus()); -} - -TEST_F(GPUProcessorTest, ProcessCommandsDoesNothingAfterUnrecoverableError) { - command_buffer::CommandHeader* header = - reinterpret_cast(&buffer_[0]); - header[0].command = 7; - header[0].size = 1; - header[1].command = 8; - header[1].size = 1; - - EXPECT_CALL(*command_buffer_, GetPutOffset()) - .WillOnce(Return(2)); - - EXPECT_CALL(*async_api_, DoCommand(7, 0, &buffer_[0])) - .WillOnce(Return(command_buffer::parse_error::kParseInvalidSize)); - - processor_->ProcessCommands(); - processor_->ProcessCommands(); - - EXPECT_EQ(command_buffer::parse_error::kParseInvalidSize, - command_buffer_->ResetParseError()); - EXPECT_TRUE(command_buffer_->GetErrorStatus()); -} - -TEST_F(GPUProcessorTest, CanGetAddressOfSharedMemory) { - EXPECT_CALL(*command_buffer_.Get(), GetTransferBuffer(7)) - .WillOnce(Return(shared_memory_.get())); - - EXPECT_EQ(&buffer_[0], processor_->GetSharedMemoryAddress(7)); -} - -ACTION_P2(SetPointee, address, value) { - *address = value; -} - -TEST_F(GPUProcessorTest, GetAddressOfSharedMemoryMapsMemoryIfUnmapped) { - EXPECT_CALL(*command_buffer_.Get(), GetTransferBuffer(7)) - .WillOnce(Return(shared_memory_.get())); - - EXPECT_EQ(&buffer_[0], processor_->GetSharedMemoryAddress(7)); -} - -TEST_F(GPUProcessorTest, CanGetSizeOfSharedMemory) { - EXPECT_CALL(*command_buffer_.Get(), GetTransferBuffer(7)) - .WillOnce(Return(shared_memory_.get())); - - EXPECT_EQ(kRingBufferSize, processor_->GetSharedMemorySize(7)); -} - -TEST_F(GPUProcessorTest, SetTokenForwardsToCommandBuffer) { - processor_->set_token(7); - EXPECT_EQ(7, command_buffer_->GetToken()); -} - -} // namespace gpu_plugin \ No newline at end of file diff --git a/o3d/gpu/gpu_plugin/gpu_processor_win.cc b/o3d/gpu/gpu_plugin/gpu_processor_win.cc deleted file mode 100644 index 4c62098..0000000 --- a/o3d/gpu/gpu_plugin/gpu_processor_win.cc +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include - -#include "gpu/gpu_plugin/gpu_processor.h" - -using ::base::SharedMemory; - -namespace gpu_plugin { - -GPUProcessor::GPUProcessor(NPP npp, - CommandBuffer* command_buffer) - : npp_(npp), - command_buffer_(command_buffer), - commands_per_update_(100) { - DCHECK(command_buffer); - gapi_.reset(new GPUGAPIInterface); - decoder_.reset(new command_buffer::o3d::GAPIDecoder(gapi_.get())); - decoder_->set_engine(this); -} - -GPUProcessor::GPUProcessor(NPP npp, - CommandBuffer* command_buffer, - GPUGAPIInterface* gapi, - command_buffer::o3d::GAPIDecoder* decoder, - command_buffer::CommandParser* parser, - int commands_per_update) - : npp_(npp), - command_buffer_(command_buffer), - commands_per_update_(commands_per_update) { - DCHECK(command_buffer); - gapi_.reset(gapi); - decoder_.reset(decoder); - parser_.reset(parser); -} - -bool GPUProcessor::Initialize(HWND handle) { - DCHECK(handle); - - // Cannot reinitialize. - if (gapi_->hwnd() != NULL) - return false; - - // Map the ring buffer and create the parser. - SharedMemory* ring_buffer = command_buffer_->GetRingBuffer(); - if (ring_buffer) { - size_t size = ring_buffer->max_size(); - if (!ring_buffer->Map(size)) { - return false; - } - - void* ptr = ring_buffer->memory(); - parser_.reset(new command_buffer::CommandParser(ptr, size, 0, size, 0, - decoder_.get())); - } else { - parser_.reset(new command_buffer::CommandParser(NULL, 0, 0, 0, 0, - decoder_.get())); - } - - // Initialize GAPI immediately if the window handle is valid. - gapi_->set_hwnd(handle); - return gapi_->Initialize(); -} - -void GPUProcessor::Destroy() { - // Destroy GAPI if window handle has not already become invalid. - if (gapi_->hwnd()) { - gapi_->Destroy(); - gapi_->set_hwnd(NULL); - } -} - -bool GPUProcessor::SetWindow(HWND handle, int width, int height) { - if (handle == NULL) { - // Destroy GAPI when the window handle becomes invalid. - Destroy(); - return true; - } else { - return Initialize(handle); - } -} - -} // namespace gpu_plugin diff --git a/o3d/gpu/np_utils/default_np_object.h b/o3d/gpu/np_utils/default_np_object.h deleted file mode 100644 index 575dabc..0000000 --- a/o3d/gpu/np_utils/default_np_object.h +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) 2006-2008 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 GPU_NP_UTILS_DEFAULT_NP_OBJECT_H_ -#define GPU_NP_UTILS_DEFAULT_NP_OBJECT_H_ - -#include "base/basictypes.h" -#include "gpu/np_utils/np_headers.h" - -namespace gpu_plugin { - -class BaseNPDispatcher; - -// This class implements each of the functions in the NPClass interface. They -// all return error by default. Note that these are not virtual functions and -// this is not an interface. This class can be used as a mixin so that an -// NPObject class does not need to implement every NPClass function but rather -// inherits a default from DefaultNPObject. -template -class DefaultNPObject : public RootClass { - public: - void Invalidate() {} - - bool HasMethod(NPIdentifier name) { - return false; - } - - bool Invoke(NPIdentifier name, - const NPVariant* args, - uint32_t num_args, - NPVariant* result) { - return false; - } - - bool InvokeDefault(const NPVariant* args, - uint32_t num_args, - NPVariant* result) { - return false; - } - - bool HasProperty(NPIdentifier name) { - return false; - } - - bool GetProperty(NPIdentifier name, NPVariant* result) { - return false; - } - - bool SetProperty(NPIdentifier name, const NPVariant* value) { - return false; - } - - bool RemoveProperty(NPIdentifier name) { - return false; - } - - bool Enumerate(NPIdentifier** names, - uint32_t* count) { - *names = NULL; - *count = 0; - return true; - } - - bool Construct(const NPVariant* args, - uint32_t num_args, - NPVariant* result) { - return false; - } - - static BaseNPDispatcher* GetDispatcherChain() { - return NULL; - } - - protected: - DefaultNPObject() {} - virtual ~DefaultNPObject() {} - - private: - DISALLOW_COPY_AND_ASSIGN(DefaultNPObject); -}; -} // namespace gpu_plugin - -#endif // GPU_NP_UTILS_DEFAULT_NP_OBJECT_H_ diff --git a/o3d/gpu/np_utils/dispatched_np_object_unittest.cc b/o3d/gpu/np_utils/dispatched_np_object_unittest.cc deleted file mode 100644 index d4b2f96..0000000 --- a/o3d/gpu/np_utils/dispatched_np_object_unittest.cc +++ /dev/null @@ -1,403 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include - -#include "gpu/np_utils/default_np_object.h" -#include "gpu/np_utils/np_browser_stub.h" -#include "gpu/np_utils/np_dispatcher.h" -#include "gpu/np_utils/np_object_mock.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using testing::Return; -using testing::StrictMock; - -namespace gpu_plugin { - -// This mock class has a dispatcher chain with an entry for each mocked -// function. The tests that follow that invoking an NPAPI method calls the -// corresponding mocked member function. -class MockDispatchedNPObject : public DefaultNPObject { - public: - explicit MockDispatchedNPObject(NPP npp) { - } - - MOCK_METHOD0(VoidReturnNoParams, void()); - MOCK_METHOD1(VoidReturnBoolParam, void(bool)); - MOCK_METHOD1(VoidReturnIntParam, void(int)); - MOCK_METHOD1(VoidReturnFloatParam, void(float)); - MOCK_METHOD1(VoidReturnDoubleParam, void(double)); - MOCK_METHOD1(VoidReturnStringParam, void(std::string)); - MOCK_METHOD1(VoidReturnObjectParam, void(NPObjectPointer)); - MOCK_METHOD2(VoidReturnTwoParams, void(bool, int)); - MOCK_METHOD0(Overloaded, void()); - MOCK_METHOD1(Overloaded, void(bool)); - MOCK_METHOD1(Overloaded, void(std::string)); - MOCK_METHOD0(BoolReturn, bool()); - MOCK_METHOD0(IntReturn, int()); - MOCK_METHOD0(FloatReturn, float()); - MOCK_METHOD0(DoubleReturn, double()); - MOCK_METHOD0(StringReturn, std::string()); - MOCK_METHOD0(ObjectReturn, NPObjectPointer()); - - NP_UTILS_BEGIN_DISPATCHER_CHAIN(MockDispatchedNPObject, DefaultNPObject) - NP_UTILS_DISPATCHER(VoidReturnNoParams, void()) - NP_UTILS_DISPATCHER(VoidReturnBoolParam, void(bool)) - NP_UTILS_DISPATCHER(VoidReturnIntParam, void(int)) - NP_UTILS_DISPATCHER(VoidReturnFloatParam, void(float)) - NP_UTILS_DISPATCHER(VoidReturnDoubleParam, void(double)) - NP_UTILS_DISPATCHER(VoidReturnStringParam, void(std::string)) - NP_UTILS_DISPATCHER(VoidReturnObjectParam, void(NPObjectPointer)) - NP_UTILS_DISPATCHER(VoidReturnTwoParams, void(bool, int)) - NP_UTILS_DISPATCHER(Overloaded, void()) - NP_UTILS_DISPATCHER(Overloaded, void(bool)) - NP_UTILS_DISPATCHER(Overloaded, void(std::string)) - NP_UTILS_DISPATCHER(BoolReturn, bool()) - NP_UTILS_DISPATCHER(IntReturn, int()) - NP_UTILS_DISPATCHER(FloatReturn, float()) - NP_UTILS_DISPATCHER(DoubleReturn, double()) - NP_UTILS_DISPATCHER(StringReturn, std::string()) - NP_UTILS_DISPATCHER(ObjectReturn, NPObjectPointer()); - NP_UTILS_END_DISPATCHER_CHAIN -}; - -class DispatchedNPObjectTest : public testing::Test { - protected: - virtual void SetUp() { - object_ = NPCreateObject >(NULL); - passed_object_ = NPCreateObject(NULL); - - for (int i = 0; i != arraysize(args_); ++i) { - NULL_TO_NPVARIANT(args_[i]); - } - NULL_TO_NPVARIANT(result_); - } - - StubNPBrowser stub_browser_; - NPVariant args_[3]; - NPVariant result_; - NPObjectPointer object_; - NPObjectPointer passed_object_; -}; - -TEST_F(DispatchedNPObjectTest, CannotInvokeMissingFunction) { - EXPECT_FALSE(object_->Invoke( - NPBrowser::get()->GetStringIdentifier("missing"), - NULL, - 0, - &result_)); - EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); -} - -TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnNoParams) { - EXPECT_CALL(*object_, VoidReturnNoParams()); - - EXPECT_TRUE(object_->Invoke( - NPBrowser::get()->GetStringIdentifier("voidReturnNoParams"), - NULL, - 0, - &result_)); - EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); -} - -TEST_F(DispatchedNPObjectTest, - CannotInvokeVoidReturnNoParamsWithTooManyParams) { - EXPECT_FALSE(object_->Invoke( - NPBrowser::get()->GetStringIdentifier("voidReturnNoParams"), - args_, - 1, - &result_)); - EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); -} - -TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnIntParam) { - EXPECT_CALL(*object_, VoidReturnIntParam(7)); - - INT32_TO_NPVARIANT(7, args_[0]); - - EXPECT_TRUE(object_->Invoke( - NPBrowser::get()->GetStringIdentifier("voidReturnIntParam"), - args_, - 1, - &result_)); - EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); -} - -TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnBoolParam) { - EXPECT_CALL(*object_, VoidReturnBoolParam(true)); - - BOOLEAN_TO_NPVARIANT(true, args_[0]); - - EXPECT_TRUE(object_->Invoke( - NPBrowser::get()->GetStringIdentifier("voidReturnBoolParam"), - args_, - 1, - &result_)); - EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); -} - -TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnFloatParamWithDoubleParam) { - EXPECT_CALL(*object_, VoidReturnFloatParam(7.0f)); - - DOUBLE_TO_NPVARIANT(7.0, args_[0]); - - EXPECT_TRUE(object_->Invoke( - NPBrowser::get()->GetStringIdentifier("voidReturnFloatParam"), - args_, - 1, - &result_)); - EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); -} - -TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnFloatParamWithIntParam) { - EXPECT_CALL(*object_, VoidReturnFloatParam(7.0f)); - - INT32_TO_NPVARIANT(7, args_[0]); - - EXPECT_TRUE(object_->Invoke( - NPBrowser::get()->GetStringIdentifier("voidReturnFloatParam"), - args_, - 1, - &result_)); - EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); -} - -TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnDoubleParamWithDoubleParam) { - EXPECT_CALL(*object_, VoidReturnDoubleParam(7.0)); - - DOUBLE_TO_NPVARIANT(7.0, args_[0]); - - EXPECT_TRUE(object_->Invoke( - NPBrowser::get()->GetStringIdentifier("voidReturnDoubleParam"), - args_, - 1, - &result_)); - EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); -} - -TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnDoubleParamWithIntParam) { - EXPECT_CALL(*object_, VoidReturnDoubleParam(7.0f)); - - INT32_TO_NPVARIANT(7, args_[0]); - - EXPECT_TRUE(object_->Invoke( - NPBrowser::get()->GetStringIdentifier("voidReturnDoubleParam"), - args_, - 1, - &result_)); - EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); -} - -TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnStringParam) { - EXPECT_CALL(*object_, VoidReturnStringParam(std::string("hello"))); - - STRINGZ_TO_NPVARIANT("hello", args_[0]); - - EXPECT_TRUE(object_->Invoke( - NPBrowser::get()->GetStringIdentifier("voidReturnStringParam"), - args_, - 1, - &result_)); - EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); -} - -TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnObjectParamWithObject) { - EXPECT_CALL(*object_, VoidReturnObjectParam(passed_object_)); - - OBJECT_TO_NPVARIANT(passed_object_.Get(), args_[0]); - - EXPECT_TRUE(object_->Invoke( - NPBrowser::get()->GetStringIdentifier("voidReturnObjectParam"), - args_, - 1, - &result_)); - EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); -} - -TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnObjectParamWithNull) { - EXPECT_CALL( - *object_, - VoidReturnObjectParam(NPObjectPointer())); - - NULL_TO_NPVARIANT(args_[0]); - - EXPECT_TRUE(object_->Invoke( - NPBrowser::get()->GetStringIdentifier("voidReturnObjectParam"), - args_, - 1, - &result_)); - EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); -} - -TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnTwoParams) { - EXPECT_CALL(*object_, VoidReturnTwoParams(false, 7)); - - BOOLEAN_TO_NPVARIANT(false, args_[0]); - INT32_TO_NPVARIANT(7, args_[1]); - - EXPECT_TRUE(object_->Invoke( - NPBrowser::get()->GetStringIdentifier("voidReturnTwoParams"), - args_, - 2, - &result_)); - EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); -} - -TEST_F(DispatchedNPObjectTest, CanInvokeOverloadedWithNoParams) { - EXPECT_CALL(*object_, Overloaded()); - - EXPECT_TRUE(object_->Invoke( - NPBrowser::get()->GetStringIdentifier("overloaded"), - NULL, - 0, - &result_)); - EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); -} - -TEST_F(DispatchedNPObjectTest, CanInvokeOverloadedWithOneStringParam) { - EXPECT_CALL(*object_, Overloaded(std::string("hello"))); - - STRINGZ_TO_NPVARIANT("hello", args_[0]); - - EXPECT_TRUE(object_->Invoke( - NPBrowser::get()->GetStringIdentifier("overloaded"), - args_, - 1, - &result_)); - EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); -} - -TEST_F(DispatchedNPObjectTest, CanInvokeOverloadedWithOneBoolParam) { - EXPECT_CALL(*object_, Overloaded(true)); - - BOOLEAN_TO_NPVARIANT(true, args_[0]); - - EXPECT_TRUE(object_->Invoke( - NPBrowser::get()->GetStringIdentifier("overloaded"), - args_, - 1, - &result_)); - EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); -} - -TEST_F(DispatchedNPObjectTest, CanInvokeBoolReturn) { - EXPECT_CALL(*object_, BoolReturn()).WillOnce(Return(true)); - - EXPECT_TRUE(object_->Invoke( - NPBrowser::get()->GetStringIdentifier("boolReturn"), - NULL, - 0, - &result_)); - EXPECT_TRUE(NPVARIANT_IS_BOOLEAN(result_)); - EXPECT_TRUE(NPVARIANT_TO_BOOLEAN(result_)); -} - -TEST_F(DispatchedNPObjectTest, CanInvokeIntReturn) { - EXPECT_CALL(*object_, IntReturn()).WillOnce(Return(7)); - - EXPECT_TRUE(object_->Invoke( - NPBrowser::get()->GetStringIdentifier("intReturn"), - NULL, - 0, - &result_)); - EXPECT_TRUE(NPVARIANT_IS_INT32(result_)); - EXPECT_EQ(7, NPVARIANT_TO_INT32(result_)); -} - -TEST_F(DispatchedNPObjectTest, CanInvokeFloatReturn) { - EXPECT_CALL(*object_, FloatReturn()).WillOnce(Return(7.0f)); - - EXPECT_TRUE(object_->Invoke( - NPBrowser::get()->GetStringIdentifier("floatReturn"), - NULL, - 0, - &result_)); - EXPECT_TRUE(NPVARIANT_IS_DOUBLE(result_)); - EXPECT_EQ(7.0, NPVARIANT_TO_DOUBLE(result_)); -} - -TEST_F(DispatchedNPObjectTest, CanInvokeDoubleReturn) { - EXPECT_CALL(*object_, DoubleReturn()).WillOnce(Return(7.0)); - - EXPECT_TRUE(object_->Invoke( - NPBrowser::get()->GetStringIdentifier("doubleReturn"), - NULL, - 0, - &result_)); - EXPECT_TRUE(NPVARIANT_IS_DOUBLE(result_)); - EXPECT_EQ(7.0, NPVARIANT_TO_DOUBLE(result_)); -} - -TEST_F(DispatchedNPObjectTest, CanInvokeStringReturn) { - EXPECT_CALL(*object_, StringReturn()).WillOnce(Return(std::string("hello"))); - - EXPECT_TRUE(object_->Invoke( - NPBrowser::get()->GetStringIdentifier("stringReturn"), - NULL, - 0, - &result_)); - EXPECT_TRUE(NPVARIANT_IS_STRING(result_)); - - NPString& str = NPVARIANT_TO_STRING(result_); - EXPECT_EQ(std::string("hello"), - std::string(str.UTF8Characters, str.UTF8Length)); - - // Callee is responsible for releasing string. - NPBrowser::get()->ReleaseVariantValue(&result_); -} - -TEST_F(DispatchedNPObjectTest, CanInvokeObjectReturnWithObject) { - EXPECT_CALL(*object_, ObjectReturn()).WillOnce(Return(passed_object_)); - - EXPECT_TRUE(object_->Invoke( - NPBrowser::get()->GetStringIdentifier("objectReturn"), - NULL, - 0, - &result_)); - EXPECT_TRUE(NPVARIANT_IS_OBJECT(result_)); - EXPECT_EQ(passed_object_.Get(), NPVARIANT_TO_OBJECT(result_)); - - NPBrowser::get()->ReleaseVariantValue(&result_); -} - -TEST_F(DispatchedNPObjectTest, CanInvokeObjectReturnWithNull) { - EXPECT_CALL(*object_, ObjectReturn()) - .WillOnce(Return(NPObjectPointer())); - - EXPECT_TRUE(object_->Invoke( - NPBrowser::get()->GetStringIdentifier("objectReturn"), - NULL, - 0, - &result_)); - EXPECT_TRUE(NPVARIANT_IS_NULL(result_)); -} - -TEST_F(DispatchedNPObjectTest, HasMethodReturnsTrueIfMatchingMemberVariable) { - EXPECT_TRUE(object_->HasMethod( - NPBrowser::get()->GetStringIdentifier("objectReturn"))); -} - -TEST_F(DispatchedNPObjectTest, HasMethodReturnsTrueIfNoMatchingMemberVariable) { - EXPECT_FALSE(object_->HasMethod( - NPBrowser::get()->GetStringIdentifier("missing"))); -} - -TEST_F(DispatchedNPObjectTest, EnumeratesAllAvailableMethods) { - NPIdentifier* names; - uint32_t num_names; - ASSERT_TRUE(object_->Enumerate(&names, &num_names)); - - // Don't compare all of them; this test would need to change every time new - // dispatchers were added to the test NPObject class. Just compare the first - // registered (last in the dispatcher chain) and that more than one is - // returned. - EXPECT_GT(num_names, 1u); - EXPECT_EQ(NPBrowser::get()->GetStringIdentifier("voidReturnNoParams"), - names[num_names - 1]); - - NPBrowser::get()->MemFree(names); -} - -} // namespace gpu_plugin diff --git a/o3d/gpu/np_utils/dynamic_np_object.cc b/o3d/gpu/np_utils/dynamic_np_object.cc deleted file mode 100644 index 153c189..0000000 --- a/o3d/gpu/np_utils/dynamic_np_object.cc +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include "gpu/np_utils/dynamic_np_object.h" - -namespace gpu_plugin { - -DynamicNPObject::DynamicNPObject(NPP npp) { -} - -void DynamicNPObject::Invalidate() { - for (PropertyMap::iterator it = properties_.begin(); - it != properties_.end(); - ++it) { - it->second.Invalidate(); - } -} - -bool DynamicNPObject::HasProperty(NPIdentifier name) { - PropertyMap::iterator it = properties_.find(name); - return it != properties_.end(); -} - -bool DynamicNPObject::GetProperty(NPIdentifier name, NPVariant* result) { - PropertyMap::iterator it = properties_.find(name); - if (it == properties_.end()) - return false; - - it->second.CopyTo(result); - return true; -} - -bool DynamicNPObject::SetProperty(NPIdentifier name, const NPVariant* value) { - properties_[name] = *value; - return true; -} - -bool DynamicNPObject::RemoveProperty(NPIdentifier name) { - properties_.erase(name); - return false; -} - -bool DynamicNPObject::Enumerate(NPIdentifier** names, uint32_t* count) { - *names = static_cast( - NPBrowser::get()->MemAlloc(properties_.size() * sizeof(*names))); - *count = properties_.size(); - - int i = 0; - for (PropertyMap::iterator it = properties_.begin(); - it != properties_.end(); - ++it) { - (*names)[i] = it->first; - ++i; - } - - return true; -} -} // namespace gpu_plugin diff --git a/o3d/gpu/np_utils/dynamic_np_object.h b/o3d/gpu/np_utils/dynamic_np_object.h deleted file mode 100644 index 8dd4892..0000000 --- a/o3d/gpu/np_utils/dynamic_np_object.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2006-2008 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 GPU_NP_UTILS_DYNAMIC_NP_OBJECT_H_ -#define GPU_NP_UTILS_DYNAMIC_NP_OBJECT_H_ - -#include - -#include "gpu/np_utils/default_np_object.h" -#include "gpu/np_utils/np_utils.h" - -namespace gpu_plugin { - -// NPObjects of this type have a dictionary of property name / variant pairs -// that can be changed at runtime through NPAPI. -class DynamicNPObject : public DefaultNPObject { - public: - explicit DynamicNPObject(NPP npp); - - void Invalidate(); - bool HasProperty(NPIdentifier name); - bool GetProperty(NPIdentifier name, NPVariant* result); - bool SetProperty(NPIdentifier name, const NPVariant* value); - bool RemoveProperty(NPIdentifier name); - bool Enumerate(NPIdentifier** names, uint32_t* count); - - private: - typedef std::map PropertyMap; - PropertyMap properties_; - DISALLOW_COPY_AND_ASSIGN(DynamicNPObject); -}; -} // namespace gpu_plugin - -#endif // GPU_NP_UTILS_DYNAMIC_NP_OBJECT_H_ diff --git a/o3d/gpu/np_utils/dynamic_np_object_unittest.cc b/o3d/gpu/np_utils/dynamic_np_object_unittest.cc deleted file mode 100644 index 56fcff7..0000000 --- a/o3d/gpu/np_utils/dynamic_np_object_unittest.cc +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include - -#include "gpu/np_utils/dynamic_np_object.h" -#include "gpu/np_utils/np_browser_stub.h" -#include "gpu/np_utils/np_utils.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using testing::Return; -using testing::StrictMock; - -namespace gpu_plugin { - -class NPDynamicNPObjectTest : public testing::Test { - protected: - virtual void SetUp() { - object_ = NPCreateObject(NULL); - } - - StubNPBrowser stub_browser_; - NPObjectPointer object_; -}; - -TEST_F(NPDynamicNPObjectTest, HasPropertyReturnsFalseForMissingProperty) { - EXPECT_FALSE(NPHasProperty(NULL, object_, "missing")); -} - -TEST_F(NPDynamicNPObjectTest, GetPropertyReturnsFalseForMissingProperty) { - int32 r; - EXPECT_FALSE(NPGetProperty(NULL, object_, "missing", &r)); -} - -TEST_F(NPDynamicNPObjectTest, CanSetProperty) { - EXPECT_TRUE(NPSetProperty(NULL, object_, "foo", 7)); - int32 r; - EXPECT_TRUE(NPHasProperty(NULL, object_, "foo")); - EXPECT_TRUE(NPGetProperty(NULL, object_, "foo", &r)); - EXPECT_EQ(7, r); -} - -TEST_F(NPDynamicNPObjectTest, CanRemoveProperty) { - EXPECT_TRUE(NPSetProperty(NULL, object_, "foo", 7)); - EXPECT_TRUE(NPHasProperty(NULL, object_, "foo")); - EXPECT_FALSE(NPRemoveProperty(NULL, object_, "foo")); - EXPECT_FALSE(NPHasProperty(NULL, object_, "foo")); - int32 r; - EXPECT_FALSE(NPGetProperty(NULL, object_, "foo", &r)); -} - -TEST_F(NPDynamicNPObjectTest, CanEnumerateProperties) { - EXPECT_TRUE(NPSetProperty(NULL, object_, "foo", 7)); - - NPIdentifier* names; - uint32 num_names; - EXPECT_TRUE(object_->_class->enumerate(object_.Get(), &names, &num_names)); - - EXPECT_EQ(1, num_names); - EXPECT_EQ(NPBrowser::get()->GetStringIdentifier("foo"), names[0]); - - NPBrowser::get()->MemFree(names); -} - -// Properties should not be -TEST_F(NPDynamicNPObjectTest, InvalidateNullsObjectProperties) { - EXPECT_EQ(1, object_->referenceCount); - { - EXPECT_TRUE(NPSetProperty(NULL, object_, "foo", object_)); - EXPECT_TRUE(NPHasProperty(NULL, object_, "foo")); - object_->_class->invalidate(object_.Get()); - EXPECT_TRUE(NPHasProperty(NULL, object_, "foo")); - NPObjectPointer r; - EXPECT_TRUE(NPGetProperty(NULL, object_, "foo", &r)); - EXPECT_TRUE(NULL == r.Get()); - } - // Invalidate did not release object - EXPECT_EQ(2, object_->referenceCount); - NPBrowser::get()->ReleaseObject(object_.Get()); -} -} // namespace gpu_plugin diff --git a/o3d/gpu/np_utils/np_browser.cc b/o3d/gpu/np_utils/np_browser.cc deleted file mode 100644 index 3754d3b..0000000 --- a/o3d/gpu/np_utils/np_browser.cc +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include "gpu/np_utils/np_browser.h" -#include "base/logging.h" - -#if defined(O3D_IN_CHROME) -#include "webkit/glue/plugins/nphostapi.h" -#else -#include "o3d/third_party/npapi/include/npfunctions.h" -#endif - -namespace gpu_plugin { - -NPBrowser* NPBrowser::browser_; - -NPBrowser::NPBrowser(NPNetscapeFuncs* funcs) - : netscape_funcs_(funcs) { - // Make this the first browser in the linked list. - previous_browser_ = browser_; - browser_ = this; -} - -NPBrowser::~NPBrowser() { - // Remove this browser from the linked list. - DCHECK(browser_ == this); - browser_ = previous_browser_; -} - -NPIdentifier NPBrowser::GetStringIdentifier(const NPUTF8* name) { - return netscape_funcs_->getstringidentifier(name); -} - -void* NPBrowser::MemAlloc(size_t size) { - return netscape_funcs_->memalloc(size); -} - -void NPBrowser::MemFree(void* p) { - netscape_funcs_->memfree(p); -} - -NPObject* NPBrowser::CreateObject(NPP npp, const NPClass* cl) { - return netscape_funcs_->createobject(npp, const_cast(cl)); -} - -NPObject* NPBrowser::RetainObject(NPObject* object) { - return netscape_funcs_->retainobject(object); -} - -void NPBrowser::ReleaseObject(NPObject* object) { - netscape_funcs_->releaseobject(object); -} - -void NPBrowser::ReleaseVariantValue(NPVariant* variant) { - netscape_funcs_->releasevariantvalue(variant); -} - -bool NPBrowser::HasProperty(NPP npp, - NPObject* object, - NPIdentifier name) { - return netscape_funcs_->hasproperty(npp, object, name); -} - -bool NPBrowser::GetProperty(NPP npp, - NPObject* object, - NPIdentifier name, - NPVariant* result) { - return netscape_funcs_->getproperty(npp, object, name, result); -} - -bool NPBrowser::SetProperty(NPP npp, - NPObject* object, - NPIdentifier name, - const NPVariant* result) { - return netscape_funcs_->setproperty(npp, object, name, result); -} - -bool NPBrowser::RemoveProperty(NPP npp, - NPObject* object, - NPIdentifier name) { - return netscape_funcs_->removeproperty(npp, object, name); -} - -bool NPBrowser::HasMethod(NPP npp, - NPObject* object, - NPIdentifier name) { - return netscape_funcs_->hasmethod(npp, object, name); -} - -bool NPBrowser::Invoke(NPP npp, - NPObject* object, - NPIdentifier name, - const NPVariant* args, - uint32_t num_args, - NPVariant* result) { - return netscape_funcs_->invoke(npp, object, name, args, num_args, result); -} - -NPObject* NPBrowser::GetWindowNPObject(NPP npp) { - NPObject* window; - if (NPERR_NO_ERROR == netscape_funcs_->getvalue(npp, - NPNVWindowNPObject, - &window)) { - return window; - } else { - return NULL; - } -} - -void NPBrowser::PluginThreadAsyncCall(NPP npp, - PluginThreadAsyncCallProc callback, - void* data) { - netscape_funcs_->pluginthreadasynccall(npp, callback, data); -} - -uint32 NPBrowser::ScheduleTimer(NPP npp, - uint32 interval, - bool repeat, - TimerProc callback) { - return netscape_funcs_->scheduletimer(npp, interval, repeat, callback); -} - -void NPBrowser::UnscheduleTimer(NPP npp, uint32 timer_id) { - netscape_funcs_->unscheduletimer(npp, timer_id); -} - -} // namespace gpu_plugin diff --git a/o3d/gpu/np_utils/np_browser.h b/o3d/gpu/np_utils/np_browser.h deleted file mode 100644 index d792316..0000000 --- a/o3d/gpu/np_utils/np_browser.h +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) 2006-2008 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 GPU_NP_UTILS_NP_BROWSER_H_ -#define GPU_NP_UTILS_NP_BROWSER_H_ - -#include "base/basictypes.h" -#include "gpu/np_utils/np_headers.h" - -typedef struct _NPNetscapeFuncs NPNetscapeFuncs; - -namespace gpu_plugin { - -// This class exposes the functions provided by the browser to a plugin (the -// ones prefixed NPN_). -class NPBrowser { - public: - explicit NPBrowser(NPNetscapeFuncs* funcs); - virtual ~NPBrowser(); - - static NPBrowser* get() { - return browser_; - } - - // Standard functions from NPNetscapeFuncs. - - virtual NPIdentifier GetStringIdentifier(const NPUTF8* name); - - virtual void* MemAlloc(size_t size); - - virtual void MemFree(void* p); - - virtual NPObject* CreateObject(NPP npp, const NPClass* cl); - - virtual NPObject* RetainObject(NPObject* object); - - virtual void ReleaseObject(NPObject* object); - - virtual void ReleaseVariantValue(NPVariant* variant); - - virtual bool HasProperty(NPP npp, - NPObject* object, - NPIdentifier name); - - virtual bool GetProperty(NPP npp, - NPObject* object, - NPIdentifier name, - NPVariant* result); - - virtual bool SetProperty(NPP npp, - NPObject* object, - NPIdentifier name, - const NPVariant* result); - - virtual bool RemoveProperty(NPP npp, - NPObject* object, - NPIdentifier name); - - virtual bool HasMethod(NPP npp, - NPObject* object, - NPIdentifier name); - - virtual bool Invoke(NPP npp, - NPObject* object, - NPIdentifier name, - const NPVariant* args, - uint32_t num_args, - NPVariant* result); - - virtual NPObject* GetWindowNPObject(NPP npp); - - typedef void (*PluginThreadAsyncCallProc)(void* data); - virtual void PluginThreadAsyncCall(NPP npp, - PluginThreadAsyncCallProc callback, - void* data); - - typedef void (*TimerProc)(NPP npp, uint32 timer_id); - virtual uint32 ScheduleTimer(NPP npp, - uint32 interval, - bool repeat, - TimerProc callback); - - virtual void UnscheduleTimer(NPP npp, uint32 timer_id); - - private: - static NPBrowser* browser_; - NPBrowser* previous_browser_; - NPNetscapeFuncs* netscape_funcs_; - DISALLOW_COPY_AND_ASSIGN(NPBrowser); -}; - -} // namespace gpu_plugin - -#endif // GPU_NP_UTILS_NP_BROWSER_H_ diff --git a/o3d/gpu/np_utils/np_browser_mock.h b/o3d/gpu/np_utils/np_browser_mock.h deleted file mode 100644 index 1ef574e..0000000 --- a/o3d/gpu/np_utils/np_browser_mock.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2006-2008 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 GPU_NP_UTILS_NP_BROWSER_MOCK_H_ -#define GPU_NP_UTILS_NP_BROWSER_MOCK_H_ - -#include "gpu/np_utils/np_browser_stub.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace gpu_plugin { - -// This mocks certain member functions of the stub browser. Those relating -// to identifiers, memory management, reference counting and forwarding to -// NPObjects are deliberately not mocked so the mock browser can be used as -// normal for these calls. -class MockNPBrowser : public StubNPBrowser { - public: - NPObject* ConcreteCreateObject(NPP npp, const NPClass* cl) { - return StubNPBrowser::CreateObject(npp, cl); - } - - MockNPBrowser() { - // Do not mock CreateObject by default but allow it to be mocked so object - // creation can be intercepted. - ON_CALL(*this, CreateObject(testing::_, testing::_)) - .WillByDefault(testing::Invoke(this, - &MockNPBrowser::ConcreteCreateObject)); - } - - void ConcretePluginThreadAsyncCall(NPP npp, - PluginThreadAsyncCallProc callback, - void* data) { - return StubNPBrowser::PluginThreadAsyncCall(npp, callback, data); - } - - MOCK_METHOD2(CreateObject, NPObject*(NPP npp, const NPClass* cl)); - MOCK_METHOD1(GetWindowNPObject, NPObject*(NPP cpp)); - MOCK_METHOD3(PluginThreadAsyncCall, - void(NPP npp, PluginThreadAsyncCallProc callback, void* data)); - MOCK_METHOD4(ScheduleTimer, uint32(NPP npp, - uint32 interval, - bool repeat, - TimerProc callback)); - MOCK_METHOD2(UnscheduleTimer, void(NPP npp, uint32 timer_id)); -}; - -} // namespace gpu_plugin - -#endif // GPU_NP_UTILS_NP_BROWSER_MOCK_H_ diff --git a/o3d/gpu/np_utils/np_browser_stub.cc b/o3d/gpu/np_utils/np_browser_stub.cc deleted file mode 100644 index 2bc1c6a..0000000 --- a/o3d/gpu/np_utils/np_browser_stub.cc +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include "gpu/np_utils/np_browser_stub.h" -#include "base/logging.h" -#include "base/message_loop.h" - -namespace gpu_plugin { - -StubNPBrowser::StubNPBrowser() : NPBrowser(NULL) { -} - -StubNPBrowser::~StubNPBrowser() { -} - -NPIdentifier StubNPBrowser::GetStringIdentifier(const NPUTF8* name) { - static std::set names; - std::set::iterator it = names.find(name); - if (it == names.end()) { - it = names.insert(name).first; - } - return const_cast((*it).c_str()); -} - -void* StubNPBrowser::MemAlloc(size_t size) { - return malloc(size); -} - -void StubNPBrowser::MemFree(void* p) { - free(p); -} - -NPObject* StubNPBrowser::CreateObject(NPP npp, const NPClass* cl) { - NPObject* object = cl->allocate(npp, const_cast(cl)); - object->referenceCount = 1; - object->_class = const_cast(cl); - return object; -} - -NPObject* StubNPBrowser::RetainObject(NPObject* object) { - ++object->referenceCount; - return object; -} - -void StubNPBrowser::ReleaseObject(NPObject* object) { - DCHECK_GE(object->referenceCount, 0u); - --object->referenceCount; - if (object->referenceCount == 0) { - object->_class->deallocate(object); - } -} - -void StubNPBrowser::ReleaseVariantValue(NPVariant* variant) { - if (NPVARIANT_IS_STRING(*variant)) { - MemFree(const_cast(variant->value.stringValue.UTF8Characters)); - } else if (NPVARIANT_IS_OBJECT(*variant)) { - ReleaseObject(NPVARIANT_TO_OBJECT(*variant)); - } -} - -bool StubNPBrowser::HasProperty(NPP npp, - NPObject* object, - NPIdentifier name) { - return object->_class->hasProperty(object, name); -} - -bool StubNPBrowser::GetProperty(NPP npp, - NPObject* object, - NPIdentifier name, - NPVariant* result) { - return object->_class->getProperty(object, name, result); -} - -bool StubNPBrowser::SetProperty(NPP npp, - NPObject* object, - NPIdentifier name, - const NPVariant* result) { - return object->_class->setProperty(object, name, result); -} - -bool StubNPBrowser::RemoveProperty(NPP npp, - NPObject* object, - NPIdentifier name) { - return object->_class->removeProperty(object, name); -} - -bool StubNPBrowser::HasMethod(NPP npp, - NPObject* object, - NPIdentifier name) { - return object->_class->hasMethod(object, name); -} - -bool StubNPBrowser::Invoke(NPP npp, - NPObject* object, - NPIdentifier name, - const NPVariant* args, - uint32_t num_args, - NPVariant* result) { - return object->_class->invoke(object, name, args, num_args, result); -} - -NPObject* StubNPBrowser::GetWindowNPObject(NPP npp) { - return NULL; -} - -void StubNPBrowser::PluginThreadAsyncCall( - NPP npp, - PluginThreadAsyncCallProc callback, - void* data) { - MessageLoop::current()->PostTask(FROM_HERE, - NewRunnableFunction(callback, data)); -} - -uint32 StubNPBrowser::ScheduleTimer(NPP npp, - uint32 interval, - bool repeat, - TimerProc callback) { - return 0; -} - -void StubNPBrowser::UnscheduleTimer(NPP npp, uint32 timer_id) { -} - -} // namespace gpu_plugin diff --git a/o3d/gpu/np_utils/np_browser_stub.h b/o3d/gpu/np_utils/np_browser_stub.h deleted file mode 100644 index b18d52d..0000000 --- a/o3d/gpu/np_utils/np_browser_stub.h +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) 2006-2008 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 GPU_NP_UTILS_NP_BROWSER_STUB_H_ -#define GPU_NP_UTILS_NP_BROWSER_STUB_H_ - -#include -#include - -#include "gpu/np_utils/np_browser.h" - -namespace gpu_plugin { - -// Simple implementation of subset of the NPN functions for testing. -class StubNPBrowser : public NPBrowser { - public: - StubNPBrowser(); - virtual ~StubNPBrowser(); - - // Standard functions from NPNetscapeFuncs. - - virtual NPIdentifier GetStringIdentifier(const NPUTF8* name); - - virtual void* MemAlloc(size_t size); - - virtual void MemFree(void* p); - - virtual NPObject* CreateObject(NPP npp, const NPClass* cl); - - virtual NPObject* RetainObject(NPObject* object); - - virtual void ReleaseObject(NPObject* object); - - virtual void ReleaseVariantValue(NPVariant* variant); - - virtual bool HasProperty(NPP npp, - NPObject* object, - NPIdentifier name); - - virtual bool GetProperty(NPP npp, - NPObject* object, - NPIdentifier name, - NPVariant* result); - - virtual bool SetProperty(NPP npp, - NPObject* object, - NPIdentifier name, - const NPVariant* result); - - virtual bool RemoveProperty(NPP npp, - NPObject* object, - NPIdentifier name); - - virtual bool HasMethod(NPP npp, - NPObject* object, - NPIdentifier name); - virtual bool Invoke(NPP npp, - NPObject* object, - NPIdentifier name, - const NPVariant* args, - uint32_t num_args, - NPVariant* result); - - virtual NPObject* GetWindowNPObject(NPP npp); - - virtual void PluginThreadAsyncCall(NPP npp, - PluginThreadAsyncCallProc callback, - void* data); - - virtual uint32 ScheduleTimer(NPP npp, - uint32 interval, - bool repeat, - TimerProc callback); - - virtual void UnscheduleTimer(NPP npp, uint32 timer_id); - - private: - DISALLOW_COPY_AND_ASSIGN(StubNPBrowser); -}; - -} // namespace gpu_plugin - -#endif // GPU_NP_UTILS_NP_BROWSER_STUB_H_ diff --git a/o3d/gpu/np_utils/np_class.h b/o3d/gpu/np_utils/np_class.h deleted file mode 100644 index 113f493..0000000 --- a/o3d/gpu/np_utils/np_class.h +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) 2006-2008 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 GPU_NP_UTILS_NP_CLASS_H_ -#define GPU_NP_UTILS_NP_CLASS_H_ - -#include "gpu/np_utils/np_object_pointer.h" -#include "gpu/np_utils/np_headers.h" - -// This file implements NPGetClass. This function returns an NPClass -// that can be used to instantiate an NPObject subclass T. The NPClass -// function pointers will invoke the most derived corresponding member -// functions in T. - -namespace gpu_plugin { - -namespace np_class_impl { - // This template version of the NPClass allocate function creates a subclass - // of BaseNPObject. - template - static NPObject* Allocate(NPP npp, NPClass*) { - return new NPObjectType(npp); - } - - // These implementations of the NPClass functions forward to the virtual - // functions in DefaultNPObject. - template - static void Deallocate(NPObject* object) { - delete static_cast(object); - } - - template - static void Invalidate(NPObject* object) { - return static_cast(object)->Invalidate(); - } - - template - static bool HasMethod(NPObject* object, NPIdentifier name) { - return static_cast(object)->HasMethod(name); - } - - template - static bool Invoke(NPObject* object, - NPIdentifier name, - const NPVariant* args, - uint32_t num_args, - NPVariant* result) { - return static_cast(object)->Invoke( - name, args, num_args, result); - } - - template - static bool InvokeDefault(NPObject* object, - const NPVariant* args, - uint32_t num_args, - NPVariant* result) { - return static_cast(object)->InvokeDefault( - args, num_args, result); - } - - template - static bool HasProperty(NPObject* object, NPIdentifier name) { - return static_cast(object)->HasProperty(name); - } - - template - static bool GetProperty(NPObject* object, - NPIdentifier name, - NPVariant* result) { - return static_cast(object)->GetProperty(name, result); - } - - template - static bool SetProperty(NPObject* object, - NPIdentifier name, - const NPVariant* value) { - return static_cast(object)->SetProperty(name, value); - } - - template - static bool RemoveProperty(NPObject* object, NPIdentifier name) { - return static_cast(object)->RemoveProperty(name); - } - - template - static bool Enumerate(NPObject* object, - NPIdentifier** names, - uint32_t* count) { - return static_cast(object)->Enumerate(names, count); - }; - - template - static bool Construct(NPObject* object, - const NPVariant* args, - uint32_t num_args, - NPVariant* result) { - return static_cast(object)->Construct( - args, num_args, result); - } -} // namespace np_class_impl; - -template -const NPClass* NPGetClass() { - static const NPClass np_class = { - NP_CLASS_STRUCT_VERSION, - np_class_impl::Allocate, - np_class_impl::Deallocate, - np_class_impl::Invalidate, - np_class_impl::HasMethod, - np_class_impl::Invoke, - np_class_impl::InvokeDefault, - np_class_impl::HasProperty, - np_class_impl::GetProperty, - np_class_impl::SetProperty, - np_class_impl::RemoveProperty, - np_class_impl::Enumerate, - np_class_impl::Construct, - }; - return &np_class; -}; - -} // namespace gpu_plugin - -#endif // GPU_NP_UTILS_NP_CLASS_H_ diff --git a/o3d/gpu/np_utils/np_class_unittest.cc b/o3d/gpu/np_utils/np_class_unittest.cc deleted file mode 100644 index 0db632b..0000000 --- a/o3d/gpu/np_utils/np_class_unittest.cc +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include "gpu/np_utils/np_class.h" -#include "gpu/np_utils/np_object_mock.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using testing::StrictMock; - -namespace gpu_plugin { - -class NPClassTest : public testing::Test { - protected: - virtual void SetUp() { - np_class = NPGetClass >(); - - // Dummy identifier is never used with real NPAPI so it can point to - // anything. - identifier = this; - } - - virtual void TearDown() { - } - - NPP_t npp_; - const NPClass* np_class; - NPIdentifier identifier; - NPVariant args[3]; - NPVariant result; -}; - -TEST_F(NPClassTest, AllocateAndDeallocateObject) { - MockNPObject* object = static_cast( - np_class->allocate(&npp_, const_cast(np_class))); - EXPECT_TRUE(NULL != object); - - np_class->deallocate(object); -} - -TEST_F(NPClassTest, InvalidateForwards) { - MockNPObject* object = static_cast( - np_class->allocate(&npp_, const_cast(np_class))); - - EXPECT_CALL(*object, Invalidate()); - np_class->invalidate(object); - - np_class->deallocate(object); -} - -TEST_F(NPClassTest, HasMethodForwards) { - MockNPObject* object = static_cast( - np_class->allocate(&npp_, const_cast(np_class))); - - EXPECT_CALL(*object, HasMethod(identifier)); - np_class->hasMethod(object, identifier); - - np_class->deallocate(object); -} - -TEST_F(NPClassTest, InvokeForwards) { - MockNPObject* object = static_cast( - np_class->allocate(&npp_, const_cast(np_class))); - - EXPECT_CALL(*object, Invoke(identifier, args, 3, &result)); - np_class->invoke(object, identifier, args, 3, &result); - - np_class->deallocate(object); -} - -TEST_F(NPClassTest, InvokeDefaultForwards) { - MockNPObject* object = static_cast( - np_class->allocate(&npp_, const_cast(np_class))); - - EXPECT_CALL(*object, InvokeDefault(args, 3, &result)); - np_class->invokeDefault(object, args, 3, &result); - - np_class->deallocate(object); -} - -TEST_F(NPClassTest, HasPropertyForwards) { - MockNPObject* object = static_cast( - np_class->allocate(&npp_, const_cast(np_class))); - - EXPECT_CALL(*object, HasProperty(identifier)); - np_class->hasProperty(object, identifier); - - np_class->deallocate(object); -} - -TEST_F(NPClassTest, GetPropertyForwards) { - MockNPObject* object = static_cast( - np_class->allocate(&npp_, const_cast(np_class))); - - EXPECT_CALL(*object, GetProperty(identifier, &result)); - np_class->getProperty(object, identifier, &result); - - np_class->deallocate(object); -} - -TEST_F(NPClassTest, SetPropertyForwards) { - MockNPObject* object = static_cast( - np_class->allocate(&npp_, const_cast(np_class))); - - EXPECT_CALL(*object, SetProperty(identifier, &result)); - np_class->setProperty(object, identifier, &result); - - np_class->deallocate(object); -} - -TEST_F(NPClassTest, RemovePropertyForwards) { - MockNPObject* object = static_cast( - np_class->allocate(&npp_, const_cast(np_class))); - - EXPECT_CALL(*object, RemoveProperty(identifier)); - np_class->removeProperty(object, identifier); - - np_class->deallocate(object); -} - -TEST_F(NPClassTest, EnumerateForwards) { - MockNPObject* object = static_cast( - np_class->allocate(&npp_, const_cast(np_class))); - - NPIdentifier* identifier = NULL; - uint32_t count; - EXPECT_CALL(*object, Enumerate(&identifier, &count)); - np_class->enumerate(object, &identifier, &count); - - np_class->deallocate(object); -} - -TEST_F(NPClassTest, ConstructForwards) { - MockNPObject* object = static_cast( - np_class->allocate(&npp_, const_cast(np_class))); - - EXPECT_CALL(*object, Construct(args, 3, &result)); - np_class->construct(object, args, 3, &result); - - np_class->deallocate(object); -} -} // namespace gpu_plugin diff --git a/o3d/gpu/np_utils/np_dispatcher.cc b/o3d/gpu/np_utils/np_dispatcher.cc deleted file mode 100644 index cf8eeff..0000000 --- a/o3d/gpu/np_utils/np_dispatcher.cc +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include "gpu/np_utils/np_dispatcher.h" - -namespace gpu_plugin { - -bool DispatcherHasMethodHelper(BaseNPDispatcher* chain, - NPObject* object, - NPIdentifier name) { - for (BaseNPDispatcher* dispatcher = chain; - dispatcher; - dispatcher = dispatcher->next()) { - if (dispatcher->name() == name) { - return true; - } - } - - return false; -} - -bool DispatcherInvokeHelper(BaseNPDispatcher* chain, - NPObject* object, - NPIdentifier name, - const NPVariant* args, - uint32_t num_args, - NPVariant* result) { - VOID_TO_NPVARIANT(*result); - - for (BaseNPDispatcher* dispatcher = chain; - dispatcher; - dispatcher = dispatcher->next()) { - if (dispatcher->name() == name && dispatcher->num_args() == num_args) { - if (dispatcher->Invoke(object, args, num_args, result)) - return true; - } - } - - return false; -} - -bool DispatcherEnumerateHelper(BaseNPDispatcher* chain, - NPObject* object, - NPIdentifier** names, - uint32_t* num_names) { - // Count the number of names. - *num_names = 0; - for (BaseNPDispatcher* dispatcher = chain; - dispatcher; - dispatcher = dispatcher->next()) { - ++(*num_names); - } - - // Copy names into the array. - *names = static_cast( - NPBrowser::get()->MemAlloc((*num_names) * sizeof(**names))); - int i = 0; - for (BaseNPDispatcher* dispatcher = chain; - dispatcher; - dispatcher = dispatcher->next()) { - (*names)[i] = dispatcher->name(); - ++i; - } - - return true; -} - -BaseNPDispatcher::BaseNPDispatcher(BaseNPDispatcher* next, const NPUTF8* name) - : next_(next) { - // Convert first character to lower case if it is the ASCII range. - // TODO(apatrick): do this correctly for non-ASCII characters. - std::string java_script_style_name(name); - if (isupper(java_script_style_name[0])) { - java_script_style_name[0] = tolower(java_script_style_name[0]); - } - - name_ = NPBrowser::get()->GetStringIdentifier( - java_script_style_name.c_str()); -} - -BaseNPDispatcher::~BaseNPDispatcher() { -} - -} // namespace gpu_plugin diff --git a/o3d/gpu/np_utils/np_dispatcher.h b/o3d/gpu/np_utils/np_dispatcher.h deleted file mode 100644 index 5b84f86..0000000 --- a/o3d/gpu/np_utils/np_dispatcher.h +++ /dev/null @@ -1,222 +0,0 @@ -// Copyright (c) 2006-2008 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 GPU_NP_UTILS_NP_DISPATCHER_H_ -#define GPU_NP_UTILS_NP_DISPATCHER_H_ - -#include - -#include "gpu/np_utils/np_utils.h" -#include "gpu/np_utils/np_headers.h" - -// Dispatchers make regular member functions available as NPObject methods. -// Usage: -// -// class MyNPObject : public DefaultNPObject { -// public: -// int MyMethod(bool a, float b); -// NP_UTILS_BEGIN_DISPATCHER_CHAIN(MyNPObject, DispatchedNPObject) -// NP_UTILS_DISPATCHER(MyMethod, int(bool, float)) -// NP_UTILS_END_DISPATCHER_CHAIN -// }; -// -// Multiple member functions may be listed in the dispatcher chain. Inheritance -// is supported. The following types are supported as return types and parameter -// types: -// * bool -// * int -// * float -// * double -// * std::string -// * NPObject* -// - -// These macros are used to make dispatcher chains. -#define NP_UTILS_NP_UTILS_DISPATCHER_JOIN2(a, b) a ## b -#define NP_UTILS_DISPATCHER_JOIN(a, b) NP_UTILS_NP_UTILS_DISPATCHER_JOIN2(a, b) -#define NP_UTILS_DISPATCHER_UNIQUE \ - NP_UTILS_DISPATCHER_JOIN(dispatcher, __LINE__) - -#define NP_UTILS_BEGIN_DISPATCHER_CHAIN(Class, BaseClass) \ - static BaseNPDispatcher* GetDispatcherChain() { \ - typedef Class ThisClass; \ - BaseNPDispatcher* top_dispatcher = BaseClass::GetDispatcherChain(); \ - -#define NP_UTILS_DISPATCHER(name, Signature) \ - static NPDispatcher \ - NP_UTILS_DISPATCHER_UNIQUE( \ - top_dispatcher, \ - #name, \ - &ThisClass::name); \ - top_dispatcher = &NP_UTILS_DISPATCHER_UNIQUE; \ - -#define NP_UTILS_END_DISPATCHER_CHAIN \ - return top_dispatcher; \ - } \ - bool HasMethod(NPIdentifier name) { \ - return DispatcherHasMethodHelper(GetDispatcherChain(), this, name); \ - } \ - bool Invoke(NPIdentifier name, \ - const NPVariant* args, \ - uint32_t num_args, \ - NPVariant* result) { \ - return DispatcherInvokeHelper(GetDispatcherChain(), \ - this, \ - name, \ - args, \ - num_args, \ - result); \ - } \ - bool Enumerate(NPIdentifier** names, uint32_t* num_names) { \ - return DispatcherEnumerateHelper(GetDispatcherChain(), \ - this, \ - names, \ - num_names); \ - } \ - -namespace gpu_plugin { - -class BaseNPDispatcher { - public: - BaseNPDispatcher(BaseNPDispatcher* next, const NPUTF8* name); - - virtual ~BaseNPDispatcher(); - - BaseNPDispatcher* next() const { - return next_; - } - - NPIdentifier name() const { - return name_; - } - - virtual int num_args() const = 0; - - virtual bool Invoke(NPObject* object, - const NPVariant* args, - uint32_t num_args, - NPVariant* result) = 0; - - private: - BaseNPDispatcher* next_; - NPIdentifier name_; - DISALLOW_COPY_AND_ASSIGN(BaseNPDispatcher); -}; - -bool DispatcherHasMethodHelper(BaseNPDispatcher* chain, - NPObject* object, - NPIdentifier name); - -bool DispatcherInvokeHelper(BaseNPDispatcher* chain, - NPObject* object, - NPIdentifier name, - const NPVariant* args, - uint32_t num_args, - NPVariant* result); - -bool DispatcherEnumerateHelper(BaseNPDispatcher* chain, - NPObject* object, - NPIdentifier** names, - uint32_t* num_names); - -// This class should never be instantiated. It is always specialized. Attempting -// to instantiate it results in a compilation error. This might mean an -// attempt to instantiate a dispatcher with more parameters than have been -// specialized for. See the specialization code below. -template -struct NPDispatcher { -}; - -#define TO_NPVARIANT(index) \ - T##index n##index; \ - if (!NPVariantToValue(&n##index, args[index])) \ - return false; \ - -#define NUM_PARAMS 0 -#define PARAM_TYPENAMES -#define PARAM_TYPES -#define PARAM_NAMES -#define PARAM_DECLS // NOLINT - -#define PARAM_TO_NVPARIANT_CONVERSIONS \ - -#include "gpu/np_utils/np_dispatcher_specializations.h" // NOLINT - - -#define NUM_PARAMS 1 -#define PARAM_TYPENAMES , typename T0 -#define PARAM_TYPES T0 -#define PARAM_NAMES n0 -#define PARAM_DECLS T0 n0; // NOLINT - -#define PARAM_TO_NVPARIANT_CONVERSIONS \ - TO_NPVARIANT(0); \ - -#include "gpu/np_utils/np_dispatcher_specializations.h" // NOLINT - - -#define NUM_PARAMS 2 -#define PARAM_TYPENAMES , typename T0, typename T1 -#define PARAM_TYPES T0, T1 -#define PARAM_NAMES n0, n1 -#define PARAM_DECLS T0 n0; T1 n1; // NOLINT - -#define PARAM_TO_NVPARIANT_CONVERSIONS \ - TO_NPVARIANT(0); \ - TO_NPVARIANT(1); \ - -#include "gpu/np_utils/np_dispatcher_specializations.h" // NOLINT - - -#define NUM_PARAMS 3 -#define PARAM_TYPENAMES , typename T0, typename T1, typename T2 -#define PARAM_TYPES T0, T1, T2 -#define PARAM_NAMES n0, n1, n2 -#define PARAM_DECLS T0 n0; T1 n1; T2 n2; // NOLINT - -#define PARAM_TO_NVPARIANT_CONVERSIONS \ - TO_NPVARIANT(0); \ - TO_NPVARIANT(1); \ - TO_NPVARIANT(2); \ - -#include "gpu/np_utils/np_dispatcher_specializations.h" // NOLINT - - -#define NUM_PARAMS 4 -#define PARAM_TYPENAMES , typename T0, typename T1, typename T2, typename T3 -#define PARAM_TYPES T0, T1, T2, T3 -#define PARAM_NAMES n0, n1, n2, n3 -#define PARAM_DECLS T0 n0; T1 n1; T2 n2; T3 n3; // NOLINT - -#define PARAM_TO_NVPARIANT_CONVERSIONS \ - TO_NPVARIANT(0); \ - TO_NPVARIANT(1); \ - TO_NPVARIANT(2); \ - TO_NPVARIANT(3); \ - -#include "gpu/np_utils/np_dispatcher_specializations.h" // NOLINT - - -#define NUM_PARAMS 5 -#define PARAM_TYPENAMES , typename T0, typename T1, typename T2, typename T3, \ - typename T4 -#define PARAM_TYPES T0, T1, T2, T3, T4 -#define PARAM_NAMES n0, n1, n2, n3, n4 -#define PARAM_DECLS T0 n0; T1 n1; T2 n2; T3 n3; T4 n4; // NOLINT - -#define PARAM_TO_NVPARIANT_CONVERSIONS \ - TO_NPVARIANT(0); \ - TO_NPVARIANT(1); \ - TO_NPVARIANT(2); \ - TO_NPVARIANT(3); \ - TO_NPVARIANT(4); \ - -#include "gpu/np_utils/np_dispatcher_specializations.h" // NOLINT - - -#undef TO_NPVARIANT - -} // namespace gpu_plugin - -#endif // GPU_NP_UTILS_NP_DISPATCHER_H_ diff --git a/o3d/gpu/np_utils/np_dispatcher_specializations.h b/o3d/gpu/np_utils/np_dispatcher_specializations.h deleted file mode 100644 index 62fb8c4..0000000 --- a/o3d/gpu/np_utils/np_dispatcher_specializations.h +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 2006-2008 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. - -// There is deliberately no header guard here. This file is included multiple -// times, once for each dispatcher specialiation arity. Do not include this -// file directly. Include np_dispatcher.h instead. - -template -class NPDispatcher - : public BaseNPDispatcher { - typedef void (NPObjectType::*FunctionType)(PARAM_TYPES); - public: - NPDispatcher(BaseNPDispatcher* next, - const NPUTF8* name, - FunctionType function) - : BaseNPDispatcher(next, name), - function_(function) { - } - - virtual bool Invoke(NPObject* object, - const NPVariant* args, - uint32_t num_args, - NPVariant* result) { - VOID_TO_NPVARIANT(*result); - - if (num_args != NUM_PARAMS) - return false; - - PARAM_TO_NVPARIANT_CONVERSIONS - - (static_cast(object)->*function_)(PARAM_NAMES); - return true; - } - - virtual int num_args() const { - return NUM_PARAMS; - } - - private: - FunctionType function_; -}; - -template -class NPDispatcher - : public BaseNPDispatcher { - typedef R (NPObjectType::*FunctionType)(PARAM_TYPES); - public: - NPDispatcher(BaseNPDispatcher* next, - const NPUTF8* name, - FunctionType function) - : BaseNPDispatcher(next, name), - function_(function) { - } - - virtual bool Invoke(NPObject* object, - const NPVariant* args, - uint32_t num_args, - NPVariant* result) { - VOID_TO_NPVARIANT(*result); - - if (num_args != NUM_PARAMS) - return false; - - PARAM_TO_NVPARIANT_CONVERSIONS - - ValueToNPVariant( - (static_cast(object)->*function_)(PARAM_NAMES), result); - return true; - } - - virtual int num_args() const { - return NUM_PARAMS; - } - - private: - FunctionType function_; -}; - -#undef NUM_PARAMS -#undef PARAM_TYPENAMES -#undef PARAM_TYPES -#undef PARAM_NAMES -#undef PARAM_DECLS -#undef PARAM_TO_NVPARIANT_CONVERSIONS diff --git a/o3d/gpu/np_utils/np_headers.h b/o3d/gpu/np_utils/np_headers.h deleted file mode 100644 index 5f60d8e..0000000 --- a/o3d/gpu/np_utils/np_headers.h +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2006-2008 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 GPU_NP_UTILS_NP_HEADERS_H_ -#define GPU_NP_UTILS_NP_HEADERS_H_ - -#if defined(O3D_IN_CHROME) -#include "third_party/npapi/bindings/npapi.h" -#include "third_party/npapi/bindings/npruntime.h" -#else -#include "o3d/third_party/npapi/include/npapi.h" -#include "o3d/third_party/npapi/include/npruntime.h" -#endif - -#endif // GPU_NP_UTILS_NP_HEADERS_H_ diff --git a/o3d/gpu/np_utils/np_object_mock.h b/o3d/gpu/np_utils/np_object_mock.h deleted file mode 100644 index 8c3d0e7..0000000 --- a/o3d/gpu/np_utils/np_object_mock.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2006-2008 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 GPU_NP_UTILS_NP_OBJECT_MOCK_H_ -#define GPU_NP_UTILS_NP_OBJECT_MOCK_H_ - -#include "gpu/np_utils/np_browser.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace gpu_plugin { - -class MockNPObject : public NPObject { - public: - explicit MockNPObject(NPP npp) { - } - - MOCK_METHOD0(Invalidate, void()); - MOCK_METHOD1(HasMethod, bool(NPIdentifier)); - MOCK_METHOD4(Invoke, - bool(NPIdentifier, const NPVariant*, uint32_t, NPVariant*)); - MOCK_METHOD3(InvokeDefault, bool(const NPVariant*, uint32_t, NPVariant*)); - MOCK_METHOD1(HasProperty, bool(NPIdentifier)); - MOCK_METHOD2(GetProperty, bool(NPIdentifier, NPVariant*)); - MOCK_METHOD2(SetProperty, bool(NPIdentifier, const NPVariant*)); - MOCK_METHOD1(RemoveProperty, bool(NPIdentifier)); - MOCK_METHOD2(Enumerate, bool(NPIdentifier**, uint32_t*)); - MOCK_METHOD3(Construct, bool(const NPVariant*, uint32_t, NPVariant*)); - - private: - DISALLOW_COPY_AND_ASSIGN(MockNPObject); -}; - -} // namespace gpu_plugin - -#endif // GPU_NP_UTILS_NP_OBJECT_MOCK_H_ diff --git a/o3d/gpu/np_utils/np_object_pointer.h b/o3d/gpu/np_utils/np_object_pointer.h deleted file mode 100644 index a8987be..0000000 --- a/o3d/gpu/np_utils/np_object_pointer.h +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) 2006-2008 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 GPU_NP_UTILS_NP_OBJECT_POINTER_H_ -#define GPU_NP_UTILS_NP_OBJECT_POINTER_H_ - -#include "base/logging.h" -#include "gpu/np_utils/np_browser.h" -#include "gpu/np_utils/np_headers.h" - -namespace gpu_plugin { - -// Smart pointer for NPObjects that automatically handles reference counting. -template -class NPObjectPointer { - public: - NPObjectPointer() : object_(NULL) {} - - NPObjectPointer(const NPObjectPointer& rhs) : object_(rhs.object_) { - Retain(); - } - - explicit NPObjectPointer(NPObjectType* p) : object_(p) { - Retain(); - } - - template - NPObjectPointer(const NPObjectPointer& rhs) : object_(rhs.Get()) { - Retain(); - } - - ~NPObjectPointer() { - Release(); - } - - NPObjectPointer& operator=(const NPObjectPointer& rhs) { - if (object_ == rhs.Get()) - return *this; - - Release(); - object_ = rhs.object_; - Retain(); - return *this; - } - - template - NPObjectPointer& operator=(const NPObjectPointer& rhs) { - if (object_ == rhs.Get()) - return *this; - - Release(); - object_ = rhs.Get(); - Retain(); - return *this; - } - - template - bool operator==(const NPObjectPointer& rhs) const { - return object_ == rhs.Get(); - } - - template - bool operator!=(const NPObjectPointer& rhs) const { - return object_ != rhs.Get(); - } - - // The NPObject convention for returning an NPObject pointer from a function - // is that the caller is responsible for releasing the reference count. - static NPObjectPointer FromReturned(NPObjectType* p) { - NPObjectPointer pointer(p); - pointer.Release(); - return pointer; - } - - // The NPObject convention for returning an NPObject pointer from a function - // is that the caller is responsible for releasing the reference count. - NPObjectType* ToReturned() const { - Retain(); - return object_; - } - - NPObjectType* Get() const { - return object_; - } - - NPObjectType* operator->() const { - return object_; - } - - NPObjectType& operator*() const { - return *object_; - } - - private: - void Retain() const { - if (object_) { - NPBrowser::get()->RetainObject(object_); - } - } - - void Release() const { - if (object_) { - NPBrowser::get()->ReleaseObject(object_); - } - } - - NPObjectType* object_; -}; - -// For test diagnostics. -template -std::ostream& operator<<(std::ostream& stream, - const NPObjectPointer& pointer) { - return stream << pointer.Get(); -} -} // namespace gpu_plugin - -#endif // GPU_NP_UTILS_NP_OBJECT_POINTER_H_ diff --git a/o3d/gpu/np_utils/np_object_pointer_unittest.cc b/o3d/gpu/np_utils/np_object_pointer_unittest.cc deleted file mode 100644 index c14f6ed..0000000 --- a/o3d/gpu/np_utils/np_object_pointer_unittest.cc +++ /dev/null @@ -1,220 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include "gpu/np_utils/np_class.h" -#include "gpu/np_utils/np_object_mock.h" -#include "gpu/np_utils/np_browser_stub.h" -#include "gpu/np_utils/np_object_pointer.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using testing::Return; -using testing::StrictMock; - -namespace gpu_plugin { - -class DerivedNPObject : public MockNPObject { - public: - explicit DerivedNPObject(NPP npp) : MockNPObject(npp) { - } -}; - -class NPObjectPointerTest : public testing::Test { - protected: - virtual void SetUp() { - np_class_ = NPGetClass >(); - - raw_pointer_ = static_cast( - NPBrowser::get()->CreateObject(NULL, np_class_)); - - raw_derived_pointer_ = static_cast( - NPBrowser::get()->CreateObject(NULL, np_class_)); - } - - virtual void TearDown() { - NPBrowser::get()->ReleaseObject(raw_pointer_); - NPBrowser::get()->ReleaseObject(raw_derived_pointer_); - } - - StubNPBrowser stub_browser_; - const NPClass* np_class_; - MockNPObject* raw_pointer_; - DerivedNPObject* raw_derived_pointer_; -}; - -TEST_F(NPObjectPointerTest, PointerIsNullByDefault) { - NPObjectPointer p; - ASSERT_TRUE(NULL == p.Get()); -} - -TEST_F(NPObjectPointerTest, PointerCanBeExplicitlyConstructedFromRawPointer) { - EXPECT_EQ(1, raw_pointer_->referenceCount); - { - NPObjectPointer p(raw_pointer_); - ASSERT_TRUE(raw_pointer_ == p.Get()); - EXPECT_EQ(2, raw_pointer_->referenceCount); - } - EXPECT_EQ(1, raw_pointer_->referenceCount); -} - -TEST_F(NPObjectPointerTest, - PointerCanBeExplicitlyConstructedFromNullRawPointer) { - NPObjectPointer p(NULL); - ASSERT_TRUE(NULL == p.Get()); -} - -TEST_F(NPObjectPointerTest, PointerCanBeCopyConstructed) { - NPObjectPointer p1(raw_pointer_); - EXPECT_EQ(2, raw_pointer_->referenceCount); - { - NPObjectPointer p2(p1); - ASSERT_TRUE(raw_pointer_ == p2.Get()); - EXPECT_EQ(3, raw_pointer_->referenceCount); - } - EXPECT_EQ(2, raw_pointer_->referenceCount); -} - -TEST_F(NPObjectPointerTest, PointerCanBeConstructedFromDerived) { - NPObjectPointer p1(raw_derived_pointer_); - EXPECT_EQ(2, raw_derived_pointer_->referenceCount); - { - NPObjectPointer p2(p1); - ASSERT_TRUE(raw_derived_pointer_ == p2.Get()); - EXPECT_EQ(3, raw_derived_pointer_->referenceCount); - } - EXPECT_EQ(2, raw_derived_pointer_->referenceCount); -} - -TEST_F(NPObjectPointerTest, - PointerCanBeCopyConstructedFromNull) { - NPObjectPointer p(NULL); - ASSERT_TRUE(NULL == p.Get()); -} - -TEST_F(NPObjectPointerTest, PointerCanBeAssigned) { - NPObjectPointer p1(raw_pointer_); - EXPECT_EQ(2, raw_pointer_->referenceCount); - { - NPObjectPointer p2; - p2 = p1; - ASSERT_TRUE(raw_pointer_ == p2.Get()); - EXPECT_EQ(3, raw_pointer_->referenceCount); - - p2 = NPObjectPointer(); - ASSERT_TRUE(NULL == p2.Get()); - EXPECT_EQ(2, raw_pointer_->referenceCount); - - p2 = p1; - ASSERT_TRUE(raw_pointer_ == p2.Get()); - EXPECT_EQ(3, raw_pointer_->referenceCount); - } - EXPECT_EQ(2, raw_pointer_->referenceCount); -} - -TEST_F(NPObjectPointerTest, PointerCanBeAssignedToSelf) { - NPObjectPointer p(raw_pointer_); - NPBrowser::get()->ReleaseObject(raw_pointer_); - EXPECT_EQ(1, raw_pointer_->referenceCount); - p = p; - EXPECT_EQ(1, raw_pointer_->referenceCount); - NPBrowser::get()->RetainObject(raw_pointer_); -} - -TEST_F(NPObjectPointerTest, PointerCanBeAssignedDerived) { - NPObjectPointer p1(raw_derived_pointer_); - EXPECT_EQ(2, raw_derived_pointer_->referenceCount); - { - NPObjectPointer p2; - p2 = p1; - ASSERT_TRUE(raw_derived_pointer_ == p2.Get()); - EXPECT_EQ(3, raw_derived_pointer_->referenceCount); - - p2 = NPObjectPointer(); - ASSERT_TRUE(NULL == p2.Get()); - EXPECT_EQ(2, raw_derived_pointer_->referenceCount); - - p2 = p1; - ASSERT_TRUE(raw_derived_pointer_ == p2.Get()); - EXPECT_EQ(3, raw_derived_pointer_->referenceCount); - } - EXPECT_EQ(2, raw_derived_pointer_->referenceCount); -} - -TEST_F(NPObjectPointerTest, DerivedPointerCanBeAssignedToSelf) { - NPObjectPointer p1(raw_derived_pointer_); - NPObjectPointer p2(raw_derived_pointer_); - NPBrowser::get()->ReleaseObject(raw_derived_pointer_); - NPBrowser::get()->ReleaseObject(raw_derived_pointer_); - EXPECT_EQ(1, raw_derived_pointer_->referenceCount); - p1 = p2; - EXPECT_EQ(1, raw_derived_pointer_->referenceCount); - NPBrowser::get()->RetainObject(raw_derived_pointer_); - NPBrowser::get()->RetainObject(raw_derived_pointer_); -} - -TEST_F(NPObjectPointerTest, CanComparePointersForEqual) { - NPObjectPointer p1(raw_pointer_); - NPObjectPointer p2(raw_derived_pointer_); - EXPECT_TRUE(p1 == p1); - EXPECT_FALSE(p1 == p2); - EXPECT_FALSE(p2 == p1); - EXPECT_FALSE(p1 == NPObjectPointer()); -} - -TEST_F(NPObjectPointerTest, CanComparePointersForNotEqual) { - NPObjectPointer p1(raw_pointer_); - NPObjectPointer p2(raw_derived_pointer_); - EXPECT_FALSE(p1 != p1); - EXPECT_TRUE(p1 != p2); - EXPECT_TRUE(p2 != p1); - EXPECT_TRUE(p1 != NPObjectPointer()); -} - -TEST_F(NPObjectPointerTest, ArrowOperatorCanBeUsedToAccessNPObjectMembers) { - NPIdentifier name = NPBrowser::get()->GetStringIdentifier("hello"); - - EXPECT_CALL(*raw_pointer_, HasProperty(name)).WillOnce(Return(true)); - - NPObjectPointer p(raw_pointer_); - EXPECT_TRUE(p->HasProperty(name)); -} - -TEST_F(NPObjectPointerTest, StarOperatorReturnsNPObjectReference) { - NPObjectPointer p(raw_pointer_); - EXPECT_EQ(raw_pointer_, &*p); -} - -TEST_F(NPObjectPointerTest, PointerCanBeConstructedFromReturnedNPObject) { - NPBrowser::get()->RetainObject(raw_pointer_); - EXPECT_EQ(2, raw_pointer_->referenceCount); - { - NPObjectPointer p( - NPObjectPointer::FromReturned(raw_pointer_)); - EXPECT_EQ(2, raw_pointer_->referenceCount); - } - EXPECT_EQ(1, raw_pointer_->referenceCount); -} - -TEST_F(NPObjectPointerTest, PointerCanBeConstructedFromReturnedNullNPObject) { - NPObjectPointer p( - NPObjectPointer::FromReturned(NULL)); - EXPECT_TRUE(NULL == p.Get()); -} - -TEST_F(NPObjectPointerTest, PointerCanBeReturnedAsARawNPObject) { - NPObjectPointer p(raw_pointer_); - EXPECT_EQ(raw_pointer_, p.ToReturned()); - - // Check reference count is incremented before return for caller. - EXPECT_EQ(3, raw_pointer_->referenceCount); - - NPBrowser::get()->ReleaseObject(raw_pointer_); -} - -TEST_F(NPObjectPointerTest, NULLPointerCanBeReturnedAsARawNPObject) { - NPObjectPointer p; - EXPECT_TRUE(NULL == p.ToReturned()); -} - -} // namespace gpu_plugin diff --git a/o3d/gpu/np_utils/np_plugin_object.h b/o3d/gpu/np_utils/np_plugin_object.h deleted file mode 100644 index 063079f..0000000 --- a/o3d/gpu/np_utils/np_plugin_object.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2006-2008 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 GPU_NP_UTILS_NP_PLUGIN_OBJECT_H_ -#define GPU_NP_UTILS_NP_PLUGIN_OBJECT_H_ - -#include "gpu/np_utils/np_object_pointer.h" -#include "gpu/np_utils/np_headers.h" - -namespace gpu_plugin { - -// Interface for a plugin instance. The NPP plugin calls forwards to an instance -// of this interface. -class PluginObject { - public: - // Initialize this object. - virtual NPError New(NPMIMEType plugin_type, - int16 argc, - char* argn[], - char* argv[], - NPSavedData* saved) = 0; - - virtual NPError SetWindow(NPWindow* new_window) = 0; - - virtual int16 HandleEvent(NPEvent* event) = 0; - - // Uninitialize but do not deallocate the object. Release will be called to - // deallocate if Destroy succeeds. - virtual NPError Destroy(NPSavedData** saved) = 0; - - // Deallocate this object. This object is invalid after this returns. - virtual void Release() = 0; - - virtual NPObject* GetScriptableNPObject() = 0; - - protected: - PluginObject() { - } - - virtual ~PluginObject() { - } - - private: - DISALLOW_COPY_AND_ASSIGN(PluginObject); -}; - -} // namespace gpu_plugin - -#endif // GPU_NP_UTILS_NP_PLUGIN_OBJECT_H_ diff --git a/o3d/gpu/np_utils/np_plugin_object_factory.cc b/o3d/gpu/np_utils/np_plugin_object_factory.cc deleted file mode 100644 index 831a4bd..0000000 --- a/o3d/gpu/np_utils/np_plugin_object_factory.cc +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include "gpu/gpu_plugin/gpu_plugin_object_factory.h" -#include "base/logging.h" - -namespace gpu_plugin { - -NPPluginObjectFactory* NPPluginObjectFactory::factory_; - -PluginObject* NPPluginObjectFactory::CreatePluginObject( - NPP npp, - NPMIMEType plugin_type) { - return NULL; -} - -NPPluginObjectFactory::NPPluginObjectFactory() { - // Make this the first factory in the linked list. - previous_factory_ = factory_; - factory_ = this; -} - -NPPluginObjectFactory::~NPPluginObjectFactory() { - // Remove this factory from the linked list. - DCHECK(factory_ == this); - factory_ = previous_factory_; -} - -} // namespace gpu_plugin diff --git a/o3d/gpu/np_utils/np_plugin_object_factory.h b/o3d/gpu/np_utils/np_plugin_object_factory.h deleted file mode 100644 index 403d8d5..0000000 --- a/o3d/gpu/np_utils/np_plugin_object_factory.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2006-2008 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 GPU_NP_UTILS_NP_PLUGIN_OBJECT_FACTORY_H_ -#define GPU_NP_UTILS_NP_PLUGIN_OBJECT_FACTORY_H_ - -#include "base/basictypes.h" -#include "gpu/np_utils/np_headers.h" - -namespace gpu_plugin { - -class PluginObject; - -// Mockable factory base class used to create instances of PluginObject based on -// plugin mime type. -class NPPluginObjectFactory { - public: - virtual PluginObject* CreatePluginObject(NPP npp, NPMIMEType plugin_type); - - static NPPluginObjectFactory* get() { - return factory_; - } - - protected: - NPPluginObjectFactory(); - virtual ~NPPluginObjectFactory(); - - private: - static NPPluginObjectFactory* factory_; - NPPluginObjectFactory* previous_factory_; - DISALLOW_COPY_AND_ASSIGN(NPPluginObjectFactory); -}; - -} // namespace gpu_plugin - -#endif // GPU_NP_UTILS_NP_PLUGIN_OBJECT_FACTORY_H_ diff --git a/o3d/gpu/np_utils/np_plugin_object_factory_mock.h b/o3d/gpu/np_utils/np_plugin_object_factory_mock.h deleted file mode 100644 index e15447a..0000000 --- a/o3d/gpu/np_utils/np_plugin_object_factory_mock.h +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2006-2008 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 GPU_NP_UTILS_NP_PLUGIN_OBJECT_FACTORY_MOCK_H_ -#define GPU_NP_UTILS_NP_PLUGIN_OBJECT_FACTORY_MOCK_H_ - -#include "gpu/np_utils/np_plugin_object_factory.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace gpu_plugin { - -// Mockable factory used to create instances of PluginObject based on plugin -// mime type. -class MockPluginObjectFactory : public NPPluginObjectFactory { - public: - MOCK_METHOD2(CreatePluginObject, PluginObject*(NPP, NPMIMEType)); -}; - -} // namespace gpu_plugin - -#endif // GPU_NP_UTILS_NP_PLUGIN_OBJECT_FACTORY_MOCK_H_ diff --git a/o3d/gpu/np_utils/np_plugin_object_mock.h b/o3d/gpu/np_utils/np_plugin_object_mock.h deleted file mode 100644 index e67861b..0000000 --- a/o3d/gpu/np_utils/np_plugin_object_mock.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2006-2008 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 GPU_NP_UTILS_NP_PLUGIN_OBJECT_MOCK_H_ -#define GPU_NP_UTILS_NP_PLUGIN_OBJECT_MOCK_H_ - -#include "gpu/np_utils/np_plugin_object.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace gpu_plugin { - -class MockPluginObject : public PluginObject { - public: - MOCK_METHOD5(New, NPError(NPMIMEType, int16, char*[], char*[], NPSavedData*)); - MOCK_METHOD1(SetWindow, NPError(NPWindow*)); - MOCK_METHOD1(HandleEvent, int16(NPEvent*)); - MOCK_METHOD1(Destroy, NPError(NPSavedData**)); - MOCK_METHOD0(Release, void()); - MOCK_METHOD0(GetScriptableNPObject, NPObject*()); -}; - -} // namespace gpu_plugin - -#endif // GPU_NP_UTILS_NP_PLUGIN_OBJECT_MOCK_H_ diff --git a/o3d/gpu/np_utils/np_utils.cc b/o3d/gpu/np_utils/np_utils.cc deleted file mode 100644 index 03c4a20..0000000 --- a/o3d/gpu/np_utils/np_utils.cc +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include "gpu/np_utils/np_utils.h" - -namespace gpu_plugin { - -bool NPVariantToValue(bool* value, const NPVariant& variant) { - if (NPVARIANT_IS_BOOLEAN(variant)) { - *value = NPVARIANT_TO_BOOLEAN(variant); - return true; - } - - return false; -} - -bool NPVariantToValue(int32* value, const NPVariant& variant) { - if (NPVARIANT_IS_INT32(variant)) { - *value = NPVARIANT_TO_INT32(variant); - return true; - } - - return false; -} - -bool NPVariantToValue(float* value, const NPVariant& variant) { - if (NPVARIANT_IS_DOUBLE(variant)) { - *value = static_cast(NPVARIANT_TO_DOUBLE(variant)); - return true; - } else if (NPVARIANT_IS_INT32(variant)) { - *value = static_cast(NPVARIANT_TO_INT32(variant)); - return true; - } - - return false; -} - -bool NPVariantToValue(double* value, const NPVariant& variant) { - if (NPVARIANT_IS_DOUBLE(variant)) { - *value = NPVARIANT_TO_DOUBLE(variant); - return true; - } else if (NPVARIANT_IS_INT32(variant)) { - *value = NPVARIANT_TO_INT32(variant); - return true; - } - - return false; -} - -bool NPVariantToValue(std::string* value, const NPVariant& variant) { - if (NPVARIANT_IS_STRING(variant)) { - const NPString& str = NPVARIANT_TO_STRING(variant); - *value = std::string(str.UTF8Characters, str.UTF8Length); - return true; - } - - return false; -} - -void ValueToNPVariant(bool value, NPVariant* variant) { - BOOLEAN_TO_NPVARIANT(value, *variant); -} - -void ValueToNPVariant(int32 value, NPVariant* variant) { - INT32_TO_NPVARIANT(value, *variant); -} - -void ValueToNPVariant(float value, NPVariant* variant) { - DOUBLE_TO_NPVARIANT(value, *variant); -} - -void ValueToNPVariant(double value, NPVariant* variant) { - DOUBLE_TO_NPVARIANT(value, *variant); -} - -void ValueToNPVariant(const std::string& value, NPVariant* variant) { - NPUTF8* p = static_cast(NPBrowser::get()->MemAlloc(value.length())); - memcpy(p, value.c_str(), value.length()); - STRINGN_TO_NPVARIANT(p, value.length(), *variant); -} - -SmartNPVariant::SmartNPVariant() { - VOID_TO_NPVARIANT(*this); -} - -SmartNPVariant::SmartNPVariant(const SmartNPVariant& rhs) { - rhs.CopyTo(this); -} - -SmartNPVariant::SmartNPVariant(const NPVariant& rhs) { - static_cast(rhs).CopyTo(this); -} - -SmartNPVariant::~SmartNPVariant() { - Release(); -} - -SmartNPVariant& SmartNPVariant::operator=(const SmartNPVariant& rhs) { - Release(); - rhs.CopyTo(this); - return *this; -} - -SmartNPVariant& SmartNPVariant::operator=(const NPVariant& rhs) { - Release(); - static_cast(rhs).CopyTo(this); - return *this; -} - -bool SmartNPVariant::IsVoid() const { - return NPVARIANT_IS_VOID(*this); -} - -void SmartNPVariant::Release() { - NPBrowser::get()->ReleaseVariantValue(this); - VOID_TO_NPVARIANT(*this); -} - -void SmartNPVariant::Invalidate() { - if (NPVARIANT_IS_OBJECT(*this)) { - NULL_TO_NPVARIANT(*this); - } -} - -void SmartNPVariant::CopyTo(NPVariant* rhs) const { - if (NPVARIANT_IS_OBJECT(*this)) { - NPObject* object = NPVARIANT_TO_OBJECT(*this); - OBJECT_TO_NPVARIANT(object, *rhs); - NPBrowser::get()->RetainObject(object); - } else if (NPVARIANT_IS_STRING(*this)) { - NPUTF8* copy = static_cast(NPBrowser::get()->MemAlloc( - value.stringValue.UTF8Length)); - memcpy(copy, - value.stringValue.UTF8Characters, - value.stringValue.UTF8Length); - STRINGN_TO_NPVARIANT(copy, value.stringValue.UTF8Length, *rhs); - } else { - memcpy(rhs, this, sizeof(*rhs)); - } -} - -bool NPHasMethod(NPP npp, - const NPObjectPointer& object, - const NPUTF8* name) { - return NPBrowser::get()->HasMethod( - npp, - object.Get(), - NPBrowser::get()->GetStringIdentifier(name)); -} - -bool NPHasProperty(NPP npp, - const NPObjectPointer& object, - const NPUTF8* name) { - return NPBrowser::get()->HasProperty( - npp, - object.Get(), - NPBrowser::get()->GetStringIdentifier(name)); -} - -bool NPRemoveProperty(NPP npp, - const NPObjectPointer& object, - const NPUTF8* name) { - return NPBrowser::get()->RemoveProperty( - npp, - object.Get(), - NPBrowser::get()->GetStringIdentifier(name)); -} - -} // namespace gpu_plugin diff --git a/o3d/gpu/np_utils/np_utils.h b/o3d/gpu/np_utils/np_utils.h deleted file mode 100644 index 2ab9384..0000000 --- a/o3d/gpu/np_utils/np_utils.h +++ /dev/null @@ -1,271 +0,0 @@ -// Copyright (c) 2006-2008 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 GPU_NP_UTILS_NP_UTILS_H_ -#define GPU_NP_UTILS_NP_UTILS_H_ - -#include - -#include "gpu/np_utils/np_browser.h" -#include "gpu/np_utils/np_class.h" -#include "gpu/np_utils/np_object_pointer.h" -#include "gpu/np_utils/np_headers.h" - -namespace gpu_plugin { - -// Convert NPVariant to C++ type. Returns whether the conversion was successful. -bool NPVariantToValue(bool* value, const NPVariant& variant); -bool NPVariantToValue(int32* value, const NPVariant& variant); -bool NPVariantToValue(float* value, const NPVariant& variant); -bool NPVariantToValue(double* value, const NPVariant& variant); -bool NPVariantToValue(std::string* value, const NPVariant& variant); - -template -bool NPVariantToValue(NPObjectPointer* value, - const NPVariant& variant) { - if (NPVARIANT_IS_NULL(variant)) { - *value = NPObjectPointer(); - return true; - } else if (NPVARIANT_IS_OBJECT(variant)) { - NPObject* object = NPVARIANT_TO_OBJECT(variant); - if (object->_class == NPGetClass()) { - *value = NPObjectPointer(static_cast( - NPVARIANT_TO_OBJECT(variant))); - return true; - } - } - - return false; -} - -// Specialization for NPObject does not check for mismatched NPClass. -template <> -inline bool NPVariantToValue(NPObjectPointer* value, - const NPVariant& variant) { - if (NPVARIANT_IS_NULL(variant)) { - *value = NPObjectPointer(); - return true; - } else if (NPVARIANT_IS_OBJECT(variant)) { - *value = NPObjectPointer(NPVARIANT_TO_OBJECT(variant)); - return true; - } - - return false; -} - -// Convert C++ type to NPVariant. -void ValueToNPVariant(bool value, NPVariant* variant); -void ValueToNPVariant(int32 value, NPVariant* variant); -void ValueToNPVariant(float value, NPVariant* variant); -void ValueToNPVariant(double value, NPVariant* variant); -void ValueToNPVariant(const std::string& value, NPVariant* variant); - -template -void ValueToNPVariant(const NPObjectPointer& value, - NPVariant* variant) { - if (value.Get()) { - NPBrowser::get()->RetainObject(value.Get()); - OBJECT_TO_NPVARIANT(value.Get(), *variant); - } else { - NULL_TO_NPVARIANT(*variant); - } -} - -// NPVariant that automatically manages lifetime of string and object variants. -class SmartNPVariant : public NPVariant { - public: - SmartNPVariant(); - SmartNPVariant(const SmartNPVariant& rhs); - explicit SmartNPVariant(const NPVariant& rhs); - - template - explicit SmartNPVariant(const T& v) { - ValueToNPVariant(v, this); - } - - ~SmartNPVariant(); - - SmartNPVariant& operator=(const SmartNPVariant& rhs); - SmartNPVariant& operator=(const NPVariant& rhs); - - template - bool GetValue(T* v) const { - return NPVariantToValue(v, *this); - } - - bool IsVoid() const; - - template - void SetValue(const T& v) { - Release(); - ValueToNPVariant(v, this); - } - - void CopyTo(NPVariant* target) const; - - // Sets the variant to void. - void Release(); - - // Called when an NPObject is invalidated to clear any references to other - // NPObjects. Does not release the object as it might no longer be valid. - void Invalidate(); -}; - -// These allow a method to be invoked with automatic conversion of C++ -// types to variants for arguments and return values. - -bool NPHasMethod(NPP npp, - const NPObjectPointer& object, - const NPUTF8* name); - -inline bool NPInvokeVoid(NPP npp, - const NPObjectPointer& object, - const NPUTF8* name) { - SmartNPVariant result; - return NPBrowser::get()->Invoke( - npp, - object.Get(), - NPBrowser::get()->GetStringIdentifier(name), - NULL, 0, - &result); -} - -template -bool NPInvoke(NPP npp, - const NPObjectPointer& object, - const NPUTF8* name, - R* r) { - SmartNPVariant result; - if (NPBrowser::get()->Invoke( - npp, - object.Get(), - NPBrowser::get()->GetStringIdentifier(name), - NULL, 0, - &result)) { - return result.GetValue(r); - } - return false; -} - -template -bool NPInvokeVoid(NPP npp, - const NPObjectPointer& object, - const NPUTF8* name, - P0 p0) { - SmartNPVariant args[1]; - args[0].SetValue(p0); - SmartNPVariant result; - return NPBrowser::get()->Invoke( - npp, - object.Get(), - NPBrowser::get()->GetStringIdentifier(name), - &args[0], 1, - &result); -} - -template -bool NPInvoke(NPP npp, - const NPObjectPointer& object, - const NPUTF8* name, - P0 p0, - R* r) { - SmartNPVariant args[1]; - args[0].SetValue(p0); - SmartNPVariant result; - if (NPBrowser::get()->Invoke( - npp, - object.Get(), - NPBrowser::get()->GetStringIdentifier(name), - &args[0], 1, - &result)) { - return result.GetValue(r); - } - return false; -} - -template -bool NPInvokeVoid(NPP npp, - const NPObjectPointer& object, - const NPUTF8* name, - P0 p0, P1 p1) { - SmartNPVariant args[2]; - args[0].SetValue(p0); - args[1].SetValue(p1); - SmartNPVariant result; - return NPBrowser::get()->Invoke( - npp, - object.Get(), - NPBrowser::get()->GetStringIdentifier(name), - &args[0], 2, - &result); -} - -template -bool NPInvoke(NPP npp, - const NPObjectPointer& object, - const NPUTF8* name, - P0 p0, P1 p1, - R* r) { - SmartNPVariant args[2]; - args[0].SetValue(p0); - args[1].SetValue(p1); - SmartNPVariant result; - if (NPBrowser::get()->Invoke( - npp, - object.Get(), - NPBrowser::get()->GetStringIdentifier(name), - &args[0], 2, - &result)) { - return result.GetValue(r); - } - return false; -} - -bool NPHasProperty(NPP npp, - const NPObjectPointer& object, - const NPUTF8* name); - -template -bool NPGetProperty(NPP npp, - const NPObjectPointer& object, - const NPUTF8* name, - T* value) { - SmartNPVariant result; - if (NPBrowser::get()->GetProperty(npp, - object.Get(), - NPBrowser::get()->GetStringIdentifier(name), - &result)) { - return result.GetValue(value); - } - return false; -} - -template -bool NPSetProperty(NPP npp, - const NPObjectPointer& object, - const NPUTF8* name, - const T& value) { - SmartNPVariant variant(value); - return NPBrowser::get()->SetProperty( - npp, - object.Get(), - NPBrowser::get()->GetStringIdentifier(name), - &variant); -} - -bool NPRemoveProperty(NPP npp, - const NPObjectPointer& object, - const NPUTF8* name); - -template -NPObjectPointer NPCreateObject(NPP npp) { - const NPClass* np_class = NPGetClass(); - NPObjectType* object = static_cast( - NPBrowser::get()->CreateObject(npp, np_class)); - return NPObjectPointer::FromReturned(object); -} - -} // namespace gpu_plugin - -#endif // GPU_NP_UTILS_NP_UTILS_H_ diff --git a/o3d/gpu/np_utils/np_utils_unittest.cc b/o3d/gpu/np_utils/np_utils_unittest.cc deleted file mode 100644 index e481187..0000000 --- a/o3d/gpu/np_utils/np_utils_unittest.cc +++ /dev/null @@ -1,424 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include "gpu/np_utils/np_object_mock.h" -#include "gpu/np_utils/np_browser_stub.h" -#include "gpu/np_utils/np_utils.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using testing::_; -using testing::DoAll; -using testing::MakeMatcher; -using testing::Matcher; -using testing::Pointee; -using testing::Return; -using testing::SetArgumentPointee; -using testing::StrictMock; - -namespace gpu_plugin { - -class NPUtilsTest : public testing::Test { - protected: - StubNPBrowser stub_browser_; - NPP_t npp_; - NPVariant variant_; -}; - -TEST_F(NPUtilsTest, TestBoolNPVariantToValue) { - bool v; - - BOOLEAN_TO_NPVARIANT(false, variant_); - EXPECT_TRUE(NPVariantToValue(&v, variant_)); - EXPECT_FALSE(v); - - BOOLEAN_TO_NPVARIANT(true, variant_); - EXPECT_TRUE(NPVariantToValue(&v, variant_)); - EXPECT_TRUE(v); - - INT32_TO_NPVARIANT(7, variant_); - EXPECT_FALSE(NPVariantToValue(&v, variant_)); -} - -TEST_F(NPUtilsTest, TestIntNPVariantToValue) { - INT32_TO_NPVARIANT(7, variant_); - - int v1; - EXPECT_TRUE(NPVariantToValue(&v1, variant_)); - EXPECT_EQ(7, v1); - - float v2; - EXPECT_TRUE(NPVariantToValue(&v2, variant_)); - EXPECT_EQ(7.0f, v2); - - double v3; - EXPECT_TRUE(NPVariantToValue(&v3, variant_)); - EXPECT_EQ(7.0, v3); - - BOOLEAN_TO_NPVARIANT(false, variant_); - EXPECT_FALSE(NPVariantToValue(&v1, variant_)); -} - -TEST_F(NPUtilsTest, TestFloatNPVariantToValue) { - float v; - - DOUBLE_TO_NPVARIANT(7.0, variant_); - EXPECT_TRUE(NPVariantToValue(&v, variant_)); - EXPECT_EQ(7.0f, v); - - BOOLEAN_TO_NPVARIANT(false, variant_); - EXPECT_FALSE(NPVariantToValue(&v, variant_)); -} - -TEST_F(NPUtilsTest, TestDoubleNPVariantToValue) { - double v; - - DOUBLE_TO_NPVARIANT(7.0, variant_); - EXPECT_TRUE(NPVariantToValue(&v, variant_)); - EXPECT_EQ(7.0, v); - - BOOLEAN_TO_NPVARIANT(false, variant_); - EXPECT_FALSE(NPVariantToValue(&v, variant_)); -} - -TEST_F(NPUtilsTest, TestStringNPVariantToValue) { - std::string v; - - STRINGZ_TO_NPVARIANT("hello", variant_); - EXPECT_TRUE(NPVariantToValue(&v, variant_)); - EXPECT_EQ(std::string("hello"), v); - - BOOLEAN_TO_NPVARIANT(false, variant_); - EXPECT_FALSE(NPVariantToValue(&v, variant_)); -} - -TEST_F(NPUtilsTest, TestObjectNPVariantToValue) { - NPObjectPointer object = - NPCreateObject >(NULL); - NPObjectPointer v; - - OBJECT_TO_NPVARIANT(object.Get(), variant_); - EXPECT_TRUE(NPVariantToValue(&v, variant_)); - EXPECT_EQ(object, v); - - BOOLEAN_TO_NPVARIANT(false, variant_); - EXPECT_FALSE(NPVariantToValue(&v, variant_)); -} - -TEST_F(NPUtilsTest, TestNullNPVariantToValue) { - NPObjectPointer v; - - NULL_TO_NPVARIANT(variant_); - EXPECT_TRUE(NPVariantToValue(&v, variant_)); - EXPECT_TRUE(NPObjectPointer() == v); - - BOOLEAN_TO_NPVARIANT(false, variant_); - EXPECT_FALSE(NPVariantToValue(&v, variant_)); -} - -TEST_F(NPUtilsTest, TestDerivedObjectNPVariantToValue) { - NPObjectPointer object = - NPCreateObject >(NULL); - NPObjectPointer > v; - - OBJECT_TO_NPVARIANT(object.Get(), variant_); - EXPECT_TRUE(NPVariantToValue(&v, variant_)); - EXPECT_EQ(object, v); -} - -TEST_F(NPUtilsTest, - TestDerivedObjectNPVariantToValueFailsIfValueHasDifferentType) { - NPObjectPointer object = - NPCreateObject >(NULL); - NPObjectPointer v; - - OBJECT_TO_NPVARIANT(object.Get(), variant_); - EXPECT_FALSE(NPVariantToValue(&v, variant_)); -} - -TEST_F(NPUtilsTest, TestBoolValueToNPVariant) { - ValueToNPVariant(true, &variant_); - EXPECT_TRUE(NPVARIANT_IS_BOOLEAN(variant_)); - EXPECT_TRUE(NPVARIANT_TO_BOOLEAN(variant_)); - - ValueToNPVariant(false, &variant_); - EXPECT_TRUE(NPVARIANT_IS_BOOLEAN(variant_)); - EXPECT_FALSE(NPVARIANT_TO_BOOLEAN(variant_)); -} - -TEST_F(NPUtilsTest, TestIntValueToNPVariant) { - ValueToNPVariant(7, &variant_); - EXPECT_TRUE(NPVARIANT_IS_INT32(variant_)); - EXPECT_EQ(7, NPVARIANT_TO_INT32(variant_)); -} - -TEST_F(NPUtilsTest, TestFloatValueToNPVariant) { - ValueToNPVariant(7.0f, &variant_); - EXPECT_TRUE(NPVARIANT_IS_DOUBLE(variant_)); - EXPECT_EQ(7.0, NPVARIANT_TO_DOUBLE(variant_)); -} - -TEST_F(NPUtilsTest, TestDoubleValueToNPVariant) { - ValueToNPVariant(7.0, &variant_); - EXPECT_TRUE(NPVARIANT_IS_DOUBLE(variant_)); - EXPECT_EQ(7.0, NPVARIANT_TO_DOUBLE(variant_)); -} - -TEST_F(NPUtilsTest, TestStringValueToNPVariant) { - ValueToNPVariant(std::string("hello"), &variant_); - EXPECT_TRUE(NPVARIANT_IS_STRING(variant_)); - EXPECT_EQ(std::string("hello"), - std::string(variant_.value.stringValue.UTF8Characters, - variant_.value.stringValue.UTF8Length)); -} - -TEST_F(NPUtilsTest, TestObjectValueToNPVariant) { - NPObjectPointer object = - NPCreateObject >(NULL); - - ValueToNPVariant(object, &variant_); - EXPECT_TRUE(NPVARIANT_IS_OBJECT(variant_)); - EXPECT_EQ(object.Get(), NPVARIANT_TO_OBJECT(variant_)); - - NPBrowser::get()->ReleaseVariantValue(&variant_); -} - -TEST_F(NPUtilsTest, TestNullValueToNPVariant) { - ValueToNPVariant(NPObjectPointer(), &variant_); - EXPECT_TRUE(NPVARIANT_IS_NULL(variant_)); -} - -TEST_F(NPUtilsTest, CanCopyObjectSmartVariant) { - NPObjectPointer object = - NPCreateObject >(NULL); - EXPECT_EQ(1, object->referenceCount); - { - SmartNPVariant v1(object); - EXPECT_EQ(2, object->referenceCount); - { - SmartNPVariant v2(v1); - EXPECT_EQ(3, object->referenceCount); - } - EXPECT_EQ(2, object->referenceCount); - } - EXPECT_EQ(1, object->referenceCount); -} - -TEST_F(NPUtilsTest, CanCopyStringSmartVariant) { - SmartNPVariant v1(std::string("hello")); - SmartNPVariant v2(v1); - std::string r; - EXPECT_TRUE(NPVariantToValue(&r, v2)); - EXPECT_EQ(std::string("hello"), r); - EXPECT_NE(v1.value.stringValue.UTF8Characters, - v2.value.stringValue.UTF8Characters); -} - -TEST_F(NPUtilsTest, CanReleaseSmartVariant) { - SmartNPVariant variant(std::string("hello")); - EXPECT_FALSE(variant.IsVoid()); - variant.Release(); - EXPECT_TRUE(variant.IsVoid()); -} - -template -class VariantMatcher : public testing::MatcherInterface { - public: - explicit VariantMatcher(const T& value) : value_(value) { - } - - virtual bool Matches(const NPVariant& variant) const { - T other_value; - return NPVariantToValue(&other_value, variant) && other_value == value_; - } - - virtual void DescribeTo(::std::ostream* os) const { - *os << "equals " << value_; - } - - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "does not equal " << value_; - } - - private: - T value_; -}; - -template -Matcher VariantMatches(const T& value) { - return MakeMatcher(new VariantMatcher(value)); -} - -TEST_F(NPUtilsTest, CanDetermineIfObjectHasMethod) { - NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); - NPObjectPointer object = - NPCreateObject >(NULL); - - EXPECT_CALL(*object, HasMethod(name)) - .WillOnce(Return(true)); - - EXPECT_TRUE(NPHasMethod(NULL, object, "foo")); -} - -TEST_F(NPUtilsTest, CanInvokeVoidMethodWithNativeTypes) { - NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); - NPObjectPointer object = - NPCreateObject >(NULL); - - VOID_TO_NPVARIANT(variant_); - - EXPECT_CALL(*object, Invoke(name, Pointee(VariantMatches(7)), 1, _)) - .WillOnce(DoAll(SetArgumentPointee<3>(variant_), - Return(true))); - - EXPECT_TRUE(NPInvokeVoid(NULL, object, "foo", 7)); -} - -TEST_F(NPUtilsTest, InvokeVoidMethodCanFail) { - NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); - NPObjectPointer object = - NPCreateObject >(NULL); - - VOID_TO_NPVARIANT(variant_); - - EXPECT_CALL(*object, Invoke(name, Pointee(VariantMatches(7)), 1, _)) - .WillOnce(DoAll(SetArgumentPointee<3>(variant_), - Return(false))); - - EXPECT_FALSE(NPInvokeVoid(NULL, object, "foo", 7)); -} - -TEST_F(NPUtilsTest, CanInvokeNonVoidMethodWithNativeTypes) { - NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); - NPObjectPointer object = - NPCreateObject >(NULL); - - DOUBLE_TO_NPVARIANT(1.5, variant_); - - EXPECT_CALL(*object, Invoke(name, Pointee(VariantMatches(7)), 1, _)) - .WillOnce(DoAll(SetArgumentPointee<3>(variant_), - Return(true))); - - double r; - EXPECT_TRUE(NPInvoke(NULL, object, "foo", 7, &r)); - EXPECT_EQ(1.5, r); -} - -TEST_F(NPUtilsTest, InvokeNonVoidMethodCanFail) { - NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); - NPObjectPointer object = - NPCreateObject >(NULL); - - DOUBLE_TO_NPVARIANT(1.5, variant_); - - EXPECT_CALL(*object, Invoke(name, Pointee(VariantMatches(7)), 1, _)) - .WillOnce(DoAll(SetArgumentPointee<3>(variant_), - Return(false))); - - double r; - EXPECT_FALSE(NPInvoke(NULL, object, "foo", 7, &r)); -} - -TEST_F(NPUtilsTest, InvokeNonVoidMethodFailsIfResultIsIncompatible) { - NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); - NPObjectPointer object = - NPCreateObject >(NULL); - - DOUBLE_TO_NPVARIANT(1.5, variant_); - - EXPECT_CALL(*object, Invoke(name, Pointee(VariantMatches(7)), 1, _)) - .WillOnce(DoAll(SetArgumentPointee<3>(variant_), - Return(true))); - - int r; - EXPECT_FALSE(NPInvoke(NULL, object, "foo", 7, &r)); -} - -TEST_F(NPUtilsTest, CanDetermineIfObjectHasProperty) { - NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); - NPObjectPointer object = - NPCreateObject >(NULL); - - EXPECT_CALL(*object, HasProperty(name)) - .WillOnce(Return(true)); - - EXPECT_TRUE(NPHasProperty(NULL, object, "foo")); -} - -TEST_F(NPUtilsTest, CanGetPropertyValue) { - NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); - NPObjectPointer object = - NPCreateObject >(NULL); - - DOUBLE_TO_NPVARIANT(1.5, variant_); - - EXPECT_CALL(*object, GetProperty(name, _)) - .WillOnce(DoAll(SetArgumentPointee<1>(variant_), - Return(true))); - - double r; - EXPECT_TRUE(NPGetProperty(NULL, object, "foo", &r)); -} - -TEST_F(NPUtilsTest, NPGetPropertyReportsFailureIfResultTypeIsDifferent) { - NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); - NPObjectPointer object = - NPCreateObject >(NULL); - - DOUBLE_TO_NPVARIANT(1.5, variant_); - - EXPECT_CALL(*object, GetProperty(name, _)) - .WillOnce(DoAll(SetArgumentPointee<1>(variant_), - Return(true))); - - bool r; - EXPECT_FALSE(NPGetProperty(NULL, object, "foo", &r)); -} - -TEST_F(NPUtilsTest, NPGetPropertyReportsFailureFromGetProperty) { - NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); - NPObjectPointer object = - NPCreateObject >(NULL); - - EXPECT_CALL(*object, GetProperty(name, _)) - .WillOnce(Return(false)); - - double r; - EXPECT_FALSE(NPGetProperty(NULL, object, "foo", &r)); -} - -TEST_F(NPUtilsTest, CanSetPropertyValue) { - NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); - NPObjectPointer object = - NPCreateObject >(NULL); - - EXPECT_CALL(*object, SetProperty(name, Pointee(VariantMatches(1.5)))) - .WillOnce(Return(true)); - - EXPECT_TRUE(NPSetProperty(NULL, object, "foo", 1.5)); -} - -TEST_F(NPUtilsTest, NPSetPropertyReportsFailureFromSetProperty) { - NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); - NPObjectPointer object = - NPCreateObject >(NULL); - - EXPECT_CALL(*object, SetProperty(name, Pointee(VariantMatches(1.5)))) - .WillOnce(Return(false)); - - EXPECT_FALSE(NPSetProperty(NULL, object, "foo", 1.5)); -} - -TEST_F(NPUtilsTest, CanRemovePropertyValue) { - NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); - NPObjectPointer object = - NPCreateObject >(NULL); - - EXPECT_CALL(*object, RemoveProperty(name)) - .WillOnce(Return(true)); - - EXPECT_TRUE(NPRemoveProperty(NULL, object, "foo")); -} - -} // namespace gpu_plugin diff --git a/o3d/gpu/np_utils/webkit_browser.h b/o3d/gpu/np_utils/webkit_browser.h deleted file mode 100644 index 8afc167..0000000 --- a/o3d/gpu/np_utils/webkit_browser.h +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) 2006-2008 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 GPU_NP_UTILS_WEBKIT_BROWSER_H_ -#define GPU_NP_UTILS_WEBKIT_BROWSER_H_ - -// TODO(apatrick): This does not belong in np_utils. np_utils should not be -// dependent on WebKit (and it isn't - that's why the member functions are -// inline). - -#include - -#include "gpu/np_utils/np_browser.h" -#include "WebKit/api/public/WebBindings.h" - -typedef struct _NPNetscapeFuncs NPNetscapeFuncs; -typedef struct _NPChromiumFuncs NPChromiumFuncs; - -namespace gpu_plugin { - -// This class implements NPBrowser for the WebKit WebBindings. -class WebKitBrowser : public NPBrowser { - public: - WebKitBrowser(): NPBrowser(NULL) { - } - - // Standard functions from NPNetscapeFuncs. - - virtual NPIdentifier GetStringIdentifier(const NPUTF8* name) { - return WebKit::WebBindings::getStringIdentifier(name); - } - - virtual void* MemAlloc(size_t size) { - return malloc(size); - } - - virtual void MemFree(void* p) { - free(p); - } - - virtual NPObject* CreateObject(NPP npp, const NPClass* cl) { - return WebKit::WebBindings::createObject(npp, const_cast(cl)); - } - - virtual NPObject* RetainObject(NPObject* object) { - return WebKit::WebBindings::retainObject(object); - } - - virtual void ReleaseObject(NPObject* object) { - WebKit::WebBindings::releaseObject(object); - } - - virtual void ReleaseVariantValue(NPVariant* variant) { - WebKit::WebBindings::releaseVariantValue(variant); - } - - virtual bool HasProperty(NPP npp, - NPObject* object, - NPIdentifier name) { - return WebKit::WebBindings::hasProperty(npp, object, name); - } - - virtual bool GetProperty(NPP npp, - NPObject* object, - NPIdentifier name, - NPVariant* result) { - return WebKit::WebBindings::getProperty(npp, object, name, result); - } - - virtual bool SetProperty(NPP npp, - NPObject* object, - NPIdentifier name, - const NPVariant* result) { - return WebKit::WebBindings::setProperty(npp, object, name, result); - } - - virtual bool RemoveProperty(NPP npp, - NPObject* object, - NPIdentifier name) { - return WebKit::WebBindings::removeProperty(npp, object, name); - } - - virtual bool HasMethod(NPP npp, - NPObject* object, - NPIdentifier name) { - return WebKit::WebBindings::hasMethod(npp, object, name); - } - - virtual bool Invoke(NPP npp, - NPObject* object, - NPIdentifier name, - const NPVariant* args, - uint32_t num_args, - NPVariant* result) { - return WebKit::WebBindings::invoke(npp, object, name, args, num_args, - result); - } - - virtual NPObject* GetWindowNPObject(NPP npp) { - NPObject* window; - if (NPERR_NO_ERROR == NPN_GetValue(npp, - NPNVWindowNPObject, - &window)) { - return window; - } else { - return NULL; - } - } - - private: - DISALLOW_COPY_AND_ASSIGN(WebKitBrowser); -}; - -} // namespace gpu_plugin - -#endif // GPU_NP_UTILS_WEBKIT_BROWSER_H_ diff --git a/o3d/gpu_plugin/command_buffer.cc b/o3d/gpu_plugin/command_buffer.cc new file mode 100644 index 0000000..15f52da --- /dev/null +++ b/o3d/gpu_plugin/command_buffer.cc @@ -0,0 +1,143 @@ +// Copyright (c) 2006-2008 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. + +#include "o3d/gpu_plugin/command_buffer.h" + +using ::base::SharedMemory; + +namespace gpu_plugin { + +CommandBuffer::CommandBuffer(NPP npp) + : npp_(npp), + size_(0), + get_offset_(0), + put_offset_(0), + token_(0), + parse_error_(0), + error_status_(false) { + // Element zero is always NULL. + registered_objects_.push_back(linked_ptr()); +} + +CommandBuffer::~CommandBuffer() { +} + +bool CommandBuffer::Initialize(::base::SharedMemory* ring_buffer) { + DCHECK(ring_buffer); + + // Fail if already initialized. + if (ring_buffer_.get()) + return false; + + size_t size_in_bytes = ring_buffer->max_size(); + size_ = size_in_bytes / sizeof(int32); + ring_buffer_.reset(ring_buffer); + + return true; +} + +SharedMemory* CommandBuffer::GetRingBuffer() { + return ring_buffer_.get(); +} + +int32 CommandBuffer::GetSize() { + return size_; +} + +int32 CommandBuffer::SyncOffsets(int32 put_offset) { + if (put_offset < 0 || put_offset >= size_) + return -1; + + put_offset_ = put_offset; + + if (put_offset_change_callback_.get()) { + put_offset_change_callback_->Run(); + } + + return get_offset_; +} + +int32 CommandBuffer::GetGetOffset() { + return get_offset_; +} + +void CommandBuffer::SetGetOffset(int32 get_offset) { + DCHECK(get_offset >= 0 && get_offset < size_); + get_offset_ = get_offset; +} + +int32 CommandBuffer::GetPutOffset() { + return put_offset_; +} + +void CommandBuffer::SetPutOffsetChangeCallback(Callback0::Type* callback) { + put_offset_change_callback_.reset(callback); +} + +int32 CommandBuffer::CreateTransferBuffer(size_t size) { + linked_ptr buffer(new SharedMemory); + if (!buffer->Create(std::wstring(), false, false, size)) + return -1; + + if (unused_registered_object_elements_.empty()) { + // Check we haven't exceeded the range that fits in a 32-bit integer. + int32 handle = static_cast(registered_objects_.size()); + if (handle != registered_objects_.size()) + return -1; + + registered_objects_.push_back(buffer); + return handle; + } + + int32 handle = *unused_registered_object_elements_.begin(); + unused_registered_object_elements_.erase( + unused_registered_object_elements_.begin()); + DCHECK(!registered_objects_[handle].get()); + registered_objects_[handle] = buffer; + return handle; +} + +void CommandBuffer::DestroyTransferBuffer(int32 handle) { + if (handle <= 0) + return; + + if (static_cast(handle) >= registered_objects_.size()) + return; + + registered_objects_[handle].reset(); + unused_registered_object_elements_.insert(handle); + + // Remove all null objects from the end of the vector. This allows the vector + // to shrink when, for example, all objects are unregistered. Note that this + // loop never removes element zero, which is always NULL. + while (registered_objects_.size() > 1 && !registered_objects_.back().get()) { + registered_objects_.pop_back(); + unused_registered_object_elements_.erase( + static_cast(registered_objects_.size())); + } +} + +::base::SharedMemory* CommandBuffer::GetTransferBuffer(int32 handle) { + if (handle < 0) + return NULL; + + if (static_cast(handle) >= registered_objects_.size()) + return NULL; + + return registered_objects_[handle].get(); +} + +int32 CommandBuffer::ResetParseError() { + int32 last_error = parse_error_; + parse_error_ = 0; + return last_error; +} + +void CommandBuffer::SetParseError(int32 parse_error) { + if (parse_error_ == 0) { + parse_error_ = parse_error; + } +} + +} // namespace gpu_plugin diff --git a/o3d/gpu_plugin/command_buffer.h b/o3d/gpu_plugin/command_buffer.h new file mode 100644 index 0000000..84457c0 --- /dev/null +++ b/o3d/gpu_plugin/command_buffer.h @@ -0,0 +1,130 @@ +// Copyright (c) 2006-2008 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 O3D_GPU_PLUGIN_COMMAND_BUFFER_H_ +#define O3D_GPU_PLUGIN_COMMAND_BUFFER_H_ + +#include +#include + +#include "base/linked_ptr.h" +#include "base/scoped_ptr.h" +#include "base/shared_memory.h" +#include "base/task.h" +#include "o3d/gpu_plugin/np_utils/default_np_object.h" +#include "o3d/gpu_plugin/np_utils/np_dispatcher.h" + +namespace gpu_plugin { + +// An NPObject that implements a shared memory command buffer and a synchronous +// API to manage the put and get pointers. +class CommandBuffer : public DefaultNPObject { + public: + explicit CommandBuffer(NPP npp); + virtual ~CommandBuffer(); + + // Initialize the command buffer with the given ring buffer. Takes ownership + // of ring buffer. + virtual bool Initialize(::base::SharedMemory* ring_buffer); + + // Gets the shared memory ring buffer object for the command buffer. + virtual ::base::SharedMemory* GetRingBuffer(); + + virtual int32 GetSize(); + + // The writer calls this to update its put offset. This function returns the + // reader's most recent get offset. Does not return until after the put offset + // change callback has been invoked. Returns -1 if the put offset is invalid. + virtual int32 SyncOffsets(int32 put_offset); + + // Returns the current get offset. This can be called from any thread. + virtual int32 GetGetOffset(); + + // Sets the current get offset. This can be called from any thread. + virtual void SetGetOffset(int32 get_offset); + + // Returns the current put offset. This can be called from any thread. + virtual int32 GetPutOffset(); + + // Sets a callback that should be posted on another thread whenever the put + // offset is changed. The callback must not return until some progress has + // been made (unless the command buffer is empty), i.e. the + // get offset must have changed. It need not process the entire command + // buffer though. This allows concurrency between the writer and the reader + // while giving the writer a means of waiting for the reader to make some + // progress before attempting to write more to the command buffer. Avoiding + // the use of a synchronization primitive like a condition variable to + // synchronize reader and writer reduces the risk of deadlock. + // Takes ownership of callback. The callback is invoked on the plugin thread. + virtual void SetPutOffsetChangeCallback(Callback0::Type* callback); + + // Create a shared memory transfer buffer and return a handle that uniquely + // identifies it or -1 on error. + virtual int32 CreateTransferBuffer(size_t size); + + // Destroy a shared memory transfer buffer and recycle the handle. + virtual void DestroyTransferBuffer(int32 id); + + // Get the shared memory associated with a handle. + virtual ::base::SharedMemory* GetTransferBuffer(int32 handle); + + // Get the current token value. This is used for by the writer to defer + // changes to shared memory objects until the reader has reached a certain + // point in the command buffer. The reader is responsible for updating the + // token value, for example in response to an asynchronous set token command + // embedded in the command buffer. The default token value is zero. + int32 GetToken() { + return token_; + } + + // Allows the reader to update the current token value. + void SetToken(int32 token) { + token_ = token; + } + + // Get the current parse error and reset it to zero. Zero means no error. Non- + // zero means error. The default error status is zero. + int32 ResetParseError(); + + // Allows the reader to set the current parse error. + void SetParseError(int32 parse_error); + + // Returns whether the command buffer is in the error state. + bool GetErrorStatus() { + return error_status_; + } + + // Allows the reader to set the error status. Once in an error state, the + // command buffer cannot recover and ceases to process commands. + void RaiseErrorStatus() { + error_status_ = true; + } + + NP_UTILS_BEGIN_DISPATCHER_CHAIN(CommandBuffer, DefaultNPObject) + NP_UTILS_DISPATCHER(GetSize, int32()) + NP_UTILS_DISPATCHER(SyncOffsets, int32(int32 get_offset)) + NP_UTILS_DISPATCHER(GetGetOffset, int32()); + NP_UTILS_DISPATCHER(GetPutOffset, int32()); + NP_UTILS_DISPATCHER(GetToken, int32()); + NP_UTILS_DISPATCHER(ResetParseError, int32()); + NP_UTILS_DISPATCHER(GetErrorStatus, bool()); + NP_UTILS_END_DISPATCHER_CHAIN + + private: + NPP npp_; + scoped_ptr< ::base::SharedMemory> ring_buffer_; + int32 size_; + int32 get_offset_; + int32 put_offset_; + scoped_ptr put_offset_change_callback_; + std::vector > registered_objects_; + std::set unused_registered_object_elements_; + int32 token_; + int32 parse_error_; + bool error_status_; +}; + +} // namespace gpu_plugin + +#endif // O3D_GPU_PLUGIN_COMMAND_BUFFER_H_ diff --git a/o3d/gpu_plugin/command_buffer_mock.h b/o3d/gpu_plugin/command_buffer_mock.h new file mode 100644 index 0000000..ab82bdb --- /dev/null +++ b/o3d/gpu_plugin/command_buffer_mock.h @@ -0,0 +1,42 @@ +// Copyright (c) 2006-2008 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 O3D_GPU_PLUGIN_COMMAND_BUFFER_MOCK_H_ +#define O3D_GPU_PLUGIN_COMMAND_BUFFER_MOCK_H_ + +#include "o3d/gpu_plugin/command_buffer.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace gpu_plugin { + +// An NPObject that implements a shared memory command buffer and a synchronous +// API to manage the put and get pointers. +class MockCommandBuffer : public CommandBuffer { + public: + explicit MockCommandBuffer(NPP npp) : CommandBuffer(npp) { + ON_CALL(*this, GetRingBuffer()) + .WillByDefault(testing::Return(static_cast<::base::SharedMemory*>(NULL))); + ON_CALL(*this, GetTransferBuffer(testing::_)) + .WillByDefault(testing::Return(static_cast<::base::SharedMemory*>(NULL))); + } + + MOCK_METHOD1(Initialize, bool(::base::SharedMemory* ring_buffer)); + MOCK_METHOD0(GetRingBuffer, ::base::SharedMemory*()); + MOCK_METHOD0(GetSize, int32()); + MOCK_METHOD1(SyncOffsets, int32(int32 put_offset)); + MOCK_METHOD0(GetGetOffset, int32()); + MOCK_METHOD1(SetGetOffset, void(int32 get_offset)); + MOCK_METHOD0(GetPutOffset, int32()); + MOCK_METHOD1(SetPutOffsetChangeCallback, void(Callback0::Type* callback)); + MOCK_METHOD1(CreateTransferBuffer, int32(size_t size)); + MOCK_METHOD1(DestroyTransferBuffer, void(int32 handle)); + MOCK_METHOD1(GetTransferBuffer, ::base::SharedMemory*(int32 handle)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockCommandBuffer); +}; + +} // namespace gpu_plugin + +#endif // O3D_GPU_PLUGIN_COMMAND_BUFFER_MOCK_H_ diff --git a/o3d/gpu_plugin/command_buffer_unittest.cc b/o3d/gpu_plugin/command_buffer_unittest.cc new file mode 100644 index 0000000..5041d48 --- /dev/null +++ b/o3d/gpu_plugin/command_buffer_unittest.cc @@ -0,0 +1,182 @@ +// Copyright (c) 2006-2008 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. + +#include "base/thread.h" +#include "o3d/gpu_plugin/command_buffer.h" +#include "o3d/gpu_plugin/np_utils/np_browser_mock.h" +#include "o3d/gpu_plugin/np_utils/dynamic_np_object.h" +#include "o3d/gpu_plugin/np_utils/np_object_mock.h" +#include "o3d/gpu_plugin/np_utils/np_object_pointer.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/gmock/include/gmock/gmock.h" + +using base::SharedMemory; +using testing::_; +using testing::DoAll; +using testing::Return; +using testing::SetArgumentPointee; +using testing::StrictMock; + +namespace gpu_plugin { + +class CommandBufferTest : public testing::Test { + protected: + virtual void SetUp() { + command_buffer_ = NPCreateObject(NULL); + } + + MockNPBrowser mock_browser_; + NPObjectPointer command_buffer_; +}; + +TEST_F(CommandBufferTest, NullRingBufferByDefault) { + EXPECT_TRUE(NULL == command_buffer_->GetRingBuffer()); +} + +TEST_F(CommandBufferTest, InitializesCommandBuffer) { + SharedMemory* ring_buffer = new SharedMemory; + EXPECT_TRUE(ring_buffer->Create(std::wstring(), false, false, 1024)); + EXPECT_TRUE(command_buffer_->Initialize(ring_buffer)); + EXPECT_TRUE(ring_buffer == command_buffer_->GetRingBuffer()); + EXPECT_EQ(256, command_buffer_->GetSize()); +} + +TEST_F(CommandBufferTest, InitializeFailsSecondTime) { + SharedMemory* ring_buffer = new SharedMemory; + EXPECT_TRUE(command_buffer_->Initialize(ring_buffer)); + EXPECT_FALSE(command_buffer_->Initialize(ring_buffer)); +} + +TEST_F(CommandBufferTest, GetAndPutOffsetsDefaultToZero) { + EXPECT_EQ(0, command_buffer_->GetGetOffset()); + EXPECT_EQ(0, command_buffer_->GetPutOffset()); +} + +class MockCallback : public CallbackRunner { + public: + MOCK_METHOD1(RunWithParams, void(const Tuple0&)); +}; + +TEST_F(CommandBufferTest, CanSyncGetAndPutOffset) { + SharedMemory* ring_buffer = new SharedMemory; + ring_buffer->Create(std::wstring(), false, false, 1024); + + EXPECT_TRUE(command_buffer_->Initialize(ring_buffer)); + + StrictMock* put_offset_change_callback = + new StrictMock; + command_buffer_->SetPutOffsetChangeCallback(put_offset_change_callback); + + EXPECT_CALL(*put_offset_change_callback, RunWithParams(_)); + EXPECT_EQ(0, command_buffer_->SyncOffsets(2)); + EXPECT_EQ(2, command_buffer_->GetPutOffset()); + + EXPECT_CALL(*put_offset_change_callback, RunWithParams(_)); + EXPECT_EQ(0, command_buffer_->SyncOffsets(4)); + EXPECT_EQ(4, command_buffer_->GetPutOffset()); + + command_buffer_->SetGetOffset(2); + EXPECT_EQ(2, command_buffer_->GetGetOffset()); + EXPECT_CALL(*put_offset_change_callback, RunWithParams(_)); + EXPECT_EQ(2, command_buffer_->SyncOffsets(6)); + + EXPECT_EQ(-1, command_buffer_->SyncOffsets(-1)); + EXPECT_EQ(-1, command_buffer_->SyncOffsets(1024)); +} + +TEST_F(CommandBufferTest, ZeroHandleMapsToNull) { + EXPECT_TRUE(NULL == command_buffer_->GetTransferBuffer(0)); +} + +TEST_F(CommandBufferTest, NegativeHandleMapsToNull) { + EXPECT_TRUE(NULL == command_buffer_->GetTransferBuffer(-1)); +} + +TEST_F(CommandBufferTest, OutOfRangeHandleMapsToNull) { + EXPECT_TRUE(NULL == command_buffer_->GetTransferBuffer(1)); +} + +TEST_F(CommandBufferTest, CanCreateTransferBuffers) { + int32 handle = command_buffer_->CreateTransferBuffer(1024); + EXPECT_EQ(1, handle); + SharedMemory* buffer = command_buffer_->GetTransferBuffer(handle); + ASSERT_TRUE(NULL != buffer); + EXPECT_EQ(1024, buffer->max_size()); +} + +TEST_F(CommandBufferTest, CreateTransferBufferReturnsDistinctHandles) { + EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); +} + +TEST_F(CommandBufferTest, CreateTransferBufferReusesUnregisteredHandles) { + EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); + EXPECT_EQ(2, command_buffer_->CreateTransferBuffer(1024)); + command_buffer_->DestroyTransferBuffer(1); + EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); + EXPECT_EQ(3, command_buffer_->CreateTransferBuffer(1024)); +} + +TEST_F(CommandBufferTest, CannotUnregisterHandleZero) { + command_buffer_->DestroyTransferBuffer(0); + EXPECT_TRUE(NULL == command_buffer_->GetTransferBuffer(0)); + EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); +} + +TEST_F(CommandBufferTest, CannotUnregisterNegativeHandles) { + command_buffer_->DestroyTransferBuffer(-1); + EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); +} + +TEST_F(CommandBufferTest, CannotUnregisterUnregisteredHandles) { + command_buffer_->DestroyTransferBuffer(1); + EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); +} + +// Testing this case specifically because there is an optimization that takes +// a different code path in this case. +TEST_F(CommandBufferTest, UnregistersLastRegisteredHandle) { + EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); + command_buffer_->DestroyTransferBuffer(1); + EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); +} + +// Testing this case specifically because there is an optimization that takes +// a different code path in this case. +TEST_F(CommandBufferTest, UnregistersTwoLastRegisteredHandles) { + EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); + EXPECT_EQ(2, command_buffer_->CreateTransferBuffer(1024)); + command_buffer_->DestroyTransferBuffer(2); + command_buffer_->DestroyTransferBuffer(1); + EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); +} + +TEST_F(CommandBufferTest, DefaultTokenIsZero) { + EXPECT_EQ(0, command_buffer_->GetToken()); +} + +TEST_F(CommandBufferTest, CanSetToken) { + command_buffer_->SetToken(7); + EXPECT_EQ(7, command_buffer_->GetToken()); +} + +TEST_F(CommandBufferTest, DefaultParseErrorIsNoError) { + EXPECT_EQ(0, command_buffer_->ResetParseError()); +} + +TEST_F(CommandBufferTest, CanSetAndResetParseError) { + command_buffer_->SetParseError(1); + EXPECT_EQ(1, command_buffer_->ResetParseError()); + EXPECT_EQ(0, command_buffer_->ResetParseError()); +} + +TEST_F(CommandBufferTest, DefaultErrorStatusIsFalse) { + EXPECT_FALSE(command_buffer_->GetErrorStatus()); +} + +TEST_F(CommandBufferTest, CanRaiseErrorStatus) { + command_buffer_->RaiseErrorStatus(); + EXPECT_TRUE(command_buffer_->GetErrorStatus()); +} + +} // namespace gpu_plugin diff --git a/o3d/gpu_plugin/gpu_plugin.cc b/o3d/gpu_plugin/gpu_plugin.cc new file mode 100644 index 0000000..fa270f7 --- /dev/null +++ b/o3d/gpu_plugin/gpu_plugin.cc @@ -0,0 +1,136 @@ +// Copyright (c) 2006-2008 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. + +#include "o3d/gpu_plugin/gpu_plugin.h" +#include "o3d/gpu_plugin/gpu_plugin_object_factory.h" +#include "o3d/gpu_plugin/np_utils/np_browser.h" +#include "o3d/gpu_plugin/np_utils/np_plugin_object.h" +#include "o3d/gpu_plugin/np_utils/np_plugin_object_factory.h" + +#if defined(O3D_IN_CHROME) +#include "webkit/glue/plugins/nphostapi.h" +#else +#include "o3d/third_party/npapi/include/npfunctions.h" +#endif + +namespace gpu_plugin { + +// Definitions of NPAPI plugin entry points. + +namespace { +NPBrowser* g_browser; +GPUPluginObjectFactory g_plugin_object_factory; + +NPError NPP_New(NPMIMEType plugin_type, NPP instance, + uint16 mode, int16 argc, char* argn[], + char* argv[], NPSavedData* saved) { + if (!instance) + return NPERR_INVALID_INSTANCE_ERROR; + + PluginObject* plugin_object = + NPPluginObjectFactory::get()->CreatePluginObject(instance, plugin_type); + if (!plugin_object) + return NPERR_GENERIC_ERROR; + + instance->pdata = plugin_object; + + NPError error = plugin_object->New(plugin_type, argc, argn, argv, saved); + if (error != NPERR_NO_ERROR) { + plugin_object->Release(); + } + + return error; +} + +NPError NPP_Destroy(NPP instance, NPSavedData** saved) { + if (!instance) + return NPERR_INVALID_INSTANCE_ERROR; + + PluginObject* plugin_object = static_cast(instance->pdata); + NPError error = plugin_object->Destroy(saved); + + if (error == NPERR_NO_ERROR) { + plugin_object->Release(); + } + + return error; +} + +NPError NPP_SetWindow(NPP instance, NPWindow* window) { + if (!instance) + return NPERR_INVALID_INSTANCE_ERROR; + + PluginObject* plugin_object = static_cast(instance->pdata); + return plugin_object->SetWindow(window); +} + +int16 NPP_HandleEvent(NPP instance, void* event) { + if (!instance) + return 0; + + PluginObject* plugin_object = static_cast(instance->pdata); + return plugin_object->HandleEvent(static_cast(event)); +} + +NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value) { + if (!instance) + return NPERR_INVALID_INSTANCE_ERROR; + + PluginObject* plugin_object = static_cast(instance->pdata); + switch (variable) { + case NPPVpluginScriptableNPObject: + *reinterpret_cast(value) = + plugin_object->GetScriptableNPObject(); + return NPERR_NO_ERROR; + default: + return NPERR_GENERIC_ERROR; + } +} + +NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value) { + return NPERR_NO_ERROR; +} +} + +NPError NP_GetEntryPoints(NPPluginFuncs* funcs) { + funcs->newp = NPP_New; + funcs->destroy = NPP_Destroy; + funcs->setwindow = NPP_SetWindow; + funcs->event = NPP_HandleEvent; + funcs->getvalue = NPP_GetValue; + funcs->setvalue = NPP_SetValue; + return NPERR_NO_ERROR; +} + +#if defined(OS_LINUX) +NPError API_CALL NP_Initialize(NPNetscapeFuncs *browser_funcs, + NPPluginFuncs* plugin_funcs) { +#else +NPError NP_Initialize(NPNetscapeFuncs *browser_funcs) { +#endif + if (!browser_funcs) + return NPERR_INVALID_FUNCTABLE_ERROR; + + if (g_browser) + return NPERR_GENERIC_ERROR; + +#if defined(OS_LINUX) + NP_GetEntryPoints(plugin_funcs); +#endif + + g_browser = new NPBrowser(browser_funcs); + + return NPERR_NO_ERROR; +} + +NPError NP_Shutdown() { + if (!g_browser) + return NPERR_GENERIC_ERROR; + + delete g_browser; + g_browser = NULL; + + return NPERR_NO_ERROR; +} +} // namespace gpu_plugin diff --git a/o3d/gpu_plugin/gpu_plugin.gyp b/o3d/gpu_plugin/gpu_plugin.gyp new file mode 100644 index 0000000..c604a30 --- /dev/null +++ b/o3d/gpu_plugin/gpu_plugin.gyp @@ -0,0 +1,162 @@ +# Copyright (c) 2009 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. + +{ + 'includes': [ + '../build/common.gypi', + ], + 'targets': [ + { + 'target_name': 'np_utils', + 'type': '<(library)', + 'dependencies': [ + '../../base/base.gyp:base', + '../build/o3d_in_chrome.gyp:o3d_in_chrome', + ], + 'include_dirs': [ + '../..', + '../../third_party/npapi', + ], + 'all_dependent_settings': { + 'include_dirs': [ + '../..', + '../../third_party/npapi', + ], + }, # 'all_dependent_settings' + 'sources': [ + 'np_utils/default_np_object.h', + 'np_utils/dynamic_np_object.cc', + 'np_utils/dynamic_np_object.h', + 'np_utils/np_browser.cc', + 'np_utils/np_browser.h', + 'np_utils/np_browser_mock.h', + 'np_utils/np_browser_stub.cc', + 'np_utils/np_browser_stub.h', + 'np_utils/np_class.h', + 'np_utils/np_dispatcher.cc', + 'np_utils/np_dispatcher.h', + 'np_utils/np_dispatcher_specializations.h', + 'np_utils/np_headers.h', + 'np_utils/np_object_mock.h', + 'np_utils/np_object_pointer.h', + 'np_utils/np_plugin_object.h', + 'np_utils/np_plugin_object_mock.h', + 'np_utils/np_plugin_object_factory.cc', + 'np_utils/np_plugin_object_factory.h', + 'np_utils/np_plugin_object_factory_mock.h', + 'np_utils/np_utils.cc', + 'np_utils/np_utils.h', + 'np_utils/webkit_browser.h', + ], + }, + + # This is a standalone executable until O3D is fully moved over to using + # gyp. At that point these can become part of the regular O3D unit tests. + { + 'target_name': 'np_utils_unittests', + 'type': 'executable', + 'dependencies': [ + 'np_utils', + '../../testing/gmock.gyp:gmock', + '../../testing/gmock.gyp:gmockmain', + '../../testing/gtest.gyp:gtest', + ], + 'include_dirs': [ + '../..', + ], + 'all_dependent_settings': { + 'include_dirs': [ + '../..', + ], + }, # 'all_dependent_settings' + 'sources': [ + 'np_utils/dispatched_np_object_unittest.cc', + 'np_utils/dynamic_np_object_unittest.cc', + 'np_utils/np_class_unittest.cc', + 'np_utils/np_object_pointer_unittest.cc', + 'np_utils/np_utils_unittest.cc', + ], + }, + + # These can eventually be merged back into the gpu_plugin target. There + # separated for now so O3D can statically link against them and use command + # buffers in-process without the GPU plugin. + { + 'target_name': 'command_buffer', + 'type': '<(library)', + 'dependencies': [ + '../../base/base.gyp:base', + '../command_buffer/command_buffer.gyp:command_buffer_service', + 'np_utils', + ], + 'all_dependent_settings': { + 'include_dirs': [ + '../..', + ], + }, # 'all_dependent_settings' + 'sources': [ + 'command_buffer.cc', + 'command_buffer.h', + 'command_buffer_mock.h', + 'gpu_processor.h', + 'gpu_processor.cc', + 'gpu_processor_mock.h', + 'gpu_processor_win.cc', + ], + }, + + { + 'target_name': 'gpu_plugin', + 'type': '<(library)', + 'dependencies': [ + '../../base/base.gyp:base', + 'command_buffer', + 'np_utils', + ], + 'include_dirs': [ + '../..', + ], + 'sources': [ + 'gpu_plugin.cc', + 'gpu_plugin.h', + 'gpu_plugin_object.cc', + 'gpu_plugin_object.h', + 'gpu_plugin_object_win.cc', + 'gpu_plugin_object_factory.cc', + 'gpu_plugin_object_factory.h', + ], + }, + + # This is a standalone executable until O3D is fully moved over to using + # gyp. At that point these can become part of the regular O3D unit tests. + { + 'target_name': 'gpu_plugin_unittests', + 'type': 'executable', + 'dependencies': [ + '../command_buffer/command_buffer.gyp:command_buffer_service', + 'gpu_plugin', + 'np_utils', + '../../testing/gmock.gyp:gmock', + '../../testing/gmock.gyp:gmockmain', + '../../testing/gtest.gyp:gtest', + ], + 'include_dirs': [ + '../..', + ], + 'sources': [ + 'command_buffer_unittest.cc', + 'gpu_plugin_unittest.cc', + 'gpu_plugin_object_unittest.cc', + 'gpu_plugin_object_factory_unittest.cc', + 'gpu_processor_unittest.cc', + ], + }, + ] +} + +# Local Variables: +# tab-width:2 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=2 shiftwidth=2: diff --git a/o3d/gpu_plugin/gpu_plugin.h b/o3d/gpu_plugin/gpu_plugin.h new file mode 100644 index 0000000..1cefa29 --- /dev/null +++ b/o3d/gpu_plugin/gpu_plugin.h @@ -0,0 +1,30 @@ +// Copyright (c) 2006-2008 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 O3D_GPU_PLUGIN_GPU_PLUGIN_H_ +#define O3D_GPU_PLUGIN_GPU_PLUGIN_H_ + +#include "o3d/gpu_plugin/np_utils/np_headers.h" + +typedef struct _NPPluginFuncs NPPluginFuncs; +typedef struct _NPNetscapeFuncs NPNetscapeFuncs; + +namespace gpu_plugin { + +// Declarations of NPAPI plugin entry points. + +NPError NP_GetEntryPoints(NPPluginFuncs* funcs); + +#if defined(OS_LINUX) +NPError NP_Initialize(NPNetscapeFuncs *browser_funcs, + NPPluginFuncs* plugin_funcs); +#else +NPError NP_Initialize(NPNetscapeFuncs* browser_funcs); +#endif + +NPError NP_Shutdown(); + +} // namespace gpu_plugin + +#endif // O3D_GPU_PLUGIN_GPU_PLUGIN_H_ diff --git a/o3d/gpu_plugin/gpu_plugin_object.cc b/o3d/gpu_plugin/gpu_plugin_object.cc new file mode 100644 index 0000000..801cbca --- /dev/null +++ b/o3d/gpu_plugin/gpu_plugin_object.cc @@ -0,0 +1,117 @@ +// Copyright (c) 2006-2008 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. + +#include + +#include "base/logging.h" +#include "o3d/gpu_plugin/np_utils/np_utils.h" +#include "o3d/gpu_plugin/gpu_plugin_object.h" +#include "o3d/gpu_plugin/gpu_processor.h" + +using ::base::SharedMemory; + +namespace gpu_plugin { + +const NPUTF8 GPUPluginObject::kPluginType[] = + "application/vnd.google.chrome.gpu-plugin"; + +GPUPluginObject::GPUPluginObject(NPP npp) + : npp_(npp), + status_(kWaitingForNew), + command_buffer_(NPCreateObject(npp)), + processor_(new GPUProcessor(npp, command_buffer_.Get())) { + memset(&window_, 0, sizeof(window_)); +} + +NPError GPUPluginObject::New(NPMIMEType plugin_type, + int16 argc, + char* argn[], + char* argv[], + NPSavedData* saved) { + if (status_ != kWaitingForNew) + return NPERR_GENERIC_ERROR; + + status_ = kWaitingForSetWindow; + + return NPERR_NO_ERROR; +} + +NPError GPUPluginObject::SetWindow(NPWindow* new_window) { + if (status_ == kWaitingForNew || status_ == kDestroyed) + return NPERR_GENERIC_ERROR; + + // PlatformSpecificSetWindow advances the status depending on what happens. + NPError error = PlatformSpecificSetWindow(new_window); + if (error == NPERR_NO_ERROR) { + window_ = *new_window; + + if (event_sync_.Get()) { + NPInvokeVoid(npp_, + event_sync_, + "resize", + static_cast(window_.width), + static_cast(window_.height)); + } + } else { + memset(&window_, 0, sizeof(window_)); + } + + return error; +} + +int16 GPUPluginObject::HandleEvent(NPEvent* event) { + return 0; +} + +NPError GPUPluginObject::Destroy(NPSavedData** saved) { + if (status_ == kWaitingForNew || status_ == kDestroyed) + return NPERR_GENERIC_ERROR; + + if (command_buffer_.Get()) { + command_buffer_->SetPutOffsetChangeCallback(NULL); + } + + status_ = kDestroyed; + + return NPERR_NO_ERROR; +} + +void GPUPluginObject::Release() { + DCHECK(status_ == kWaitingForNew || status_ == kDestroyed); + NPBrowser::get()->ReleaseObject(this); +} + +NPObject*GPUPluginObject::GetScriptableNPObject() { + NPBrowser::get()->RetainObject(this); + return this; +} + +NPObjectPointer GPUPluginObject::OpenCommandBuffer() { + if (status_ == kInitializationSuccessful) + return command_buffer_; + + // SetWindow must have been called before OpenCommandBuffer. + // PlatformSpecificSetWindow advances the status to + // kWaitingForOpenCommandBuffer. + if (status_ != kWaitingForOpenCommandBuffer) + return NPObjectPointer(); + + scoped_ptr ring_buffer(new SharedMemory); + if (!ring_buffer->Create(std::wstring(), false, false, kCommandBufferSize)) + return NPObjectPointer(); + + if (command_buffer_->Initialize(ring_buffer.release())) { + if (processor_->Initialize(static_cast(window_.window))) { + command_buffer_->SetPutOffsetChangeCallback( + NewCallback(processor_.get(), + &GPUProcessor::ProcessCommands)); + status_ = kInitializationSuccessful; + return command_buffer_; + } + } + + return NPObjectPointer(); +} + +} // namespace gpu_plugin diff --git a/o3d/gpu_plugin/gpu_plugin_object.h b/o3d/gpu_plugin/gpu_plugin_object.h new file mode 100644 index 0000000..63f44fb --- /dev/null +++ b/o3d/gpu_plugin/gpu_plugin_object.h @@ -0,0 +1,132 @@ +// Copyright (c) 2006-2008 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 O3D_GPU_PLUGIN_GPU_PLUGIN_OBJECT_H_ +#define O3D_GPU_PLUGIN_GPU_PLUGIN_OBJECT_H_ + +#include + +#include "base/ref_counted.h" +#include "base/thread.h" +#include "o3d/gpu_plugin/command_buffer.h" +#include "o3d/gpu_plugin/gpu_processor.h" +#include "o3d/gpu_plugin/np_utils/default_np_object.h" +#include "o3d/gpu_plugin/np_utils/np_dispatcher.h" +#include "o3d/gpu_plugin/np_utils/np_headers.h" +#include "o3d/gpu_plugin/np_utils/np_plugin_object.h" +#include "o3d/gpu_plugin/np_utils/np_utils.h" + +namespace gpu_plugin { + +// The scriptable object for the GPU plugin. +class GPUPluginObject : public DefaultNPObject, + public PluginObject { + public: + static const int32 kCommandBufferSize = 1024 * 1024; + + enum Status { + // In the state of waiting for the named function to be called to continue + // the initialization sequence. + kWaitingForNew, + kWaitingForSetWindow, + kWaitingForOpenCommandBuffer, + + // Initialization either succeeded or failed. + kInitializationSuccessful, + kInitializationFailed, + + // Destroy has now been called and the plugin object cannot be used. + kDestroyed, + }; + + static const NPUTF8 kPluginType[]; + + explicit GPUPluginObject(NPP npp); + + virtual NPError New(NPMIMEType plugin_type, + int16 argc, + char* argn[], + char* argv[], + NPSavedData* saved); + + virtual NPError SetWindow(NPWindow* new_window); + const NPWindow& GetWindow() { return window_; } + + virtual int16 HandleEvent(NPEvent* event); + + virtual NPError Destroy(NPSavedData** saved); + + virtual void Release(); + + virtual NPObject* GetScriptableNPObject(); + + // Returns the current initialization status. See Status enum. + int32 GetStatus() { + return status_; + } + + // Get the width of the plugin window. + int32 GetWidth() { + return window_.width; + } + + // Get the height of the plugin window. + int32 GetHeight() { + return window_.height; + } + + // Set the object that receives notifications of GPU plugin object events + // such as resize and keyboard and mouse input. + void SetEventSync(NPObjectPointer event_sync) { + event_sync_ = event_sync; + } + + NPObjectPointer GetEventSync() { + return event_sync_; + } + + // Initializes and returns the command buffer object. Returns NULL if the + // command buffer cannot be initialized, for example if the plugin does not + // yet have a window handle. + NPObjectPointer OpenCommandBuffer(); + + // Set the status for testing. + void set_status(Status status) { + status_ = status; + } + + // Replace the default command buffer for testing. + void set_command_buffer( + const NPObjectPointer& command_buffer) { + command_buffer_ = command_buffer; + } + + // Replace the default GPU processor for testing. + void set_gpu_processor(const scoped_refptr& processor) { + processor_ = processor; + } + + NP_UTILS_BEGIN_DISPATCHER_CHAIN(GPUPluginObject, DefaultNPObject) + NP_UTILS_DISPATCHER(GetStatus, int32()); + NP_UTILS_DISPATCHER(GetWidth, int32()); + NP_UTILS_DISPATCHER(GetHeight, int32()); + NP_UTILS_DISPATCHER(SetEventSync, void(NPObjectPointer sync)); + NP_UTILS_DISPATCHER(GetEventSync, NPObjectPointer()); + NP_UTILS_DISPATCHER(OpenCommandBuffer, NPObjectPointer()) + NP_UTILS_END_DISPATCHER_CHAIN + + private: + NPError PlatformSpecificSetWindow(NPWindow* new_window); + + NPP npp_; + Status status_; + NPWindow window_; + NPObjectPointer command_buffer_; + scoped_refptr processor_; + NPObjectPointer event_sync_; +}; + +} // namespace gpu_plugin + +#endif // O3D_GPU_PLUGIN_GPU_PLUGIN_OBJECT_H_ diff --git a/o3d/gpu_plugin/gpu_plugin_object_factory.cc b/o3d/gpu_plugin/gpu_plugin_object_factory.cc new file mode 100644 index 0000000..7727f50 --- /dev/null +++ b/o3d/gpu_plugin/gpu_plugin_object_factory.cc @@ -0,0 +1,27 @@ +// Copyright (c) 2006-2008 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. + +#include "o3d/gpu_plugin/gpu_plugin_object.h" +#include "o3d/gpu_plugin/gpu_plugin_object_factory.h" +#include "o3d/gpu_plugin/np_utils/np_utils.h" + +namespace gpu_plugin { + +GPUPluginObjectFactory::GPUPluginObjectFactory() { +} + +GPUPluginObjectFactory::~GPUPluginObjectFactory() { +} + +PluginObject* GPUPluginObjectFactory::CreatePluginObject( + NPP npp, + NPMIMEType plugin_type) { + if (strcmp(plugin_type, GPUPluginObject::kPluginType) == 0) { + return NPCreateObject(npp).ToReturned(); + } + + return NULL; +} + +} // namespace gpu_plugin diff --git a/o3d/gpu_plugin/gpu_plugin_object_factory.h b/o3d/gpu_plugin/gpu_plugin_object_factory.h new file mode 100644 index 0000000..d038297 --- /dev/null +++ b/o3d/gpu_plugin/gpu_plugin_object_factory.h @@ -0,0 +1,26 @@ +// Copyright (c) 2006-2008 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 O3D_GPU_PLUGIN_GPU_PLUGIN_OBJECT_FACTORY_H_ +#define O3D_GPU_PLUGIN_GPU_PLUGIN_OBJECT_FACTORY_H_ + +#include "o3d/gpu_plugin/np_utils/np_plugin_object_factory.h" + +namespace gpu_plugin { + +// Plugin object factory for creating the GPUPluginObject. +class GPUPluginObjectFactory : public NPPluginObjectFactory { + public: + GPUPluginObjectFactory(); + virtual ~GPUPluginObjectFactory(); + + virtual PluginObject* CreatePluginObject(NPP npp, NPMIMEType plugin_type); + + private: + DISALLOW_COPY_AND_ASSIGN(GPUPluginObjectFactory); +}; + +} // namespace gpu_plugin + +#endif // O3D_GPU_PLUGIN_GPU_PLUGIN_OBJECT_FACTORY_H_ diff --git a/o3d/gpu_plugin/gpu_plugin_object_factory_unittest.cc b/o3d/gpu_plugin/gpu_plugin_object_factory_unittest.cc new file mode 100644 index 0000000..8a3413d --- /dev/null +++ b/o3d/gpu_plugin/gpu_plugin_object_factory_unittest.cc @@ -0,0 +1,39 @@ +// Copyright (c) 2006-2008 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. + +#include "o3d/gpu_plugin/gpu_plugin_object.h" +#include "o3d/gpu_plugin/gpu_plugin_object_factory.h" +#include "o3d/gpu_plugin/np_utils/np_browser_stub.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace gpu_plugin { + +class PluginObjectFactoryTest : public testing::Test { + protected: + virtual void SetUp() { + factory_ = new GPUPluginObjectFactory; + } + + virtual void TearDown() { + delete factory_; + } + + StubNPBrowser stub_browser_; + GPUPluginObjectFactory* factory_; +}; + +TEST_F(PluginObjectFactoryTest, ReturnsNullForUnknownMimeType) { + PluginObject* plugin_object = factory_->CreatePluginObject( + NULL, "application/unknown"); + EXPECT_TRUE(NULL == plugin_object); +} + +TEST_F(PluginObjectFactoryTest, CreatesGPUPlugin) { + PluginObject* plugin_object = factory_->CreatePluginObject( + NULL, const_cast(GPUPluginObject::kPluginType)); + EXPECT_TRUE(NULL != plugin_object); +} + +} // namespace gpu_plugin diff --git a/o3d/gpu_plugin/gpu_plugin_object_unittest.cc b/o3d/gpu_plugin/gpu_plugin_object_unittest.cc new file mode 100644 index 0000000..8bc7bfb --- /dev/null +++ b/o3d/gpu_plugin/gpu_plugin_object_unittest.cc @@ -0,0 +1,346 @@ +// Copyright (c) 2006-2008 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. + +#include "o3d/gpu_plugin/command_buffer_mock.h" +#include "o3d/gpu_plugin/gpu_plugin_object.h" +#include "o3d/gpu_plugin/gpu_processor_mock.h" +#include "o3d/gpu_plugin/np_utils/np_browser_mock.h" +#include "o3d/gpu_plugin/np_utils/dynamic_np_object.h" +#include "o3d/gpu_plugin/np_utils/np_object_mock.h" +#include "o3d/gpu_plugin/np_utils/np_object_pointer.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/gmock/include/gmock/gmock.h" + +#if defined(O3D_IN_CHROME) +#include "webkit/glue/plugins/nphostapi.h" +#else +#include "o3d/third_party/npapi/include/npfunctions.h" +#endif + +using ::base::SharedMemory; + +using testing::_; +using testing::DoAll; +using testing::Invoke; +using testing::NotNull; +using testing::Return; +using testing::SetArgumentPointee; +using testing::StrictMock; + +namespace gpu_plugin { + +class MockSystemNPObject : public DefaultNPObject { + public: + explicit MockSystemNPObject(NPP npp) { + } + + MOCK_METHOD1(CreateSharedMemory, NPObjectPointer(int32 size)); + + NP_UTILS_BEGIN_DISPATCHER_CHAIN(MockSystemNPObject, DefaultNPObject) + NP_UTILS_DISPATCHER(CreateSharedMemory, + NPObjectPointer(int32 size)) + NP_UTILS_END_DISPATCHER_CHAIN + + private: + DISALLOW_COPY_AND_ASSIGN(MockSystemNPObject); +}; + +class GPUPluginObjectTest : public testing::Test { + protected: + virtual void SetUp() { + plugin_object_ = NPCreateObject(NULL); + + command_buffer_ = NPCreateObject(NULL); + plugin_object_->set_command_buffer(command_buffer_); + + processor_ = new MockGPUProcessor(NULL, command_buffer_.Get()); + plugin_object_->set_gpu_processor(processor_.get()); + + window_object_ = NPCreateObject(NULL); + ON_CALL(mock_browser_, GetWindowNPObject(NULL)) + .WillByDefault(Return(window_object_.ToReturned())); + + chromium_object_ = NPCreateObject(NULL); + NPSetProperty(NULL, window_object_, "chromium", chromium_object_); + + system_object_ = NPCreateObject >(NULL); + NPSetProperty(NULL, chromium_object_, "system", system_object_); + } + + MockNPBrowser mock_browser_; + NPObjectPointer plugin_object_; + NPObjectPointer command_buffer_; + scoped_refptr processor_; + NPObjectPointer window_object_; + NPObjectPointer chromium_object_; + NPObjectPointer system_object_; +}; + +namespace { +template +void DeleteObject(T* object) { + delete object; +} +} // namespace anonymous + + +TEST_F(GPUPluginObjectTest, CanInstantiateAndDestroyPluginObject) { + EXPECT_EQ(GPUPluginObject::kWaitingForNew, plugin_object_->GetStatus()); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", + 0, + NULL, + NULL, + NULL)); + + EXPECT_EQ(GPUPluginObject::kWaitingForSetWindow, plugin_object_->GetStatus()); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); + + EXPECT_EQ(GPUPluginObject::kDestroyed, plugin_object_->GetStatus()); +} + +TEST_F(GPUPluginObjectTest, DestroyFailsIfNotInitialized) { + EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_object_->Destroy(NULL)); +} + +TEST_F(GPUPluginObjectTest, NewFailsIfAlreadyInitialized) { + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", + 0, + NULL, + NULL, + NULL)); + + EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_object_->New("application/foo", + 0, + NULL, + NULL, + NULL)); + + EXPECT_EQ(GPUPluginObject::kWaitingForSetWindow, plugin_object_->GetStatus()); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); + + EXPECT_EQ(GPUPluginObject::kDestroyed, plugin_object_->GetStatus()); +} + +TEST_F(GPUPluginObjectTest, NewFailsIfObjectHasPreviouslyBeenDestroyed) { + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", + 0, + NULL, + NULL, + NULL)); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); + + EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_object_->New("application/foo", + 0, + NULL, + NULL, + NULL)); + + EXPECT_EQ(GPUPluginObject::kDestroyed, plugin_object_->GetStatus()); +} + +TEST_F(GPUPluginObjectTest, WindowIsNullBeforeSetWindowCalled) { + NPWindow window = plugin_object_->GetWindow(); + EXPECT_EQ(NULL, window.window); +} + +TEST_F(GPUPluginObjectTest, CanSetWindow) { + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", + 0, + NULL, + NULL, + NULL)); + + NPWindow window = {0}; + window.window = &window; + window.x = 7; + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->SetWindow(&window)); + EXPECT_EQ(0, memcmp(&window, &plugin_object_->GetWindow(), sizeof(window))); + EXPECT_EQ(GPUPluginObject::kWaitingForOpenCommandBuffer, + plugin_object_->GetStatus()); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); +} + +TEST_F(GPUPluginObjectTest, CanGetWindowSize) { + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", + 0, + NULL, + NULL, + NULL)); + + NPWindow window = {0}; + window.window = &window; + window.x = 10; + window.y = 10; + window.width = 100; + window.height = 200; + + EXPECT_EQ(0, plugin_object_->GetWidth()); + EXPECT_EQ(0, plugin_object_->GetHeight()); + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->SetWindow(&window)); + EXPECT_EQ(100, plugin_object_->GetWidth()); + EXPECT_EQ(200, plugin_object_->GetHeight()); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); +} + +TEST_F(GPUPluginObjectTest, SetWindowFailsIfNotInitialized) { + NPWindow window = {0}; + EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_object_->SetWindow(&window)); + EXPECT_EQ(GPUPluginObject::kWaitingForNew, plugin_object_->GetStatus()); +} + +TEST_F(GPUPluginObjectTest, CanGetScriptableNPObject) { + NPObject* scriptable_object = plugin_object_->GetScriptableNPObject(); + EXPECT_EQ(plugin_object_.Get(), scriptable_object); + NPBrowser::get()->ReleaseObject(scriptable_object); +} + +TEST_F(GPUPluginObjectTest, OpenCommandBufferReturnsInitializedCommandBuffer) { + EXPECT_CALL(*command_buffer_.Get(), Initialize(NotNull())) + .WillOnce(DoAll(Invoke(DeleteObject), + Return(true))); + + EXPECT_CALL(*processor_.get(), Initialize(NULL)) + .WillOnce(Return(true)); + + EXPECT_CALL(*command_buffer_.Get(), SetPutOffsetChangeCallback(NotNull())) + .WillOnce(Invoke(DeleteObject)); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", + 0, + NULL, + NULL, + NULL)); + + // Set status as though SetWindow has been called. Avoids having to create a + // valid window handle to pass to SetWindow in tests. + plugin_object_->set_status(GPUPluginObject::kWaitingForOpenCommandBuffer); + + EXPECT_EQ(command_buffer_, plugin_object_->OpenCommandBuffer()); + + // Calling OpenCommandBuffer again just returns the existing command buffer. + EXPECT_EQ(command_buffer_, plugin_object_->OpenCommandBuffer()); + + EXPECT_EQ(GPUPluginObject::kInitializationSuccessful, + plugin_object_->GetStatus()); + + EXPECT_CALL(*command_buffer_.Get(), SetPutOffsetChangeCallback(NULL)); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); +} + +TEST_F(GPUPluginObjectTest, OpenCommandBufferReturnsNullIfWindowNotReady) { + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", + 0, + NULL, + NULL, + NULL)); + + // Set status as though SetWindow has not been called. + plugin_object_->set_status(GPUPluginObject::kWaitingForSetWindow); + + EXPECT_EQ(NPObjectPointer(), plugin_object_->OpenCommandBuffer()); + + EXPECT_EQ(GPUPluginObject::kWaitingForSetWindow, plugin_object_->GetStatus()); +} + + +TEST_F(GPUPluginObjectTest, + OpenCommandBufferReturnsNullIfCommandBufferCannotInitialize) { + EXPECT_CALL(*command_buffer_.Get(), Initialize(NotNull())) + .WillOnce(DoAll(Invoke(DeleteObject), + Return(false))); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", + 0, + NULL, + NULL, + NULL)); + + // Set status as though SetWindow has been called. Avoids having to create a + // valid window handle to pass to SetWindow in tests. + plugin_object_->set_status(GPUPluginObject::kWaitingForOpenCommandBuffer); + + EXPECT_EQ(NPObjectPointer(), plugin_object_->OpenCommandBuffer()); + + EXPECT_EQ(GPUPluginObject::kWaitingForOpenCommandBuffer, + plugin_object_->GetStatus()); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); +} + +TEST_F(GPUPluginObjectTest, + OpenCommandBufferReturnsNullIGPUProcessorCannotInitialize) { + EXPECT_CALL(*command_buffer_.Get(), Initialize(NotNull())) + .WillOnce(DoAll(Invoke(DeleteObject), + Return(true))); + + EXPECT_CALL(*processor_.get(), Initialize(NULL)) + .WillOnce(Return(false)); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", + 0, + NULL, + NULL, + NULL)); + + // Set status as though SetWindow has been called. Avoids having to create a + // valid window handle to pass to SetWindow in tests. + plugin_object_->set_status(GPUPluginObject::kWaitingForOpenCommandBuffer); + + EXPECT_EQ(NPObjectPointer(), plugin_object_->OpenCommandBuffer()); + + EXPECT_EQ(GPUPluginObject::kWaitingForOpenCommandBuffer, + plugin_object_->GetStatus()); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); +} + +class MockEventSync : public DefaultNPObject { + public: + explicit MockEventSync(NPP npp) { + } + + MOCK_METHOD2(Resize, void(int32 width, int32 height)); + + NP_UTILS_BEGIN_DISPATCHER_CHAIN(MockEventSync, DefaultNPObject) + NP_UTILS_DISPATCHER(Resize, void(int32 width, int32 height)) + NP_UTILS_END_DISPATCHER_CHAIN + + private: + DISALLOW_COPY_AND_ASSIGN(MockEventSync); +}; + +TEST_F(GPUPluginObjectTest, SendsResizeEventOnSetWindow) { + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", + 0, + NULL, + NULL, + NULL)); + + NPObjectPointer event_sync = + NPCreateObject(NULL); + plugin_object_->SetEventSync(event_sync); + + EXPECT_CALL(*event_sync.Get(), Resize(100, 200)); + + NPWindow window = {0}; + window.window = &window; + window.x = 10; + window.y = 10; + window.width = 100; + window.height = 200; + + plugin_object_->SetWindow(&window); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); +} + +} // namespace gpu_plugin diff --git a/o3d/gpu_plugin/gpu_plugin_object_win.cc b/o3d/gpu_plugin/gpu_plugin_object_win.cc new file mode 100644 index 0000000..5ff5cf5 --- /dev/null +++ b/o3d/gpu_plugin/gpu_plugin_object_win.cc @@ -0,0 +1,62 @@ +// Copyright (c) 2006-2008 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. + +#include + +#include "o3d/gpu_plugin/gpu_plugin_object.h" +#include "o3d/gpu_plugin/gpu_processor.h" + +namespace gpu_plugin { + +namespace { +const LPCTSTR kPluginObjectProperty = TEXT("GPUPluginObject"); +const LPCTSTR kOriginalWindowProc = TEXT("GPUPluginObjectOriginalWindowProc"); + +LRESULT CALLBACK WindowProc(HWND handle, + UINT message, + WPARAM w_param, + LPARAM l_param) { + return ::DefWindowProc(handle, message, w_param, l_param); +} +} // namespace anonymous + +NPError GPUPluginObject::PlatformSpecificSetWindow(NPWindow* new_window) { + // Detach properties from old window and restore the original window proc. + if (window_.window) { + HWND handle = reinterpret_cast(window_.window); + ::RemoveProp(handle, kPluginObjectProperty); + + LONG original_window_proc = reinterpret_cast( + ::GetProp(handle, kOriginalWindowProc)); + ::SetWindowLong(handle, GWL_WNDPROC, + original_window_proc); + ::RemoveProp(handle, kOriginalWindowProc); + } + + // Attach properties to new window and set a new window proc. + if (new_window->window) { + HWND handle = reinterpret_cast(new_window->window); + ::SetProp(handle, + kPluginObjectProperty, + reinterpret_cast(this)); + + LONG original_window_proc = ::GetWindowLong(handle, GWL_WNDPROC); + ::SetProp(handle, + kOriginalWindowProc, + reinterpret_cast(original_window_proc)); + ::SetWindowLong(handle, GWL_WNDPROC, + reinterpret_cast(WindowProc)); + + status_ = kWaitingForOpenCommandBuffer; + } else { + status_ = kWaitingForSetWindow; + if (processor_) { + processor_->Destroy(); + } + } + + return NPERR_NO_ERROR; +} + +} // namespace gpu_plugin diff --git a/o3d/gpu_plugin/gpu_plugin_unittest.cc b/o3d/gpu_plugin/gpu_plugin_unittest.cc new file mode 100644 index 0000000..0bc53fd --- /dev/null +++ b/o3d/gpu_plugin/gpu_plugin_unittest.cc @@ -0,0 +1,305 @@ +// Copyright (c) 2006-2008 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. + +#include "o3d/gpu_plugin/gpu_plugin.h" +#include "o3d/gpu_plugin/gpu_plugin_object.h" +#include "o3d/gpu_plugin/np_utils/np_object_mock.h" +#include "o3d/gpu_plugin/np_utils/np_plugin_object_factory_mock.h" +#include "o3d/gpu_plugin/np_utils/np_plugin_object_mock.h" +#include "testing/gtest/include/gtest/gtest.h" + +#if defined(O3D_IN_CHROME) +#include "webkit/glue/plugins/nphostapi.h" +#else +#include "o3d/third_party/npapi/include/npfunctions.h" +#endif + +#if defined(OS_LINUX) +#define INITIALIZE_PLUGIN_FUNCS , &plugin_funcs_ +#else +#define INITIALIZE_PLUGIN_FUNCS +#endif + +using testing::_; +using testing::DoAll; +using testing::NiceMock; +using testing::Return; +using testing::SetArgumentPointee; +using testing::StrictMock; + +namespace gpu_plugin { + +class GPUPluginTest : public testing::Test { + protected: + virtual void SetUp() { + memset(&npp_, 0, sizeof(npp_)); + memset(&browser_funcs_, 0, sizeof(browser_funcs_)); + memset(&plugin_funcs_, 0, sizeof(plugin_funcs_)); + + plugin_object_factory_ = new StrictMock; + + np_class_ = NPGetClass >(); + } + + virtual void TearDown() { + delete plugin_object_factory_; + } + + NPP_t npp_; + NPNetscapeFuncs browser_funcs_; + NPPluginFuncs plugin_funcs_; + MockPluginObjectFactory* plugin_object_factory_; + const NPClass* np_class_; +}; + +TEST_F(GPUPluginTest, GetEntryPointsSetsNeededFunctionPointers) { +#if defined(OS_LINUX) + NPError error = gpu_plugin::NP_Initialize(&browser_funcs_, + &plugin_funcs_); + gpu_plugin::NP_Shutdown(); +#else + NPError error = gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); +#endif + + EXPECT_EQ(NPERR_NO_ERROR, error); + EXPECT_TRUE(NULL != plugin_funcs_.newp); + EXPECT_TRUE(NULL != plugin_funcs_.destroy); + EXPECT_TRUE(NULL != plugin_funcs_.setwindow); + EXPECT_TRUE(NULL != plugin_funcs_.event); + EXPECT_TRUE(NULL != plugin_funcs_.getvalue); + EXPECT_TRUE(NULL != plugin_funcs_.setvalue); +} + +TEST_F(GPUPluginTest, CanInitializeAndShutdownPlugin) { + EXPECT_EQ(NPERR_NO_ERROR, + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS)); + EXPECT_EQ(NPERR_NO_ERROR, gpu_plugin::NP_Shutdown()); +} + +TEST_F(GPUPluginTest, InitializeFailsIfBrowserFuncsIsNull) { + EXPECT_EQ(NPERR_INVALID_FUNCTABLE_ERROR, + gpu_plugin::NP_Initialize(NULL INITIALIZE_PLUGIN_FUNCS)); +} + +TEST_F(GPUPluginTest, InitializeFailsIfAlreadyInitialized) { + EXPECT_EQ(NPERR_NO_ERROR, + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS)); + EXPECT_EQ(NPERR_GENERIC_ERROR, + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS)); + EXPECT_EQ(NPERR_NO_ERROR, gpu_plugin::NP_Shutdown()); +} + +TEST_F(GPUPluginTest, ShutdownFailsIfNotInitialized) { + EXPECT_EQ(NPERR_GENERIC_ERROR, gpu_plugin::NP_Shutdown()); +} + +TEST_F(GPUPluginTest, NewReturnsErrorForInvalidInstance) { + gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); + + EXPECT_EQ(NPERR_INVALID_INSTANCE_ERROR, plugin_funcs_.newp( + const_cast(GPUPluginObject::kPluginType), + NULL, 0, 0, NULL, NULL, NULL)); + + gpu_plugin::NP_Shutdown(); +} + +TEST_F(GPUPluginTest, GetValueReturnsErrorForInvalidInstance) { + gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); + + int* result = NULL; + EXPECT_EQ(NPERR_INVALID_INSTANCE_ERROR, plugin_funcs_.getvalue( + NULL, NPPVjavaClass, &result)); + + gpu_plugin::NP_Shutdown(); +} + +TEST_F(GPUPluginTest, DestroyReturnsErrorForInvalidInstance) { + gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); + + EXPECT_EQ(NPERR_INVALID_INSTANCE_ERROR, plugin_funcs_.destroy(NULL, NULL)); + + gpu_plugin::NP_Shutdown(); +} + +TEST_F(GPUPluginTest, SetWindowReturnsErrorForInvalidInstance) { + gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); + + EXPECT_EQ(NPERR_INVALID_INSTANCE_ERROR, plugin_funcs_.setwindow(NULL, NULL)); + + gpu_plugin::NP_Shutdown(); +} + +TEST_F(GPUPluginTest, HandleEventReturnsFalseForInvalidInstance) { + gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); + + EXPECT_EQ(0, plugin_funcs_.event(NULL, NULL)); + + gpu_plugin::NP_Shutdown(); +} + +TEST_F(GPUPluginTest, NewCreatesAPluginObjectAndInitializesIt) { + StrictMock plugin_object; + + EXPECT_CALL(*plugin_object_factory_, CreatePluginObject( + &npp_, const_cast(GPUPluginObject::kPluginType))) + .WillOnce(Return(&plugin_object)); + + NPObject scriptable_object; + + EXPECT_CALL(plugin_object, New( + const_cast(GPUPluginObject::kPluginType), + 0, NULL, NULL, NULL)) + .WillOnce(Return(NPERR_NO_ERROR)); + + EXPECT_CALL(plugin_object, GetScriptableNPObject()) + .WillOnce(Return(&scriptable_object)); + + EXPECT_CALL(plugin_object, Destroy(static_cast(NULL))) + .WillOnce(Return(NPERR_NO_ERROR)); + + EXPECT_CALL(plugin_object, Release()); + + gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.newp( + const_cast(GPUPluginObject::kPluginType), + &npp_, 0, 0, NULL, NULL, NULL)); + + NPObject* result; + EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.getvalue( + &npp_, NPPVpluginScriptableNPObject, &result)); + EXPECT_EQ(&scriptable_object, result); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.destroy(&npp_, NULL)); + + gpu_plugin::NP_Shutdown(); +} + +TEST_F(GPUPluginTest, NewFailsIfPluginObjectFactoryFails) { + EXPECT_CALL(*plugin_object_factory_, CreatePluginObject( + &npp_, const_cast(GPUPluginObject::kPluginType))) + .WillOnce(Return(static_cast(NULL))); + + gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); + + EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_funcs_.newp( + const_cast(GPUPluginObject::kPluginType), + &npp_, 0, 0, NULL, NULL, NULL)); + + gpu_plugin::NP_Shutdown(); +} + +TEST_F(GPUPluginTest, SetWindowForwardsToPluginObject) { + StrictMock plugin_object; + + EXPECT_CALL(*plugin_object_factory_, CreatePluginObject( + &npp_, const_cast(GPUPluginObject::kPluginType))) + .WillOnce(Return(&plugin_object)); + + EXPECT_CALL(plugin_object, New( + const_cast(GPUPluginObject::kPluginType), + 0, NULL, NULL, NULL)) + .WillOnce(Return(NPERR_NO_ERROR)); + + NPWindow window = {0}; + + EXPECT_CALL(plugin_object, SetWindow(&window)) + .WillOnce(Return(NPERR_NO_ERROR)); + + EXPECT_CALL(plugin_object, Destroy(static_cast(NULL))) + .WillOnce(Return(NPERR_NO_ERROR)); + + EXPECT_CALL(plugin_object, Release()); + + gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.newp( + const_cast(GPUPluginObject::kPluginType), + &npp_, 0, 0, NULL, NULL, NULL)); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.setwindow(&npp_, &window)); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.destroy(&npp_, NULL)); + + gpu_plugin::NP_Shutdown(); +} + +TEST_F(GPUPluginTest, HandleEventForwardsToPluginObject) { + StrictMock plugin_object; + + EXPECT_CALL(*plugin_object_factory_, CreatePluginObject( + &npp_, const_cast(GPUPluginObject::kPluginType))) + .WillOnce(Return(&plugin_object)); + + EXPECT_CALL(plugin_object, New( + const_cast(GPUPluginObject::kPluginType), + 0, NULL, NULL, NULL)) + .WillOnce(Return(NPERR_NO_ERROR)); + + NPEvent event = {0}; + + EXPECT_CALL(plugin_object, HandleEvent(&event)) + .WillOnce(Return(7)); + + EXPECT_CALL(plugin_object, Destroy(static_cast(NULL))) + .WillOnce(Return(NPERR_NO_ERROR)); + + EXPECT_CALL(plugin_object, Release()); + + gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.newp( + const_cast(GPUPluginObject::kPluginType), + &npp_, 0, 0, NULL, NULL, NULL)); + + EXPECT_EQ(7, plugin_funcs_.event(&npp_, &event)); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.destroy(&npp_, NULL)); + + gpu_plugin::NP_Shutdown(); +} + +TEST_F(GPUPluginTest, GetValueReturnsErrorForUnknownVariable) { + StrictMock plugin_object; + + EXPECT_CALL(*plugin_object_factory_, CreatePluginObject( + &npp_, const_cast(GPUPluginObject::kPluginType))) + .WillOnce(Return(&plugin_object)); + + EXPECT_CALL(plugin_object, New( + const_cast(GPUPluginObject::kPluginType), + 0, NULL, NULL, NULL)) + .WillOnce(Return(NPERR_NO_ERROR)); + + EXPECT_CALL(plugin_object, Destroy(static_cast(NULL))) + .WillOnce(Return(NPERR_NO_ERROR)); + + EXPECT_CALL(plugin_object, Release()); + + gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.newp( + const_cast(GPUPluginObject::kPluginType), + &npp_, 0, 0, NULL, NULL, NULL)); + + int* result = NULL; + EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_funcs_.getvalue( + &npp_, NPPVjavaClass, &result)); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.destroy(&npp_, NULL)); + + gpu_plugin::NP_Shutdown(); +} + +} // namespace gpu_plugin diff --git a/o3d/gpu_plugin/gpu_processor.cc b/o3d/gpu_plugin/gpu_processor.cc new file mode 100644 index 0000000..f554fb5 --- /dev/null +++ b/o3d/gpu_plugin/gpu_processor.cc @@ -0,0 +1,80 @@ +// Copyright (c) 2006-2008 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. + +#include "o3d/gpu_plugin/gpu_processor.h" + +using ::base::SharedMemory; + +namespace gpu_plugin { + +GPUProcessor::~GPUProcessor() { +} + +namespace { +void InvokeProcessCommands(void* data) { + static_cast(data)->ProcessCommands(); +} +} // namespace anonymous + +void GPUProcessor::ProcessCommands() { + if (command_buffer_->GetErrorStatus()) + return; + + parser_->set_put(command_buffer_->GetPutOffset()); + + int commands_processed = 0; + while (commands_processed < commands_per_update_ && !parser_->IsEmpty()) { + command_buffer::parse_error::ParseError parse_error = + parser_->ProcessCommand(); + switch (parse_error) { + case command_buffer::parse_error::kParseUnknownCommand: + case command_buffer::parse_error::kParseInvalidArguments: + command_buffer_->SetParseError(parse_error); + break; + + case command_buffer::parse_error::kParseInvalidSize: + case command_buffer::parse_error::kParseOutOfBounds: + command_buffer_->SetParseError(parse_error); + command_buffer_->RaiseErrorStatus(); + return; + } + + ++commands_processed; + } + + command_buffer_->SetGetOffset(static_cast(parser_->get())); + + if (!parser_->IsEmpty()) { + NPBrowser::get()->PluginThreadAsyncCall(npp_, InvokeProcessCommands, this); + } +} + +void *GPUProcessor::GetSharedMemoryAddress(int32 shm_id) { + SharedMemory* shared_memory = command_buffer_->GetTransferBuffer(shm_id); + if (!shared_memory) + return NULL; + + if (!shared_memory->memory()) { + if (!shared_memory->Map(shared_memory->max_size())) + return NULL; + } + + return shared_memory->memory(); +} + +// TODO(apatrick): Consolidate this with the above and return both the address +// and size. +size_t GPUProcessor::GetSharedMemorySize(int32 shm_id) { + SharedMemory* shared_memory = command_buffer_->GetTransferBuffer(shm_id); + if (!shared_memory) + return 0; + + return shared_memory->max_size(); +} + +void GPUProcessor::set_token(int32 token) { + command_buffer_->SetToken(token); +} + +} // namespace gpu_plugin diff --git a/o3d/gpu_plugin/gpu_processor.h b/o3d/gpu_plugin/gpu_processor.h new file mode 100644 index 0000000..49c6eea --- /dev/null +++ b/o3d/gpu_plugin/gpu_processor.h @@ -0,0 +1,119 @@ +// Copyright (c) 2006-2008 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 O3D_GPU_PLUGIN_GPU_PROCESSOR_H_ +#define O3D_GPU_PLUGIN_GPU_PROCESSOR_H_ + +#include "base/ref_counted.h" +#include "base/scoped_ptr.h" +#include "base/shared_memory.h" +#include "o3d/command_buffer/service/cmd_buffer_engine.h" +#include "o3d/command_buffer/service/cmd_parser.h" +#include "o3d/command_buffer/service/gapi_decoder.h" +#include "o3d/gpu_plugin/command_buffer.h" +#include "o3d/gpu_plugin/np_utils/np_object_pointer.h" + +#if defined(CB_SERVICE_D3D9) +#include "o3d/command_buffer/service/gapi_d3d9.h" +#elif defined(CB_SERVICE_GL) +#include "o3d/command_buffer/service/gapi_gl.h" +#else +#error command buffer service not defined +#endif + +namespace gpu_plugin { + +// This class processes commands in a command buffer. It is event driven and +// posts tasks to the current message loop to do additional work. +class GPUProcessor : public ::base::RefCounted, + public command_buffer::CommandBufferEngine { + public: +#if defined(CB_SERVICE_D3D9) + typedef command_buffer::o3d::GAPID3D9 GPUGAPIInterface; +#elif defined(CB_SERVICE_GL) + typedef command_buffer::o3d::GAPIGL GPUGAPIInterface; +#else +#error command buffer service not defined +#endif + + GPUProcessor(NPP npp, + CommandBuffer* command_buffer); + + // This constructor is for unit tests. + GPUProcessor(NPP npp, + CommandBuffer* command_buffer, + GPUGAPIInterface* gapi, + command_buffer::o3d::GAPIDecoder* decoder, + command_buffer::CommandParser* parser, + int commands_per_update); + + virtual bool Initialize(HWND hwnd); + + virtual ~GPUProcessor(); + + virtual void Destroy(); + + virtual void ProcessCommands(); + +#if defined(OS_WIN) + virtual bool SetWindow(HWND handle, int width, int height); +#endif + + // Implementation of CommandBufferEngine. + + // Gets the base address of a registered shared memory buffer. + // Parameters: + // shm_id: the identifier for the shared memory buffer. + virtual void *GetSharedMemoryAddress(int32 shm_id); + + // Gets the size of a registered shared memory buffer. + // Parameters: + // shm_id: the identifier for the shared memory buffer. + virtual size_t GetSharedMemorySize(int32 shm_id); + + // Sets the token value. + virtual void set_token(int32 token); + + private: + NPP npp_; + + // The GPUProcessor holds a weak reference to the CommandBuffer. The + // CommandBuffer owns the GPUProcessor and holds a strong reference to it + // through the ProcessCommands callback. + CommandBuffer* command_buffer_; + + scoped_ptr< ::base::SharedMemory> mapped_ring_buffer_; + int commands_per_update_; + + scoped_ptr gapi_; + scoped_ptr decoder_; + scoped_ptr parser_; +}; + +} // namespace gpu_plugin + +// Callbacks to the GPUProcessor hold a reference count. +template +class CallbackStorage { + public: + CallbackStorage(gpu_plugin::GPUProcessor* obj, Method method) + : obj_(obj), + meth_(method) { + DCHECK(obj_); + obj_->AddRef(); + } + + ~CallbackStorage() { + obj_->Release(); + } + + protected: + gpu_plugin::GPUProcessor* obj_; + Method meth_; + + private: + DISALLOW_COPY_AND_ASSIGN(CallbackStorage); +}; + +#endif // O3D_GPU_PLUGIN_GPU_PROCESSOR_H_ diff --git a/o3d/gpu_plugin/gpu_processor_mock.h b/o3d/gpu_plugin/gpu_processor_mock.h new file mode 100644 index 0000000..d98f5af --- /dev/null +++ b/o3d/gpu_plugin/gpu_processor_mock.h @@ -0,0 +1,41 @@ +// Copyright (c) 2006-2008 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 O3D_GPU_PLUGIN_GPU_PROCESSOR_MOCK_H_ +#define O3D_GPU_PLUGIN_GPU_PROCESSOR_MOCK_H_ + +#include "o3d/gpu_plugin/gpu_processor.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace gpu_plugin { + +class MockGPUProcessor : public GPUProcessor { + public: + MockGPUProcessor(NPP npp, + CommandBuffer* command_buffer) + : GPUProcessor(npp, command_buffer) { + } + +#if defined(OS_WIN) + MOCK_METHOD1(Initialize, bool(HWND handle)); +#endif + + MOCK_METHOD0(Destroy, void()); + MOCK_METHOD0(ProcessCommands, void()); + +#if defined(OS_WIN) + MOCK_METHOD3(SetWindow, bool(HWND handle, int width, int height)); +#endif + + MOCK_METHOD1(GetSharedMemoryAddress, void*(int32 shm_id)); + MOCK_METHOD1(GetSharedMemorySize, size_t(int32 shm_id)); + MOCK_METHOD1(set_token, void(int32 token)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockGPUProcessor); +}; + +} // namespace gpu_plugin + +#endif // O3D_GPU_PLUGIN_GPU_PROCESSOR_MOCK_H_ diff --git a/o3d/gpu_plugin/gpu_processor_unittest.cc b/o3d/gpu_plugin/gpu_processor_unittest.cc new file mode 100644 index 0000000..74c593c --- /dev/null +++ b/o3d/gpu_plugin/gpu_processor_unittest.cc @@ -0,0 +1,309 @@ +// Copyright (c) 2006-2008 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. + +#include "base/at_exit.h" +#include "base/message_loop.h" +#include "o3d/command_buffer/service/mocks.h" +#include "o3d/gpu_plugin/command_buffer_mock.h" +#include "o3d/gpu_plugin/gpu_processor.h" +#include "o3d/gpu_plugin/np_utils/np_browser_mock.h" +#include "o3d/gpu_plugin/np_utils/np_object_pointer.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/gmock/include/gmock/gmock.h" + +using ::base::SharedMemory; + +using testing::_; +using testing::DoAll; +using testing::Invoke; +using testing::NiceMock; +using testing::Return; +using testing::SetArgumentPointee; +using testing::StrictMock; + +namespace gpu_plugin { + +const size_t kRingBufferSize = 1024; +const size_t kRingBufferEntries = kRingBufferSize / sizeof(int32); + +class GPUProcessorTest : public testing::Test { + protected: + virtual void SetUp() { + shared_memory_.reset(new SharedMemory); + shared_memory_->Create(std::wstring(), false, false, kRingBufferSize); + shared_memory_->Map(kRingBufferSize); + buffer_ = static_cast(shared_memory_->memory()); + + memset(buffer_, 0, kRingBufferSize); + + // Don't mock PluginThreadAsyncCall. Have it schedule the task. + ON_CALL(mock_browser_, PluginThreadAsyncCall(_, _, _)) + .WillByDefault(Invoke(&mock_browser_, + &MockNPBrowser::ConcretePluginThreadAsyncCall)); + + command_buffer_ = NPCreateObject(NULL); + ON_CALL(*command_buffer_.Get(), GetRingBuffer()) + .WillByDefault(Return(shared_memory_.get())); + ON_CALL(*command_buffer_.Get(), GetSize()) + .WillByDefault(Return(kRingBufferEntries)); + +#if defined(OS_WIN) + gapi_ = new GPUProcessor::GPUGAPIInterface; +#endif + + async_api_.reset(new StrictMock); + + decoder_ = new command_buffer::o3d::GAPIDecoder(gapi_); + + parser_ = new command_buffer::CommandParser(buffer_, + kRingBufferEntries, + 0, + kRingBufferEntries, + 0, + async_api_.get()); + + processor_ = new GPUProcessor(NULL, + command_buffer_.Get(), + gapi_, + decoder_, + parser_, + 2); + } + + virtual void TearDown() { + // Ensure that any unexpected tasks posted by the GPU processor are executed + // in order to fail the test. + MessageLoop::current()->RunAllPending(); + } + + base::AtExitManager at_exit_manager; + MessageLoop message_loop; + MockNPBrowser mock_browser_; + NPObjectPointer command_buffer_; + scoped_ptr shared_memory_; + int32* buffer_; + command_buffer::o3d::GAPIDecoder* decoder_; + command_buffer::CommandParser* parser_; + scoped_ptr async_api_; + scoped_refptr processor_; + +#if defined(OS_WIN) + GPUProcessor::GPUGAPIInterface* gapi_; +#endif +}; + +TEST_F(GPUProcessorTest, ProcessorDoesNothingIfRingBufferIsEmpty) { + EXPECT_CALL(*command_buffer_, GetPutOffset()) + .WillOnce(Return(0)); + EXPECT_CALL(*command_buffer_, SetGetOffset(0)); + + processor_->ProcessCommands(); + + EXPECT_EQ(command_buffer::parse_error::kParseNoError, + command_buffer_->ResetParseError()); + EXPECT_FALSE(command_buffer_->GetErrorStatus()); +} + +TEST_F(GPUProcessorTest, ProcessesOneCommand) { + command_buffer::CommandHeader* header = + reinterpret_cast(&buffer_[0]); + header[0].command = 7; + header[0].size = 2; + buffer_[1] = 123; + + EXPECT_CALL(*command_buffer_, GetPutOffset()) + .WillOnce(Return(2)); + EXPECT_CALL(*command_buffer_, SetGetOffset(2)); + + EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0])) + .WillOnce(Return(command_buffer::parse_error::kParseNoError)); + + processor_->ProcessCommands(); + + EXPECT_EQ(command_buffer::parse_error::kParseNoError, + command_buffer_->ResetParseError()); + EXPECT_FALSE(command_buffer_->GetErrorStatus()); +} + +TEST_F(GPUProcessorTest, ProcessesTwoCommands) { + command_buffer::CommandHeader* header = + reinterpret_cast(&buffer_[0]); + header[0].command = 7; + header[0].size = 2; + buffer_[1] = 123; + header[2].command = 8; + header[2].size = 1; + + EXPECT_CALL(*command_buffer_, GetPutOffset()) + .WillOnce(Return(3)); + EXPECT_CALL(*command_buffer_, SetGetOffset(3)); + + EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0])) + .WillOnce(Return(command_buffer::parse_error::kParseNoError)); + + EXPECT_CALL(*async_api_, DoCommand(8, 0, &buffer_[2])) + .WillOnce(Return(command_buffer::parse_error::kParseNoError)); + + processor_->ProcessCommands(); +} + +TEST_F(GPUProcessorTest, PostsTaskToFinishRemainingCommands) { + command_buffer::CommandHeader* header = + reinterpret_cast(&buffer_[0]); + header[0].command = 7; + header[0].size = 2; + buffer_[1] = 123; + header[2].command = 8; + header[2].size = 1; + header[3].command = 9; + header[3].size = 1; + + EXPECT_CALL(*command_buffer_, GetPutOffset()) + .WillOnce(Return(4)); + + EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0])) + .WillOnce(Return(command_buffer::parse_error::kParseNoError)); + + EXPECT_CALL(*async_api_, DoCommand(8, 0, &buffer_[2])) + .WillOnce(Return(command_buffer::parse_error::kParseNoError)); + + EXPECT_CALL(*command_buffer_, SetGetOffset(3)); + + processor_->ProcessCommands(); + + // ProcessCommands is called a second time when the pending task is run. + + EXPECT_CALL(*command_buffer_, GetPutOffset()) + .WillOnce(Return(4)); + + EXPECT_CALL(*async_api_, DoCommand(9, 0, &buffer_[3])) + .WillOnce(Return(command_buffer::parse_error::kParseNoError)); + + EXPECT_CALL(*command_buffer_, SetGetOffset(4)); + + MessageLoop::current()->RunAllPending(); +} + +TEST_F(GPUProcessorTest, SetsErrorCodeOnCommandBuffer) { + command_buffer::CommandHeader* header = + reinterpret_cast(&buffer_[0]); + header[0].command = 7; + header[0].size = 1; + + EXPECT_CALL(*command_buffer_, GetPutOffset()) + .WillOnce(Return(1)); + EXPECT_CALL(*command_buffer_, SetGetOffset(1)); + + EXPECT_CALL(*async_api_, DoCommand(7, 0, &buffer_[0])) + .WillOnce(Return( + command_buffer::parse_error::kParseUnknownCommand)); + + processor_->ProcessCommands(); + + EXPECT_EQ(command_buffer::parse_error::kParseUnknownCommand, + command_buffer_->ResetParseError()); + EXPECT_FALSE(command_buffer_->GetErrorStatus()); +} + +TEST_F(GPUProcessorTest, + RecoverableParseErrorsAreNotClearedByFollowingSuccessfulCommands) { + command_buffer::CommandHeader* header = + reinterpret_cast(&buffer_[0]); + header[0].command = 7; + header[0].size = 1; + header[1].command = 8; + header[1].size = 1; + + EXPECT_CALL(*command_buffer_, GetPutOffset()) + .WillOnce(Return(2)); + EXPECT_CALL(*command_buffer_, SetGetOffset(2)); + + EXPECT_CALL(*async_api_, DoCommand(7, 0, &buffer_[0])) + .WillOnce(Return( + command_buffer::parse_error::kParseUnknownCommand)); + + EXPECT_CALL(*async_api_, DoCommand(8, 0, &buffer_[1])) + .WillOnce(Return(command_buffer::parse_error::kParseNoError)); + + processor_->ProcessCommands(); + + EXPECT_EQ(command_buffer::parse_error::kParseUnknownCommand, + command_buffer_->ResetParseError()); + EXPECT_FALSE(command_buffer_->GetErrorStatus()); +} + +TEST_F(GPUProcessorTest, UnrecoverableParseErrorsRaiseTheErrorStatus) { + command_buffer::CommandHeader* header = + reinterpret_cast(&buffer_[0]); + header[0].command = 7; + header[0].size = 1; + header[1].command = 8; + header[1].size = 1; + + EXPECT_CALL(*command_buffer_, GetPutOffset()) + .WillOnce(Return(2)); + + EXPECT_CALL(*async_api_, DoCommand(7, 0, &buffer_[0])) + .WillOnce(Return(command_buffer::parse_error::kParseInvalidSize)); + + processor_->ProcessCommands(); + + EXPECT_EQ(command_buffer::parse_error::kParseInvalidSize, + command_buffer_->ResetParseError()); + EXPECT_TRUE(command_buffer_->GetErrorStatus()); +} + +TEST_F(GPUProcessorTest, ProcessCommandsDoesNothingAfterUnrecoverableError) { + command_buffer::CommandHeader* header = + reinterpret_cast(&buffer_[0]); + header[0].command = 7; + header[0].size = 1; + header[1].command = 8; + header[1].size = 1; + + EXPECT_CALL(*command_buffer_, GetPutOffset()) + .WillOnce(Return(2)); + + EXPECT_CALL(*async_api_, DoCommand(7, 0, &buffer_[0])) + .WillOnce(Return(command_buffer::parse_error::kParseInvalidSize)); + + processor_->ProcessCommands(); + processor_->ProcessCommands(); + + EXPECT_EQ(command_buffer::parse_error::kParseInvalidSize, + command_buffer_->ResetParseError()); + EXPECT_TRUE(command_buffer_->GetErrorStatus()); +} + +TEST_F(GPUProcessorTest, CanGetAddressOfSharedMemory) { + EXPECT_CALL(*command_buffer_.Get(), GetTransferBuffer(7)) + .WillOnce(Return(shared_memory_.get())); + + EXPECT_EQ(&buffer_[0], processor_->GetSharedMemoryAddress(7)); +} + +ACTION_P2(SetPointee, address, value) { + *address = value; +} + +TEST_F(GPUProcessorTest, GetAddressOfSharedMemoryMapsMemoryIfUnmapped) { + EXPECT_CALL(*command_buffer_.Get(), GetTransferBuffer(7)) + .WillOnce(Return(shared_memory_.get())); + + EXPECT_EQ(&buffer_[0], processor_->GetSharedMemoryAddress(7)); +} + +TEST_F(GPUProcessorTest, CanGetSizeOfSharedMemory) { + EXPECT_CALL(*command_buffer_.Get(), GetTransferBuffer(7)) + .WillOnce(Return(shared_memory_.get())); + + EXPECT_EQ(kRingBufferSize, processor_->GetSharedMemorySize(7)); +} + +TEST_F(GPUProcessorTest, SetTokenForwardsToCommandBuffer) { + processor_->set_token(7); + EXPECT_EQ(7, command_buffer_->GetToken()); +} + +} // namespace gpu_plugin \ No newline at end of file diff --git a/o3d/gpu_plugin/gpu_processor_win.cc b/o3d/gpu_plugin/gpu_processor_win.cc new file mode 100644 index 0000000..21a1c4a --- /dev/null +++ b/o3d/gpu_plugin/gpu_processor_win.cc @@ -0,0 +1,85 @@ +// Copyright (c) 2006-2008 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. + +#include + +#include "o3d/gpu_plugin/gpu_processor.h" + +using ::base::SharedMemory; + +namespace gpu_plugin { + +GPUProcessor::GPUProcessor(NPP npp, + CommandBuffer* command_buffer) + : npp_(npp), + command_buffer_(command_buffer), + commands_per_update_(100) { + DCHECK(command_buffer); + gapi_.reset(new GPUGAPIInterface); + decoder_.reset(new command_buffer::o3d::GAPIDecoder(gapi_.get())); + decoder_->set_engine(this); +} + +GPUProcessor::GPUProcessor(NPP npp, + CommandBuffer* command_buffer, + GPUGAPIInterface* gapi, + command_buffer::o3d::GAPIDecoder* decoder, + command_buffer::CommandParser* parser, + int commands_per_update) + : npp_(npp), + command_buffer_(command_buffer), + commands_per_update_(commands_per_update) { + DCHECK(command_buffer); + gapi_.reset(gapi); + decoder_.reset(decoder); + parser_.reset(parser); +} + +bool GPUProcessor::Initialize(HWND handle) { + DCHECK(handle); + + // Cannot reinitialize. + if (gapi_->hwnd() != NULL) + return false; + + // Map the ring buffer and create the parser. + SharedMemory* ring_buffer = command_buffer_->GetRingBuffer(); + if (ring_buffer) { + size_t size = ring_buffer->max_size(); + if (!ring_buffer->Map(size)) { + return false; + } + + void* ptr = ring_buffer->memory(); + parser_.reset(new command_buffer::CommandParser(ptr, size, 0, size, 0, + decoder_.get())); + } else { + parser_.reset(new command_buffer::CommandParser(NULL, 0, 0, 0, 0, + decoder_.get())); + } + + // Initialize GAPI immediately if the window handle is valid. + gapi_->set_hwnd(handle); + return gapi_->Initialize(); +} + +void GPUProcessor::Destroy() { + // Destroy GAPI if window handle has not already become invalid. + if (gapi_->hwnd()) { + gapi_->Destroy(); + gapi_->set_hwnd(NULL); + } +} + +bool GPUProcessor::SetWindow(HWND handle, int width, int height) { + if (handle == NULL) { + // Destroy GAPI when the window handle becomes invalid. + Destroy(); + return true; + } else { + return Initialize(handle); + } +} + +} // namespace gpu_plugin diff --git a/o3d/gpu_plugin/np_utils/default_np_object.h b/o3d/gpu_plugin/np_utils/default_np_object.h new file mode 100644 index 0000000..388a043 --- /dev/null +++ b/o3d/gpu_plugin/np_utils/default_np_object.h @@ -0,0 +1,84 @@ +// Copyright (c) 2006-2008 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 O3D_GPU_PLUGIN_NP_UTILS_DEFAULT_NP_OBJECT_H_ +#define O3D_GPU_PLUGIN_NP_UTILS_DEFAULT_NP_OBJECT_H_ + +#include "base/basictypes.h" +#include "o3d/gpu_plugin/np_utils/np_headers.h" + +namespace gpu_plugin { + +class BaseNPDispatcher; + +// This class implements each of the functions in the NPClass interface. They +// all return error by default. Note that these are not virtual functions and +// this is not an interface. This class can be used as a mixin so that an +// NPObject class does not need to implement every NPClass function but rather +// inherits a default from DefaultNPObject. +template +class DefaultNPObject : public RootClass { + public: + void Invalidate() {} + + bool HasMethod(NPIdentifier name) { + return false; + } + + bool Invoke(NPIdentifier name, + const NPVariant* args, + uint32_t num_args, + NPVariant* result) { + return false; + } + + bool InvokeDefault(const NPVariant* args, + uint32_t num_args, + NPVariant* result) { + return false; + } + + bool HasProperty(NPIdentifier name) { + return false; + } + + bool GetProperty(NPIdentifier name, NPVariant* result) { + return false; + } + + bool SetProperty(NPIdentifier name, const NPVariant* value) { + return false; + } + + bool RemoveProperty(NPIdentifier name) { + return false; + } + + bool Enumerate(NPIdentifier** names, + uint32_t* count) { + *names = NULL; + *count = 0; + return true; + } + + bool Construct(const NPVariant* args, + uint32_t num_args, + NPVariant* result) { + return false; + } + + static BaseNPDispatcher* GetDispatcherChain() { + return NULL; + } + + protected: + DefaultNPObject() {} + virtual ~DefaultNPObject() {} + + private: + DISALLOW_COPY_AND_ASSIGN(DefaultNPObject); +}; +} // namespace gpu_plugin + +#endif // O3D_GPU_PLUGIN_NP_UTILS_DEFAULT_NP_OBJECT_H_ diff --git a/o3d/gpu_plugin/np_utils/dispatched_np_object_unittest.cc b/o3d/gpu_plugin/np_utils/dispatched_np_object_unittest.cc new file mode 100644 index 0000000..9e660da --- /dev/null +++ b/o3d/gpu_plugin/np_utils/dispatched_np_object_unittest.cc @@ -0,0 +1,403 @@ +// Copyright (c) 2006-2008 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. + +#include + +#include "o3d/gpu_plugin/np_utils/default_np_object.h" +#include "o3d/gpu_plugin/np_utils/np_browser_stub.h" +#include "o3d/gpu_plugin/np_utils/np_dispatcher.h" +#include "o3d/gpu_plugin/np_utils/np_object_mock.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::Return; +using testing::StrictMock; + +namespace gpu_plugin { + +// This mock class has a dispatcher chain with an entry for each mocked +// function. The tests that follow that invoking an NPAPI method calls the +// corresponding mocked member function. +class MockDispatchedNPObject : public DefaultNPObject { + public: + explicit MockDispatchedNPObject(NPP npp) { + } + + MOCK_METHOD0(VoidReturnNoParams, void()); + MOCK_METHOD1(VoidReturnBoolParam, void(bool)); + MOCK_METHOD1(VoidReturnIntParam, void(int)); + MOCK_METHOD1(VoidReturnFloatParam, void(float)); + MOCK_METHOD1(VoidReturnDoubleParam, void(double)); + MOCK_METHOD1(VoidReturnStringParam, void(std::string)); + MOCK_METHOD1(VoidReturnObjectParam, void(NPObjectPointer)); + MOCK_METHOD2(VoidReturnTwoParams, void(bool, int)); + MOCK_METHOD0(Overloaded, void()); + MOCK_METHOD1(Overloaded, void(bool)); + MOCK_METHOD1(Overloaded, void(std::string)); + MOCK_METHOD0(BoolReturn, bool()); + MOCK_METHOD0(IntReturn, int()); + MOCK_METHOD0(FloatReturn, float()); + MOCK_METHOD0(DoubleReturn, double()); + MOCK_METHOD0(StringReturn, std::string()); + MOCK_METHOD0(ObjectReturn, NPObjectPointer()); + + NP_UTILS_BEGIN_DISPATCHER_CHAIN(MockDispatchedNPObject, DefaultNPObject) + NP_UTILS_DISPATCHER(VoidReturnNoParams, void()) + NP_UTILS_DISPATCHER(VoidReturnBoolParam, void(bool)) + NP_UTILS_DISPATCHER(VoidReturnIntParam, void(int)) + NP_UTILS_DISPATCHER(VoidReturnFloatParam, void(float)) + NP_UTILS_DISPATCHER(VoidReturnDoubleParam, void(double)) + NP_UTILS_DISPATCHER(VoidReturnStringParam, void(std::string)) + NP_UTILS_DISPATCHER(VoidReturnObjectParam, void(NPObjectPointer)) + NP_UTILS_DISPATCHER(VoidReturnTwoParams, void(bool, int)) + NP_UTILS_DISPATCHER(Overloaded, void()) + NP_UTILS_DISPATCHER(Overloaded, void(bool)) + NP_UTILS_DISPATCHER(Overloaded, void(std::string)) + NP_UTILS_DISPATCHER(BoolReturn, bool()) + NP_UTILS_DISPATCHER(IntReturn, int()) + NP_UTILS_DISPATCHER(FloatReturn, float()) + NP_UTILS_DISPATCHER(DoubleReturn, double()) + NP_UTILS_DISPATCHER(StringReturn, std::string()) + NP_UTILS_DISPATCHER(ObjectReturn, NPObjectPointer()); + NP_UTILS_END_DISPATCHER_CHAIN +}; + +class DispatchedNPObjectTest : public testing::Test { + protected: + virtual void SetUp() { + object_ = NPCreateObject >(NULL); + passed_object_ = NPCreateObject(NULL); + + for (int i = 0; i != arraysize(args_); ++i) { + NULL_TO_NPVARIANT(args_[i]); + } + NULL_TO_NPVARIANT(result_); + } + + StubNPBrowser stub_browser_; + NPVariant args_[3]; + NPVariant result_; + NPObjectPointer object_; + NPObjectPointer passed_object_; +}; + +TEST_F(DispatchedNPObjectTest, CannotInvokeMissingFunction) { + EXPECT_FALSE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("missing"), + NULL, + 0, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnNoParams) { + EXPECT_CALL(*object_, VoidReturnNoParams()); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("voidReturnNoParams"), + NULL, + 0, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, + CannotInvokeVoidReturnNoParamsWithTooManyParams) { + EXPECT_FALSE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("voidReturnNoParams"), + args_, + 1, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnIntParam) { + EXPECT_CALL(*object_, VoidReturnIntParam(7)); + + INT32_TO_NPVARIANT(7, args_[0]); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("voidReturnIntParam"), + args_, + 1, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnBoolParam) { + EXPECT_CALL(*object_, VoidReturnBoolParam(true)); + + BOOLEAN_TO_NPVARIANT(true, args_[0]); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("voidReturnBoolParam"), + args_, + 1, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnFloatParamWithDoubleParam) { + EXPECT_CALL(*object_, VoidReturnFloatParam(7.0f)); + + DOUBLE_TO_NPVARIANT(7.0, args_[0]); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("voidReturnFloatParam"), + args_, + 1, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnFloatParamWithIntParam) { + EXPECT_CALL(*object_, VoidReturnFloatParam(7.0f)); + + INT32_TO_NPVARIANT(7, args_[0]); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("voidReturnFloatParam"), + args_, + 1, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnDoubleParamWithDoubleParam) { + EXPECT_CALL(*object_, VoidReturnDoubleParam(7.0)); + + DOUBLE_TO_NPVARIANT(7.0, args_[0]); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("voidReturnDoubleParam"), + args_, + 1, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnDoubleParamWithIntParam) { + EXPECT_CALL(*object_, VoidReturnDoubleParam(7.0f)); + + INT32_TO_NPVARIANT(7, args_[0]); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("voidReturnDoubleParam"), + args_, + 1, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnStringParam) { + EXPECT_CALL(*object_, VoidReturnStringParam(std::string("hello"))); + + STRINGZ_TO_NPVARIANT("hello", args_[0]); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("voidReturnStringParam"), + args_, + 1, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnObjectParamWithObject) { + EXPECT_CALL(*object_, VoidReturnObjectParam(passed_object_)); + + OBJECT_TO_NPVARIANT(passed_object_.Get(), args_[0]); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("voidReturnObjectParam"), + args_, + 1, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnObjectParamWithNull) { + EXPECT_CALL( + *object_, + VoidReturnObjectParam(NPObjectPointer())); + + NULL_TO_NPVARIANT(args_[0]); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("voidReturnObjectParam"), + args_, + 1, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnTwoParams) { + EXPECT_CALL(*object_, VoidReturnTwoParams(false, 7)); + + BOOLEAN_TO_NPVARIANT(false, args_[0]); + INT32_TO_NPVARIANT(7, args_[1]); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("voidReturnTwoParams"), + args_, + 2, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeOverloadedWithNoParams) { + EXPECT_CALL(*object_, Overloaded()); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("overloaded"), + NULL, + 0, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeOverloadedWithOneStringParam) { + EXPECT_CALL(*object_, Overloaded(std::string("hello"))); + + STRINGZ_TO_NPVARIANT("hello", args_[0]); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("overloaded"), + args_, + 1, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeOverloadedWithOneBoolParam) { + EXPECT_CALL(*object_, Overloaded(true)); + + BOOLEAN_TO_NPVARIANT(true, args_[0]); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("overloaded"), + args_, + 1, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeBoolReturn) { + EXPECT_CALL(*object_, BoolReturn()).WillOnce(Return(true)); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("boolReturn"), + NULL, + 0, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_BOOLEAN(result_)); + EXPECT_TRUE(NPVARIANT_TO_BOOLEAN(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeIntReturn) { + EXPECT_CALL(*object_, IntReturn()).WillOnce(Return(7)); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("intReturn"), + NULL, + 0, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_INT32(result_)); + EXPECT_EQ(7, NPVARIANT_TO_INT32(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeFloatReturn) { + EXPECT_CALL(*object_, FloatReturn()).WillOnce(Return(7.0f)); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("floatReturn"), + NULL, + 0, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_DOUBLE(result_)); + EXPECT_EQ(7.0, NPVARIANT_TO_DOUBLE(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeDoubleReturn) { + EXPECT_CALL(*object_, DoubleReturn()).WillOnce(Return(7.0)); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("doubleReturn"), + NULL, + 0, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_DOUBLE(result_)); + EXPECT_EQ(7.0, NPVARIANT_TO_DOUBLE(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeStringReturn) { + EXPECT_CALL(*object_, StringReturn()).WillOnce(Return(std::string("hello"))); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("stringReturn"), + NULL, + 0, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_STRING(result_)); + + NPString& str = NPVARIANT_TO_STRING(result_); + EXPECT_EQ(std::string("hello"), + std::string(str.UTF8Characters, str.UTF8Length)); + + // Callee is responsible for releasing string. + NPBrowser::get()->ReleaseVariantValue(&result_); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeObjectReturnWithObject) { + EXPECT_CALL(*object_, ObjectReturn()).WillOnce(Return(passed_object_)); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("objectReturn"), + NULL, + 0, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_OBJECT(result_)); + EXPECT_EQ(passed_object_.Get(), NPVARIANT_TO_OBJECT(result_)); + + NPBrowser::get()->ReleaseVariantValue(&result_); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeObjectReturnWithNull) { + EXPECT_CALL(*object_, ObjectReturn()) + .WillOnce(Return(NPObjectPointer())); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("objectReturn"), + NULL, + 0, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_NULL(result_)); +} + +TEST_F(DispatchedNPObjectTest, HasMethodReturnsTrueIfMatchingMemberVariable) { + EXPECT_TRUE(object_->HasMethod( + NPBrowser::get()->GetStringIdentifier("objectReturn"))); +} + +TEST_F(DispatchedNPObjectTest, HasMethodReturnsTrueIfNoMatchingMemberVariable) { + EXPECT_FALSE(object_->HasMethod( + NPBrowser::get()->GetStringIdentifier("missing"))); +} + +TEST_F(DispatchedNPObjectTest, EnumeratesAllAvailableMethods) { + NPIdentifier* names; + uint32_t num_names; + ASSERT_TRUE(object_->Enumerate(&names, &num_names)); + + // Don't compare all of them; this test would need to change every time new + // dispatchers were added to the test NPObject class. Just compare the first + // registered (last in the dispatcher chain) and that more than one is + // returned. + EXPECT_GT(num_names, 1u); + EXPECT_EQ(NPBrowser::get()->GetStringIdentifier("voidReturnNoParams"), + names[num_names - 1]); + + NPBrowser::get()->MemFree(names); +} + +} // namespace gpu_plugin diff --git a/o3d/gpu_plugin/np_utils/dynamic_np_object.cc b/o3d/gpu_plugin/np_utils/dynamic_np_object.cc new file mode 100644 index 0000000..6c5a309 --- /dev/null +++ b/o3d/gpu_plugin/np_utils/dynamic_np_object.cc @@ -0,0 +1,59 @@ +// Copyright (c) 2006-2008 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. + +#include "o3d/gpu_plugin/np_utils/dynamic_np_object.h" + +namespace gpu_plugin { + +DynamicNPObject::DynamicNPObject(NPP npp) { +} + +void DynamicNPObject::Invalidate() { + for (PropertyMap::iterator it = properties_.begin(); + it != properties_.end(); + ++it) { + it->second.Invalidate(); + } +} + +bool DynamicNPObject::HasProperty(NPIdentifier name) { + PropertyMap::iterator it = properties_.find(name); + return it != properties_.end(); +} + +bool DynamicNPObject::GetProperty(NPIdentifier name, NPVariant* result) { + PropertyMap::iterator it = properties_.find(name); + if (it == properties_.end()) + return false; + + it->second.CopyTo(result); + return true; +} + +bool DynamicNPObject::SetProperty(NPIdentifier name, const NPVariant* value) { + properties_[name] = *value; + return true; +} + +bool DynamicNPObject::RemoveProperty(NPIdentifier name) { + properties_.erase(name); + return false; +} + +bool DynamicNPObject::Enumerate(NPIdentifier** names, uint32_t* count) { + *names = static_cast( + NPBrowser::get()->MemAlloc(properties_.size() * sizeof(*names))); + *count = properties_.size(); + + int i = 0; + for (PropertyMap::iterator it = properties_.begin(); + it != properties_.end(); + ++it) { + (*names)[i] = it->first; + ++i; + } + + return true; +} +} // namespace gpu_plugin diff --git a/o3d/gpu_plugin/np_utils/dynamic_np_object.h b/o3d/gpu_plugin/np_utils/dynamic_np_object.h new file mode 100644 index 0000000..b80a160 --- /dev/null +++ b/o3d/gpu_plugin/np_utils/dynamic_np_object.h @@ -0,0 +1,35 @@ +// Copyright (c) 2006-2008 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 O3D_GPU_PLUGIN_NP_UTILS_DYNAMIC_NP_OBJECT_H_ +#define O3D_GPU_PLUGIN_NP_UTILS_DYNAMIC_NP_OBJECT_H_ + +#include + +#include "o3d/gpu_plugin/np_utils/default_np_object.h" +#include "o3d/gpu_plugin/np_utils/np_utils.h" + +namespace gpu_plugin { + +// NPObjects of this type have a dictionary of property name / variant pairs +// that can be changed at runtime through NPAPI. +class DynamicNPObject : public DefaultNPObject { + public: + explicit DynamicNPObject(NPP npp); + + void Invalidate(); + bool HasProperty(NPIdentifier name); + bool GetProperty(NPIdentifier name, NPVariant* result); + bool SetProperty(NPIdentifier name, const NPVariant* value); + bool RemoveProperty(NPIdentifier name); + bool Enumerate(NPIdentifier** names, uint32_t* count); + + private: + typedef std::map PropertyMap; + PropertyMap properties_; + DISALLOW_COPY_AND_ASSIGN(DynamicNPObject); +}; +} // namespace gpu_plugin + +#endif // O3D_GPU_PLUGIN_NP_UTILS_DYNAMIC_NP_OBJECT_H_ diff --git a/o3d/gpu_plugin/np_utils/dynamic_np_object_unittest.cc b/o3d/gpu_plugin/np_utils/dynamic_np_object_unittest.cc new file mode 100644 index 0000000..6a73167 --- /dev/null +++ b/o3d/gpu_plugin/np_utils/dynamic_np_object_unittest.cc @@ -0,0 +1,83 @@ +// Copyright (c) 2006-2008 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. + +#include + +#include "o3d/gpu_plugin/np_utils/dynamic_np_object.h" +#include "o3d/gpu_plugin/np_utils/np_browser_stub.h" +#include "o3d/gpu_plugin/np_utils/np_utils.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::Return; +using testing::StrictMock; + +namespace gpu_plugin { + +class NPDynamicNPObjectTest : public testing::Test { + protected: + virtual void SetUp() { + object_ = NPCreateObject(NULL); + } + + StubNPBrowser stub_browser_; + NPObjectPointer object_; +}; + +TEST_F(NPDynamicNPObjectTest, HasPropertyReturnsFalseForMissingProperty) { + EXPECT_FALSE(NPHasProperty(NULL, object_, "missing")); +} + +TEST_F(NPDynamicNPObjectTest, GetPropertyReturnsFalseForMissingProperty) { + int32 r; + EXPECT_FALSE(NPGetProperty(NULL, object_, "missing", &r)); +} + +TEST_F(NPDynamicNPObjectTest, CanSetProperty) { + EXPECT_TRUE(NPSetProperty(NULL, object_, "foo", 7)); + int32 r; + EXPECT_TRUE(NPHasProperty(NULL, object_, "foo")); + EXPECT_TRUE(NPGetProperty(NULL, object_, "foo", &r)); + EXPECT_EQ(7, r); +} + +TEST_F(NPDynamicNPObjectTest, CanRemoveProperty) { + EXPECT_TRUE(NPSetProperty(NULL, object_, "foo", 7)); + EXPECT_TRUE(NPHasProperty(NULL, object_, "foo")); + EXPECT_FALSE(NPRemoveProperty(NULL, object_, "foo")); + EXPECT_FALSE(NPHasProperty(NULL, object_, "foo")); + int32 r; + EXPECT_FALSE(NPGetProperty(NULL, object_, "foo", &r)); +} + +TEST_F(NPDynamicNPObjectTest, CanEnumerateProperties) { + EXPECT_TRUE(NPSetProperty(NULL, object_, "foo", 7)); + + NPIdentifier* names; + uint32 num_names; + EXPECT_TRUE(object_->_class->enumerate(object_.Get(), &names, &num_names)); + + EXPECT_EQ(1, num_names); + EXPECT_EQ(NPBrowser::get()->GetStringIdentifier("foo"), names[0]); + + NPBrowser::get()->MemFree(names); +} + +// Properties should not be +TEST_F(NPDynamicNPObjectTest, InvalidateNullsObjectProperties) { + EXPECT_EQ(1, object_->referenceCount); + { + EXPECT_TRUE(NPSetProperty(NULL, object_, "foo", object_)); + EXPECT_TRUE(NPHasProperty(NULL, object_, "foo")); + object_->_class->invalidate(object_.Get()); + EXPECT_TRUE(NPHasProperty(NULL, object_, "foo")); + NPObjectPointer r; + EXPECT_TRUE(NPGetProperty(NULL, object_, "foo", &r)); + EXPECT_TRUE(NULL == r.Get()); + } + // Invalidate did not release object + EXPECT_EQ(2, object_->referenceCount); + NPBrowser::get()->ReleaseObject(object_.Get()); +} +} // namespace gpu_plugin diff --git a/o3d/gpu_plugin/np_utils/np_browser.cc b/o3d/gpu_plugin/np_utils/np_browser.cc new file mode 100644 index 0000000..3fc9185 --- /dev/null +++ b/o3d/gpu_plugin/np_utils/np_browser.cc @@ -0,0 +1,128 @@ +// Copyright (c) 2006-2008 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. + +#include "o3d/gpu_plugin/np_utils/np_browser.h" +#include "base/logging.h" + +#if defined(O3D_IN_CHROME) +#include "webkit/glue/plugins/nphostapi.h" +#else +#include "o3d/third_party/npapi/include/npfunctions.h" +#endif + +namespace gpu_plugin { + +NPBrowser* NPBrowser::browser_; + +NPBrowser::NPBrowser(NPNetscapeFuncs* funcs) + : netscape_funcs_(funcs) { + // Make this the first browser in the linked list. + previous_browser_ = browser_; + browser_ = this; +} + +NPBrowser::~NPBrowser() { + // Remove this browser from the linked list. + DCHECK(browser_ == this); + browser_ = previous_browser_; +} + +NPIdentifier NPBrowser::GetStringIdentifier(const NPUTF8* name) { + return netscape_funcs_->getstringidentifier(name); +} + +void* NPBrowser::MemAlloc(size_t size) { + return netscape_funcs_->memalloc(size); +} + +void NPBrowser::MemFree(void* p) { + netscape_funcs_->memfree(p); +} + +NPObject* NPBrowser::CreateObject(NPP npp, const NPClass* cl) { + return netscape_funcs_->createobject(npp, const_cast(cl)); +} + +NPObject* NPBrowser::RetainObject(NPObject* object) { + return netscape_funcs_->retainobject(object); +} + +void NPBrowser::ReleaseObject(NPObject* object) { + netscape_funcs_->releaseobject(object); +} + +void NPBrowser::ReleaseVariantValue(NPVariant* variant) { + netscape_funcs_->releasevariantvalue(variant); +} + +bool NPBrowser::HasProperty(NPP npp, + NPObject* object, + NPIdentifier name) { + return netscape_funcs_->hasproperty(npp, object, name); +} + +bool NPBrowser::GetProperty(NPP npp, + NPObject* object, + NPIdentifier name, + NPVariant* result) { + return netscape_funcs_->getproperty(npp, object, name, result); +} + +bool NPBrowser::SetProperty(NPP npp, + NPObject* object, + NPIdentifier name, + const NPVariant* result) { + return netscape_funcs_->setproperty(npp, object, name, result); +} + +bool NPBrowser::RemoveProperty(NPP npp, + NPObject* object, + NPIdentifier name) { + return netscape_funcs_->removeproperty(npp, object, name); +} + +bool NPBrowser::HasMethod(NPP npp, + NPObject* object, + NPIdentifier name) { + return netscape_funcs_->hasmethod(npp, object, name); +} + +bool NPBrowser::Invoke(NPP npp, + NPObject* object, + NPIdentifier name, + const NPVariant* args, + uint32_t num_args, + NPVariant* result) { + return netscape_funcs_->invoke(npp, object, name, args, num_args, result); +} + +NPObject* NPBrowser::GetWindowNPObject(NPP npp) { + NPObject* window; + if (NPERR_NO_ERROR == netscape_funcs_->getvalue(npp, + NPNVWindowNPObject, + &window)) { + return window; + } else { + return NULL; + } +} + +void NPBrowser::PluginThreadAsyncCall(NPP npp, + PluginThreadAsyncCallProc callback, + void* data) { + netscape_funcs_->pluginthreadasynccall(npp, callback, data); +} + +uint32 NPBrowser::ScheduleTimer(NPP npp, + uint32 interval, + bool repeat, + TimerProc callback) { + return netscape_funcs_->scheduletimer(npp, interval, repeat, callback); +} + +void NPBrowser::UnscheduleTimer(NPP npp, uint32 timer_id) { + netscape_funcs_->unscheduletimer(npp, timer_id); +} + +} // namespace gpu_plugin diff --git a/o3d/gpu_plugin/np_utils/np_browser.h b/o3d/gpu_plugin/np_utils/np_browser.h new file mode 100644 index 0000000..5e71aac --- /dev/null +++ b/o3d/gpu_plugin/np_utils/np_browser.h @@ -0,0 +1,95 @@ +// Copyright (c) 2006-2008 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 O3D_GPU_PLUGIN_NP_UTILS_NP_BROWSER_H_ +#define O3D_GPU_PLUGIN_NP_UTILS_NP_BROWSER_H_ + +#include "base/basictypes.h" +#include "o3d/gpu_plugin/np_utils/np_headers.h" + +typedef struct _NPNetscapeFuncs NPNetscapeFuncs; + +namespace gpu_plugin { + +// This class exposes the functions provided by the browser to a plugin (the +// ones prefixed NPN_). +class NPBrowser { + public: + explicit NPBrowser(NPNetscapeFuncs* funcs); + virtual ~NPBrowser(); + + static NPBrowser* get() { + return browser_; + } + + // Standard functions from NPNetscapeFuncs. + + virtual NPIdentifier GetStringIdentifier(const NPUTF8* name); + + virtual void* MemAlloc(size_t size); + + virtual void MemFree(void* p); + + virtual NPObject* CreateObject(NPP npp, const NPClass* cl); + + virtual NPObject* RetainObject(NPObject* object); + + virtual void ReleaseObject(NPObject* object); + + virtual void ReleaseVariantValue(NPVariant* variant); + + virtual bool HasProperty(NPP npp, + NPObject* object, + NPIdentifier name); + + virtual bool GetProperty(NPP npp, + NPObject* object, + NPIdentifier name, + NPVariant* result); + + virtual bool SetProperty(NPP npp, + NPObject* object, + NPIdentifier name, + const NPVariant* result); + + virtual bool RemoveProperty(NPP npp, + NPObject* object, + NPIdentifier name); + + virtual bool HasMethod(NPP npp, + NPObject* object, + NPIdentifier name); + + virtual bool Invoke(NPP npp, + NPObject* object, + NPIdentifier name, + const NPVariant* args, + uint32_t num_args, + NPVariant* result); + + virtual NPObject* GetWindowNPObject(NPP npp); + + typedef void (*PluginThreadAsyncCallProc)(void* data); + virtual void PluginThreadAsyncCall(NPP npp, + PluginThreadAsyncCallProc callback, + void* data); + + typedef void (*TimerProc)(NPP npp, uint32 timer_id); + virtual uint32 ScheduleTimer(NPP npp, + uint32 interval, + bool repeat, + TimerProc callback); + + virtual void UnscheduleTimer(NPP npp, uint32 timer_id); + + private: + static NPBrowser* browser_; + NPBrowser* previous_browser_; + NPNetscapeFuncs* netscape_funcs_; + DISALLOW_COPY_AND_ASSIGN(NPBrowser); +}; + +} // namespace gpu_plugin + +#endif // O3D_GPU_PLUGIN_NP_UTILS_NP_BROWSER_H_ diff --git a/o3d/gpu_plugin/np_utils/np_browser_mock.h b/o3d/gpu_plugin/np_utils/np_browser_mock.h new file mode 100644 index 0000000..9175e42 --- /dev/null +++ b/o3d/gpu_plugin/np_utils/np_browser_mock.h @@ -0,0 +1,50 @@ +// Copyright (c) 2006-2008 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 O3D_GPU_PLUGIN_NP_UTILS_NP_BROWSER_MOCK_H_ +#define O3D_GPU_PLUGIN_NP_UTILS_NP_BROWSER_MOCK_H_ + +#include "o3d/gpu_plugin/np_utils/np_browser_stub.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace gpu_plugin { + +// This mocks certain member functions of the stub browser. Those relating +// to identifiers, memory management, reference counting and forwarding to +// NPObjects are deliberately not mocked so the mock browser can be used as +// normal for these calls. +class MockNPBrowser : public StubNPBrowser { + public: + NPObject* ConcreteCreateObject(NPP npp, const NPClass* cl) { + return StubNPBrowser::CreateObject(npp, cl); + } + + MockNPBrowser() { + // Do not mock CreateObject by default but allow it to be mocked so object + // creation can be intercepted. + ON_CALL(*this, CreateObject(testing::_, testing::_)) + .WillByDefault(testing::Invoke(this, + &MockNPBrowser::ConcreteCreateObject)); + } + + void ConcretePluginThreadAsyncCall(NPP npp, + PluginThreadAsyncCallProc callback, + void* data) { + return StubNPBrowser::PluginThreadAsyncCall(npp, callback, data); + } + + MOCK_METHOD2(CreateObject, NPObject*(NPP npp, const NPClass* cl)); + MOCK_METHOD1(GetWindowNPObject, NPObject*(NPP cpp)); + MOCK_METHOD3(PluginThreadAsyncCall, + void(NPP npp, PluginThreadAsyncCallProc callback, void* data)); + MOCK_METHOD4(ScheduleTimer, uint32(NPP npp, + uint32 interval, + bool repeat, + TimerProc callback)); + MOCK_METHOD2(UnscheduleTimer, void(NPP npp, uint32 timer_id)); +}; + +} // namespace gpu_plugin + +#endif // O3D_GPU_PLUGIN_NP_UTILS_NP_BROWSER_MOCK_H_ diff --git a/o3d/gpu_plugin/np_utils/np_browser_stub.cc b/o3d/gpu_plugin/np_utils/np_browser_stub.cc new file mode 100644 index 0000000..f20bbda --- /dev/null +++ b/o3d/gpu_plugin/np_utils/np_browser_stub.cc @@ -0,0 +1,125 @@ +// Copyright (c) 2006-2008 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. + +#include "o3d/gpu_plugin/np_utils/np_browser_stub.h" +#include "base/logging.h" +#include "base/message_loop.h" + +namespace gpu_plugin { + +StubNPBrowser::StubNPBrowser() : NPBrowser(NULL) { +} + +StubNPBrowser::~StubNPBrowser() { +} + +NPIdentifier StubNPBrowser::GetStringIdentifier(const NPUTF8* name) { + static std::set names; + std::set::iterator it = names.find(name); + if (it == names.end()) { + it = names.insert(name).first; + } + return const_cast((*it).c_str()); +} + +void* StubNPBrowser::MemAlloc(size_t size) { + return malloc(size); +} + +void StubNPBrowser::MemFree(void* p) { + free(p); +} + +NPObject* StubNPBrowser::CreateObject(NPP npp, const NPClass* cl) { + NPObject* object = cl->allocate(npp, const_cast(cl)); + object->referenceCount = 1; + object->_class = const_cast(cl); + return object; +} + +NPObject* StubNPBrowser::RetainObject(NPObject* object) { + ++object->referenceCount; + return object; +} + +void StubNPBrowser::ReleaseObject(NPObject* object) { + DCHECK_GE(object->referenceCount, 0u); + --object->referenceCount; + if (object->referenceCount == 0) { + object->_class->deallocate(object); + } +} + +void StubNPBrowser::ReleaseVariantValue(NPVariant* variant) { + if (NPVARIANT_IS_STRING(*variant)) { + MemFree(const_cast(variant->value.stringValue.UTF8Characters)); + } else if (NPVARIANT_IS_OBJECT(*variant)) { + ReleaseObject(NPVARIANT_TO_OBJECT(*variant)); + } +} + +bool StubNPBrowser::HasProperty(NPP npp, + NPObject* object, + NPIdentifier name) { + return object->_class->hasProperty(object, name); +} + +bool StubNPBrowser::GetProperty(NPP npp, + NPObject* object, + NPIdentifier name, + NPVariant* result) { + return object->_class->getProperty(object, name, result); +} + +bool StubNPBrowser::SetProperty(NPP npp, + NPObject* object, + NPIdentifier name, + const NPVariant* result) { + return object->_class->setProperty(object, name, result); +} + +bool StubNPBrowser::RemoveProperty(NPP npp, + NPObject* object, + NPIdentifier name) { + return object->_class->removeProperty(object, name); +} + +bool StubNPBrowser::HasMethod(NPP npp, + NPObject* object, + NPIdentifier name) { + return object->_class->hasMethod(object, name); +} + +bool StubNPBrowser::Invoke(NPP npp, + NPObject* object, + NPIdentifier name, + const NPVariant* args, + uint32_t num_args, + NPVariant* result) { + return object->_class->invoke(object, name, args, num_args, result); +} + +NPObject* StubNPBrowser::GetWindowNPObject(NPP npp) { + return NULL; +} + +void StubNPBrowser::PluginThreadAsyncCall( + NPP npp, + PluginThreadAsyncCallProc callback, + void* data) { + MessageLoop::current()->PostTask(FROM_HERE, + NewRunnableFunction(callback, data)); +} + +uint32 StubNPBrowser::ScheduleTimer(NPP npp, + uint32 interval, + bool repeat, + TimerProc callback) { + return 0; +} + +void StubNPBrowser::UnscheduleTimer(NPP npp, uint32 timer_id) { +} + +} // namespace gpu_plugin diff --git a/o3d/gpu_plugin/np_utils/np_browser_stub.h b/o3d/gpu_plugin/np_utils/np_browser_stub.h new file mode 100644 index 0000000..0740244 --- /dev/null +++ b/o3d/gpu_plugin/np_utils/np_browser_stub.h @@ -0,0 +1,84 @@ +// Copyright (c) 2006-2008 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 O3D_GPU_PLUGIN_NP_UTILS_NP_BROWSER_STUB_H_ +#define O3D_GPU_PLUGIN_NP_UTILS_NP_BROWSER_STUB_H_ + +#include +#include + +#include "o3d/gpu_plugin/np_utils/np_browser.h" + +namespace gpu_plugin { + +// Simple implementation of subset of the NPN functions for testing. +class StubNPBrowser : public NPBrowser { + public: + StubNPBrowser(); + virtual ~StubNPBrowser(); + + // Standard functions from NPNetscapeFuncs. + + virtual NPIdentifier GetStringIdentifier(const NPUTF8* name); + + virtual void* MemAlloc(size_t size); + + virtual void MemFree(void* p); + + virtual NPObject* CreateObject(NPP npp, const NPClass* cl); + + virtual NPObject* RetainObject(NPObject* object); + + virtual void ReleaseObject(NPObject* object); + + virtual void ReleaseVariantValue(NPVariant* variant); + + virtual bool HasProperty(NPP npp, + NPObject* object, + NPIdentifier name); + + virtual bool GetProperty(NPP npp, + NPObject* object, + NPIdentifier name, + NPVariant* result); + + virtual bool SetProperty(NPP npp, + NPObject* object, + NPIdentifier name, + const NPVariant* result); + + virtual bool RemoveProperty(NPP npp, + NPObject* object, + NPIdentifier name); + + virtual bool HasMethod(NPP npp, + NPObject* object, + NPIdentifier name); + virtual bool Invoke(NPP npp, + NPObject* object, + NPIdentifier name, + const NPVariant* args, + uint32_t num_args, + NPVariant* result); + + virtual NPObject* GetWindowNPObject(NPP npp); + + virtual void PluginThreadAsyncCall(NPP npp, + PluginThreadAsyncCallProc callback, + void* data); + + virtual uint32 ScheduleTimer(NPP npp, + uint32 interval, + bool repeat, + TimerProc callback); + + virtual void UnscheduleTimer(NPP npp, uint32 timer_id); + + private: + DISALLOW_COPY_AND_ASSIGN(StubNPBrowser); +}; + +} // namespace gpu_plugin + +#endif // O3D_GPU_PLUGIN_NP_UTILS_NP_BROWSER_STUB_H_ diff --git a/o3d/gpu_plugin/np_utils/np_class.h b/o3d/gpu_plugin/np_utils/np_class.h new file mode 100644 index 0000000..a6d557e --- /dev/null +++ b/o3d/gpu_plugin/np_utils/np_class.h @@ -0,0 +1,125 @@ +// Copyright (c) 2006-2008 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 O3D_GPU_PLUGIN_NP_UTILS_NP_CLASS_H_ +#define O3D_GPU_PLUGIN_NP_UTILS_NP_CLASS_H_ + +#include "o3d/gpu_plugin/np_utils/np_object_pointer.h" +#include "o3d/gpu_plugin/np_utils/np_headers.h" + +// This file implements NPGetClass. This function returns an NPClass +// that can be used to instantiate an NPObject subclass T. The NPClass +// function pointers will invoke the most derived corresponding member +// functions in T. + +namespace gpu_plugin { + +namespace np_class_impl { + // This template version of the NPClass allocate function creates a subclass + // of BaseNPObject. + template + static NPObject* Allocate(NPP npp, NPClass*) { + return new NPObjectType(npp); + } + + // These implementations of the NPClass functions forward to the virtual + // functions in DefaultNPObject. + template + static void Deallocate(NPObject* object) { + delete static_cast(object); + } + + template + static void Invalidate(NPObject* object) { + return static_cast(object)->Invalidate(); + } + + template + static bool HasMethod(NPObject* object, NPIdentifier name) { + return static_cast(object)->HasMethod(name); + } + + template + static bool Invoke(NPObject* object, + NPIdentifier name, + const NPVariant* args, + uint32_t num_args, + NPVariant* result) { + return static_cast(object)->Invoke( + name, args, num_args, result); + } + + template + static bool InvokeDefault(NPObject* object, + const NPVariant* args, + uint32_t num_args, + NPVariant* result) { + return static_cast(object)->InvokeDefault( + args, num_args, result); + } + + template + static bool HasProperty(NPObject* object, NPIdentifier name) { + return static_cast(object)->HasProperty(name); + } + + template + static bool GetProperty(NPObject* object, + NPIdentifier name, + NPVariant* result) { + return static_cast(object)->GetProperty(name, result); + } + + template + static bool SetProperty(NPObject* object, + NPIdentifier name, + const NPVariant* value) { + return static_cast(object)->SetProperty(name, value); + } + + template + static bool RemoveProperty(NPObject* object, NPIdentifier name) { + return static_cast(object)->RemoveProperty(name); + } + + template + static bool Enumerate(NPObject* object, + NPIdentifier** names, + uint32_t* count) { + return static_cast(object)->Enumerate(names, count); + }; + + template + static bool Construct(NPObject* object, + const NPVariant* args, + uint32_t num_args, + NPVariant* result) { + return static_cast(object)->Construct( + args, num_args, result); + } +} // namespace np_class_impl; + +template +const NPClass* NPGetClass() { + static const NPClass np_class = { + NP_CLASS_STRUCT_VERSION, + np_class_impl::Allocate, + np_class_impl::Deallocate, + np_class_impl::Invalidate, + np_class_impl::HasMethod, + np_class_impl::Invoke, + np_class_impl::InvokeDefault, + np_class_impl::HasProperty, + np_class_impl::GetProperty, + np_class_impl::SetProperty, + np_class_impl::RemoveProperty, + np_class_impl::Enumerate, + np_class_impl::Construct, + }; + return &np_class; +}; + +} // namespace gpu_plugin + +#endif // O3D_GPU_PLUGIN_NP_UTILS_NP_CLASS_H_ diff --git a/o3d/gpu_plugin/np_utils/np_class_unittest.cc b/o3d/gpu_plugin/np_utils/np_class_unittest.cc new file mode 100644 index 0000000..a58f47a --- /dev/null +++ b/o3d/gpu_plugin/np_utils/np_class_unittest.cc @@ -0,0 +1,143 @@ +// Copyright (c) 2006-2008 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. + +#include "o3d/gpu_plugin/np_utils/np_class.h" +#include "o3d/gpu_plugin/np_utils/np_object_mock.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::StrictMock; + +namespace gpu_plugin { + +class NPClassTest : public testing::Test { + protected: + virtual void SetUp() { + np_class = NPGetClass >(); + + // Dummy identifier is never used with real NPAPI so it can point to + // anything. + identifier = this; + } + + virtual void TearDown() { + } + + NPP_t npp_; + const NPClass* np_class; + NPIdentifier identifier; + NPVariant args[3]; + NPVariant result; +}; + +TEST_F(NPClassTest, AllocateAndDeallocateObject) { + MockNPObject* object = static_cast( + np_class->allocate(&npp_, const_cast(np_class))); + EXPECT_TRUE(NULL != object); + + np_class->deallocate(object); +} + +TEST_F(NPClassTest, InvalidateForwards) { + MockNPObject* object = static_cast( + np_class->allocate(&npp_, const_cast(np_class))); + + EXPECT_CALL(*object, Invalidate()); + np_class->invalidate(object); + + np_class->deallocate(object); +} + +TEST_F(NPClassTest, HasMethodForwards) { + MockNPObject* object = static_cast( + np_class->allocate(&npp_, const_cast(np_class))); + + EXPECT_CALL(*object, HasMethod(identifier)); + np_class->hasMethod(object, identifier); + + np_class->deallocate(object); +} + +TEST_F(NPClassTest, InvokeForwards) { + MockNPObject* object = static_cast( + np_class->allocate(&npp_, const_cast(np_class))); + + EXPECT_CALL(*object, Invoke(identifier, args, 3, &result)); + np_class->invoke(object, identifier, args, 3, &result); + + np_class->deallocate(object); +} + +TEST_F(NPClassTest, InvokeDefaultForwards) { + MockNPObject* object = static_cast( + np_class->allocate(&npp_, const_cast(np_class))); + + EXPECT_CALL(*object, InvokeDefault(args, 3, &result)); + np_class->invokeDefault(object, args, 3, &result); + + np_class->deallocate(object); +} + +TEST_F(NPClassTest, HasPropertyForwards) { + MockNPObject* object = static_cast( + np_class->allocate(&npp_, const_cast(np_class))); + + EXPECT_CALL(*object, HasProperty(identifier)); + np_class->hasProperty(object, identifier); + + np_class->deallocate(object); +} + +TEST_F(NPClassTest, GetPropertyForwards) { + MockNPObject* object = static_cast( + np_class->allocate(&npp_, const_cast(np_class))); + + EXPECT_CALL(*object, GetProperty(identifier, &result)); + np_class->getProperty(object, identifier, &result); + + np_class->deallocate(object); +} + +TEST_F(NPClassTest, SetPropertyForwards) { + MockNPObject* object = static_cast( + np_class->allocate(&npp_, const_cast(np_class))); + + EXPECT_CALL(*object, SetProperty(identifier, &result)); + np_class->setProperty(object, identifier, &result); + + np_class->deallocate(object); +} + +TEST_F(NPClassTest, RemovePropertyForwards) { + MockNPObject* object = static_cast( + np_class->allocate(&npp_, const_cast(np_class))); + + EXPECT_CALL(*object, RemoveProperty(identifier)); + np_class->removeProperty(object, identifier); + + np_class->deallocate(object); +} + +TEST_F(NPClassTest, EnumerateForwards) { + MockNPObject* object = static_cast( + np_class->allocate(&npp_, const_cast(np_class))); + + NPIdentifier* identifier = NULL; + uint32_t count; + EXPECT_CALL(*object, Enumerate(&identifier, &count)); + np_class->enumerate(object, &identifier, &count); + + np_class->deallocate(object); +} + +TEST_F(NPClassTest, ConstructForwards) { + MockNPObject* object = static_cast( + np_class->allocate(&npp_, const_cast(np_class))); + + EXPECT_CALL(*object, Construct(args, 3, &result)); + np_class->construct(object, args, 3, &result); + + np_class->deallocate(object); +} +} // namespace gpu_plugin diff --git a/o3d/gpu_plugin/np_utils/np_dispatcher.cc b/o3d/gpu_plugin/np_utils/np_dispatcher.cc new file mode 100644 index 0000000..06658b4 --- /dev/null +++ b/o3d/gpu_plugin/np_utils/np_dispatcher.cc @@ -0,0 +1,85 @@ +// Copyright (c) 2006-2008 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. + +#include "o3d/gpu_plugin/np_utils/np_dispatcher.h" + +namespace gpu_plugin { + +bool DispatcherHasMethodHelper(BaseNPDispatcher* chain, + NPObject* object, + NPIdentifier name) { + for (BaseNPDispatcher* dispatcher = chain; + dispatcher; + dispatcher = dispatcher->next()) { + if (dispatcher->name() == name) { + return true; + } + } + + return false; +} + +bool DispatcherInvokeHelper(BaseNPDispatcher* chain, + NPObject* object, + NPIdentifier name, + const NPVariant* args, + uint32_t num_args, + NPVariant* result) { + VOID_TO_NPVARIANT(*result); + + for (BaseNPDispatcher* dispatcher = chain; + dispatcher; + dispatcher = dispatcher->next()) { + if (dispatcher->name() == name && dispatcher->num_args() == num_args) { + if (dispatcher->Invoke(object, args, num_args, result)) + return true; + } + } + + return false; +} + +bool DispatcherEnumerateHelper(BaseNPDispatcher* chain, + NPObject* object, + NPIdentifier** names, + uint32_t* num_names) { + // Count the number of names. + *num_names = 0; + for (BaseNPDispatcher* dispatcher = chain; + dispatcher; + dispatcher = dispatcher->next()) { + ++(*num_names); + } + + // Copy names into the array. + *names = static_cast( + NPBrowser::get()->MemAlloc((*num_names) * sizeof(**names))); + int i = 0; + for (BaseNPDispatcher* dispatcher = chain; + dispatcher; + dispatcher = dispatcher->next()) { + (*names)[i] = dispatcher->name(); + ++i; + } + + return true; +} + +BaseNPDispatcher::BaseNPDispatcher(BaseNPDispatcher* next, const NPUTF8* name) + : next_(next) { + // Convert first character to lower case if it is the ASCII range. + // TODO(apatrick): do this correctly for non-ASCII characters. + std::string java_script_style_name(name); + if (isupper(java_script_style_name[0])) { + java_script_style_name[0] = tolower(java_script_style_name[0]); + } + + name_ = NPBrowser::get()->GetStringIdentifier( + java_script_style_name.c_str()); +} + +BaseNPDispatcher::~BaseNPDispatcher() { +} + +} // namespace gpu_plugin diff --git a/o3d/gpu_plugin/np_utils/np_dispatcher.h b/o3d/gpu_plugin/np_utils/np_dispatcher.h new file mode 100644 index 0000000..bc4ac02 --- /dev/null +++ b/o3d/gpu_plugin/np_utils/np_dispatcher.h @@ -0,0 +1,222 @@ +// Copyright (c) 2006-2008 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 O3D_GPU_PLUGIN_NP_UTILS_NP_DISPATCHER_H_ +#define O3D_GPU_PLUGIN_NP_UTILS_NP_DISPATCHER_H_ + +#include + +#include "o3d/gpu_plugin/np_utils/np_utils.h" +#include "o3d/gpu_plugin/np_utils/np_headers.h" + +// Dispatchers make regular member functions available as NPObject methods. +// Usage: +// +// class MyNPObject : public DefaultNPObject { +// public: +// int MyMethod(bool a, float b); +// NP_UTILS_BEGIN_DISPATCHER_CHAIN(MyNPObject, DispatchedNPObject) +// NP_UTILS_DISPATCHER(MyMethod, int(bool, float)) +// NP_UTILS_END_DISPATCHER_CHAIN +// }; +// +// Multiple member functions may be listed in the dispatcher chain. Inheritance +// is supported. The following types are supported as return types and parameter +// types: +// * bool +// * int +// * float +// * double +// * std::string +// * NPObject* +// + +// These macros are used to make dispatcher chains. +#define NP_UTILS_NP_UTILS_DISPATCHER_JOIN2(a, b) a ## b +#define NP_UTILS_DISPATCHER_JOIN(a, b) NP_UTILS_NP_UTILS_DISPATCHER_JOIN2(a, b) +#define NP_UTILS_DISPATCHER_UNIQUE \ + NP_UTILS_DISPATCHER_JOIN(dispatcher, __LINE__) + +#define NP_UTILS_BEGIN_DISPATCHER_CHAIN(Class, BaseClass) \ + static BaseNPDispatcher* GetDispatcherChain() { \ + typedef Class ThisClass; \ + BaseNPDispatcher* top_dispatcher = BaseClass::GetDispatcherChain(); \ + +#define NP_UTILS_DISPATCHER(name, Signature) \ + static NPDispatcher \ + NP_UTILS_DISPATCHER_UNIQUE( \ + top_dispatcher, \ + #name, \ + &ThisClass::name); \ + top_dispatcher = &NP_UTILS_DISPATCHER_UNIQUE; \ + +#define NP_UTILS_END_DISPATCHER_CHAIN \ + return top_dispatcher; \ + } \ + bool HasMethod(NPIdentifier name) { \ + return DispatcherHasMethodHelper(GetDispatcherChain(), this, name); \ + } \ + bool Invoke(NPIdentifier name, \ + const NPVariant* args, \ + uint32_t num_args, \ + NPVariant* result) { \ + return DispatcherInvokeHelper(GetDispatcherChain(), \ + this, \ + name, \ + args, \ + num_args, \ + result); \ + } \ + bool Enumerate(NPIdentifier** names, uint32_t* num_names) { \ + return DispatcherEnumerateHelper(GetDispatcherChain(), \ + this, \ + names, \ + num_names); \ + } \ + +namespace gpu_plugin { + +class BaseNPDispatcher { + public: + BaseNPDispatcher(BaseNPDispatcher* next, const NPUTF8* name); + + virtual ~BaseNPDispatcher(); + + BaseNPDispatcher* next() const { + return next_; + } + + NPIdentifier name() const { + return name_; + } + + virtual int num_args() const = 0; + + virtual bool Invoke(NPObject* object, + const NPVariant* args, + uint32_t num_args, + NPVariant* result) = 0; + + private: + BaseNPDispatcher* next_; + NPIdentifier name_; + DISALLOW_COPY_AND_ASSIGN(BaseNPDispatcher); +}; + +bool DispatcherHasMethodHelper(BaseNPDispatcher* chain, + NPObject* object, + NPIdentifier name); + +bool DispatcherInvokeHelper(BaseNPDispatcher* chain, + NPObject* object, + NPIdentifier name, + const NPVariant* args, + uint32_t num_args, + NPVariant* result); + +bool DispatcherEnumerateHelper(BaseNPDispatcher* chain, + NPObject* object, + NPIdentifier** names, + uint32_t* num_names); + +// This class should never be instantiated. It is always specialized. Attempting +// to instantiate it results in a compilation error. This might mean an +// attempt to instantiate a dispatcher with more parameters than have been +// specialized for. See the specialization code below. +template +struct NPDispatcher { +}; + +#define TO_NPVARIANT(index) \ + T##index n##index; \ + if (!NPVariantToValue(&n##index, args[index])) \ + return false; \ + +#define NUM_PARAMS 0 +#define PARAM_TYPENAMES +#define PARAM_TYPES +#define PARAM_NAMES +#define PARAM_DECLS // NOLINT + +#define PARAM_TO_NVPARIANT_CONVERSIONS \ + +#include "o3d/gpu_plugin/np_utils/np_dispatcher_specializations.h" // NOLINT + + +#define NUM_PARAMS 1 +#define PARAM_TYPENAMES , typename T0 +#define PARAM_TYPES T0 +#define PARAM_NAMES n0 +#define PARAM_DECLS T0 n0; // NOLINT + +#define PARAM_TO_NVPARIANT_CONVERSIONS \ + TO_NPVARIANT(0); \ + +#include "o3d/gpu_plugin/np_utils/np_dispatcher_specializations.h" // NOLINT + + +#define NUM_PARAMS 2 +#define PARAM_TYPENAMES , typename T0, typename T1 +#define PARAM_TYPES T0, T1 +#define PARAM_NAMES n0, n1 +#define PARAM_DECLS T0 n0; T1 n1; // NOLINT + +#define PARAM_TO_NVPARIANT_CONVERSIONS \ + TO_NPVARIANT(0); \ + TO_NPVARIANT(1); \ + +#include "o3d/gpu_plugin/np_utils/np_dispatcher_specializations.h" // NOLINT + + +#define NUM_PARAMS 3 +#define PARAM_TYPENAMES , typename T0, typename T1, typename T2 +#define PARAM_TYPES T0, T1, T2 +#define PARAM_NAMES n0, n1, n2 +#define PARAM_DECLS T0 n0; T1 n1; T2 n2; // NOLINT + +#define PARAM_TO_NVPARIANT_CONVERSIONS \ + TO_NPVARIANT(0); \ + TO_NPVARIANT(1); \ + TO_NPVARIANT(2); \ + +#include "o3d/gpu_plugin/np_utils/np_dispatcher_specializations.h" // NOLINT + + +#define NUM_PARAMS 4 +#define PARAM_TYPENAMES , typename T0, typename T1, typename T2, typename T3 +#define PARAM_TYPES T0, T1, T2, T3 +#define PARAM_NAMES n0, n1, n2, n3 +#define PARAM_DECLS T0 n0; T1 n1; T2 n2; T3 n3; // NOLINT + +#define PARAM_TO_NVPARIANT_CONVERSIONS \ + TO_NPVARIANT(0); \ + TO_NPVARIANT(1); \ + TO_NPVARIANT(2); \ + TO_NPVARIANT(3); \ + +#include "o3d/gpu_plugin/np_utils/np_dispatcher_specializations.h" // NOLINT + + +#define NUM_PARAMS 5 +#define PARAM_TYPENAMES , typename T0, typename T1, typename T2, typename T3, \ + typename T4 +#define PARAM_TYPES T0, T1, T2, T3, T4 +#define PARAM_NAMES n0, n1, n2, n3, n4 +#define PARAM_DECLS T0 n0; T1 n1; T2 n2; T3 n3; T4 n4; // NOLINT + +#define PARAM_TO_NVPARIANT_CONVERSIONS \ + TO_NPVARIANT(0); \ + TO_NPVARIANT(1); \ + TO_NPVARIANT(2); \ + TO_NPVARIANT(3); \ + TO_NPVARIANT(4); \ + +#include "o3d/gpu_plugin/np_utils/np_dispatcher_specializations.h" // NOLINT + + +#undef TO_NPVARIANT + +} // namespace gpu_plugin + +#endif // O3D_GPU_PLUGIN_NP_UTILS_NP_DISPATCHER_H_ diff --git a/o3d/gpu_plugin/np_utils/np_dispatcher_specializations.h b/o3d/gpu_plugin/np_utils/np_dispatcher_specializations.h new file mode 100644 index 0000000..62fb8c4 --- /dev/null +++ b/o3d/gpu_plugin/np_utils/np_dispatcher_specializations.h @@ -0,0 +1,85 @@ +// Copyright (c) 2006-2008 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. + +// There is deliberately no header guard here. This file is included multiple +// times, once for each dispatcher specialiation arity. Do not include this +// file directly. Include np_dispatcher.h instead. + +template +class NPDispatcher + : public BaseNPDispatcher { + typedef void (NPObjectType::*FunctionType)(PARAM_TYPES); + public: + NPDispatcher(BaseNPDispatcher* next, + const NPUTF8* name, + FunctionType function) + : BaseNPDispatcher(next, name), + function_(function) { + } + + virtual bool Invoke(NPObject* object, + const NPVariant* args, + uint32_t num_args, + NPVariant* result) { + VOID_TO_NPVARIANT(*result); + + if (num_args != NUM_PARAMS) + return false; + + PARAM_TO_NVPARIANT_CONVERSIONS + + (static_cast(object)->*function_)(PARAM_NAMES); + return true; + } + + virtual int num_args() const { + return NUM_PARAMS; + } + + private: + FunctionType function_; +}; + +template +class NPDispatcher + : public BaseNPDispatcher { + typedef R (NPObjectType::*FunctionType)(PARAM_TYPES); + public: + NPDispatcher(BaseNPDispatcher* next, + const NPUTF8* name, + FunctionType function) + : BaseNPDispatcher(next, name), + function_(function) { + } + + virtual bool Invoke(NPObject* object, + const NPVariant* args, + uint32_t num_args, + NPVariant* result) { + VOID_TO_NPVARIANT(*result); + + if (num_args != NUM_PARAMS) + return false; + + PARAM_TO_NVPARIANT_CONVERSIONS + + ValueToNPVariant( + (static_cast(object)->*function_)(PARAM_NAMES), result); + return true; + } + + virtual int num_args() const { + return NUM_PARAMS; + } + + private: + FunctionType function_; +}; + +#undef NUM_PARAMS +#undef PARAM_TYPENAMES +#undef PARAM_TYPES +#undef PARAM_NAMES +#undef PARAM_DECLS +#undef PARAM_TO_NVPARIANT_CONVERSIONS diff --git a/o3d/gpu_plugin/np_utils/np_headers.h b/o3d/gpu_plugin/np_utils/np_headers.h new file mode 100644 index 0000000..89e666a --- /dev/null +++ b/o3d/gpu_plugin/np_utils/np_headers.h @@ -0,0 +1,16 @@ +// Copyright (c) 2006-2008 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 O3D_GPU_PLUGIN_NP_UTILS_NP_HEADERS_H_ +#define O3D_GPU_PLUGIN_NP_UTILS_NP_HEADERS_H_ + +#if defined(O3D_IN_CHROME) +#include "third_party/npapi/bindings/npapi.h" +#include "third_party/npapi/bindings/npruntime.h" +#else +#include "o3d/third_party/npapi/include/npapi.h" +#include "o3d/third_party/npapi/include/npruntime.h" +#endif + +#endif // O3D_GPU_PLUGIN_NP_UTILS_NP_HEADERS_H_ diff --git a/o3d/gpu_plugin/np_utils/np_object_mock.h b/o3d/gpu_plugin/np_utils/np_object_mock.h new file mode 100644 index 0000000..84e0912 --- /dev/null +++ b/o3d/gpu_plugin/np_utils/np_object_mock.h @@ -0,0 +1,36 @@ +// Copyright (c) 2006-2008 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 O3D_GPU_PLUGIN_NP_UTILS_NP_OBJECT_MOCK_H_ +#define O3D_GPU_PLUGIN_NP_UTILS_NP_OBJECT_MOCK_H_ + +#include "o3d/gpu_plugin/np_utils/np_browser.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace gpu_plugin { + +class MockNPObject : public NPObject { + public: + explicit MockNPObject(NPP npp) { + } + + MOCK_METHOD0(Invalidate, void()); + MOCK_METHOD1(HasMethod, bool(NPIdentifier)); + MOCK_METHOD4(Invoke, + bool(NPIdentifier, const NPVariant*, uint32_t, NPVariant*)); + MOCK_METHOD3(InvokeDefault, bool(const NPVariant*, uint32_t, NPVariant*)); + MOCK_METHOD1(HasProperty, bool(NPIdentifier)); + MOCK_METHOD2(GetProperty, bool(NPIdentifier, NPVariant*)); + MOCK_METHOD2(SetProperty, bool(NPIdentifier, const NPVariant*)); + MOCK_METHOD1(RemoveProperty, bool(NPIdentifier)); + MOCK_METHOD2(Enumerate, bool(NPIdentifier**, uint32_t*)); + MOCK_METHOD3(Construct, bool(const NPVariant*, uint32_t, NPVariant*)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockNPObject); +}; + +} // namespace gpu_plugin + +#endif // O3D_GPU_PLUGIN_NP_UTILS_NP_OBJECT_MOCK_H_ diff --git a/o3d/gpu_plugin/np_utils/np_object_pointer.h b/o3d/gpu_plugin/np_utils/np_object_pointer.h new file mode 100644 index 0000000..5cf3bbe --- /dev/null +++ b/o3d/gpu_plugin/np_utils/np_object_pointer.h @@ -0,0 +1,119 @@ +// Copyright (c) 2006-2008 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 O3D_GPU_PLUGIN_NP_UTILS_NP_OBJECT_POINTER_H_ +#define O3D_GPU_PLUGIN_NP_UTILS_NP_OBJECT_POINTER_H_ + +#include "base/logging.h" +#include "o3d/gpu_plugin/np_utils/np_browser.h" +#include "o3d/gpu_plugin/np_utils/np_headers.h" + +namespace gpu_plugin { + +// Smart pointer for NPObjects that automatically handles reference counting. +template +class NPObjectPointer { + public: + NPObjectPointer() : object_(NULL) {} + + NPObjectPointer(const NPObjectPointer& rhs) : object_(rhs.object_) { + Retain(); + } + + explicit NPObjectPointer(NPObjectType* p) : object_(p) { + Retain(); + } + + template + NPObjectPointer(const NPObjectPointer& rhs) : object_(rhs.Get()) { + Retain(); + } + + ~NPObjectPointer() { + Release(); + } + + NPObjectPointer& operator=(const NPObjectPointer& rhs) { + if (object_ == rhs.Get()) + return *this; + + Release(); + object_ = rhs.object_; + Retain(); + return *this; + } + + template + NPObjectPointer& operator=(const NPObjectPointer& rhs) { + if (object_ == rhs.Get()) + return *this; + + Release(); + object_ = rhs.Get(); + Retain(); + return *this; + } + + template + bool operator==(const NPObjectPointer& rhs) const { + return object_ == rhs.Get(); + } + + template + bool operator!=(const NPObjectPointer& rhs) const { + return object_ != rhs.Get(); + } + + // The NPObject convention for returning an NPObject pointer from a function + // is that the caller is responsible for releasing the reference count. + static NPObjectPointer FromReturned(NPObjectType* p) { + NPObjectPointer pointer(p); + pointer.Release(); + return pointer; + } + + // The NPObject convention for returning an NPObject pointer from a function + // is that the caller is responsible for releasing the reference count. + NPObjectType* ToReturned() const { + Retain(); + return object_; + } + + NPObjectType* Get() const { + return object_; + } + + NPObjectType* operator->() const { + return object_; + } + + NPObjectType& operator*() const { + return *object_; + } + + private: + void Retain() const { + if (object_) { + NPBrowser::get()->RetainObject(object_); + } + } + + void Release() const { + if (object_) { + NPBrowser::get()->ReleaseObject(object_); + } + } + + NPObjectType* object_; +}; + +// For test diagnostics. +template +std::ostream& operator<<(std::ostream& stream, + const NPObjectPointer& pointer) { + return stream << pointer.Get(); +} +} // namespace gpu_plugin + +#endif // O3D_GPU_PLUGIN_NP_UTILS_NP_OBJECT_POINTER_H_ diff --git a/o3d/gpu_plugin/np_utils/np_object_pointer_unittest.cc b/o3d/gpu_plugin/np_utils/np_object_pointer_unittest.cc new file mode 100644 index 0000000..c043c08 --- /dev/null +++ b/o3d/gpu_plugin/np_utils/np_object_pointer_unittest.cc @@ -0,0 +1,220 @@ +// Copyright (c) 2006-2008 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. + +#include "o3d/gpu_plugin/np_utils/np_class.h" +#include "o3d/gpu_plugin/np_utils/np_object_mock.h" +#include "o3d/gpu_plugin/np_utils/np_browser_stub.h" +#include "o3d/gpu_plugin/np_utils/np_object_pointer.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::Return; +using testing::StrictMock; + +namespace gpu_plugin { + +class DerivedNPObject : public MockNPObject { + public: + explicit DerivedNPObject(NPP npp) : MockNPObject(npp) { + } +}; + +class NPObjectPointerTest : public testing::Test { + protected: + virtual void SetUp() { + np_class_ = NPGetClass >(); + + raw_pointer_ = static_cast( + NPBrowser::get()->CreateObject(NULL, np_class_)); + + raw_derived_pointer_ = static_cast( + NPBrowser::get()->CreateObject(NULL, np_class_)); + } + + virtual void TearDown() { + NPBrowser::get()->ReleaseObject(raw_pointer_); + NPBrowser::get()->ReleaseObject(raw_derived_pointer_); + } + + StubNPBrowser stub_browser_; + const NPClass* np_class_; + MockNPObject* raw_pointer_; + DerivedNPObject* raw_derived_pointer_; +}; + +TEST_F(NPObjectPointerTest, PointerIsNullByDefault) { + NPObjectPointer p; + ASSERT_TRUE(NULL == p.Get()); +} + +TEST_F(NPObjectPointerTest, PointerCanBeExplicitlyConstructedFromRawPointer) { + EXPECT_EQ(1, raw_pointer_->referenceCount); + { + NPObjectPointer p(raw_pointer_); + ASSERT_TRUE(raw_pointer_ == p.Get()); + EXPECT_EQ(2, raw_pointer_->referenceCount); + } + EXPECT_EQ(1, raw_pointer_->referenceCount); +} + +TEST_F(NPObjectPointerTest, + PointerCanBeExplicitlyConstructedFromNullRawPointer) { + NPObjectPointer p(NULL); + ASSERT_TRUE(NULL == p.Get()); +} + +TEST_F(NPObjectPointerTest, PointerCanBeCopyConstructed) { + NPObjectPointer p1(raw_pointer_); + EXPECT_EQ(2, raw_pointer_->referenceCount); + { + NPObjectPointer p2(p1); + ASSERT_TRUE(raw_pointer_ == p2.Get()); + EXPECT_EQ(3, raw_pointer_->referenceCount); + } + EXPECT_EQ(2, raw_pointer_->referenceCount); +} + +TEST_F(NPObjectPointerTest, PointerCanBeConstructedFromDerived) { + NPObjectPointer p1(raw_derived_pointer_); + EXPECT_EQ(2, raw_derived_pointer_->referenceCount); + { + NPObjectPointer p2(p1); + ASSERT_TRUE(raw_derived_pointer_ == p2.Get()); + EXPECT_EQ(3, raw_derived_pointer_->referenceCount); + } + EXPECT_EQ(2, raw_derived_pointer_->referenceCount); +} + +TEST_F(NPObjectPointerTest, + PointerCanBeCopyConstructedFromNull) { + NPObjectPointer p(NULL); + ASSERT_TRUE(NULL == p.Get()); +} + +TEST_F(NPObjectPointerTest, PointerCanBeAssigned) { + NPObjectPointer p1(raw_pointer_); + EXPECT_EQ(2, raw_pointer_->referenceCount); + { + NPObjectPointer p2; + p2 = p1; + ASSERT_TRUE(raw_pointer_ == p2.Get()); + EXPECT_EQ(3, raw_pointer_->referenceCount); + + p2 = NPObjectPointer(); + ASSERT_TRUE(NULL == p2.Get()); + EXPECT_EQ(2, raw_pointer_->referenceCount); + + p2 = p1; + ASSERT_TRUE(raw_pointer_ == p2.Get()); + EXPECT_EQ(3, raw_pointer_->referenceCount); + } + EXPECT_EQ(2, raw_pointer_->referenceCount); +} + +TEST_F(NPObjectPointerTest, PointerCanBeAssignedToSelf) { + NPObjectPointer p(raw_pointer_); + NPBrowser::get()->ReleaseObject(raw_pointer_); + EXPECT_EQ(1, raw_pointer_->referenceCount); + p = p; + EXPECT_EQ(1, raw_pointer_->referenceCount); + NPBrowser::get()->RetainObject(raw_pointer_); +} + +TEST_F(NPObjectPointerTest, PointerCanBeAssignedDerived) { + NPObjectPointer p1(raw_derived_pointer_); + EXPECT_EQ(2, raw_derived_pointer_->referenceCount); + { + NPObjectPointer p2; + p2 = p1; + ASSERT_TRUE(raw_derived_pointer_ == p2.Get()); + EXPECT_EQ(3, raw_derived_pointer_->referenceCount); + + p2 = NPObjectPointer(); + ASSERT_TRUE(NULL == p2.Get()); + EXPECT_EQ(2, raw_derived_pointer_->referenceCount); + + p2 = p1; + ASSERT_TRUE(raw_derived_pointer_ == p2.Get()); + EXPECT_EQ(3, raw_derived_pointer_->referenceCount); + } + EXPECT_EQ(2, raw_derived_pointer_->referenceCount); +} + +TEST_F(NPObjectPointerTest, DerivedPointerCanBeAssignedToSelf) { + NPObjectPointer p1(raw_derived_pointer_); + NPObjectPointer p2(raw_derived_pointer_); + NPBrowser::get()->ReleaseObject(raw_derived_pointer_); + NPBrowser::get()->ReleaseObject(raw_derived_pointer_); + EXPECT_EQ(1, raw_derived_pointer_->referenceCount); + p1 = p2; + EXPECT_EQ(1, raw_derived_pointer_->referenceCount); + NPBrowser::get()->RetainObject(raw_derived_pointer_); + NPBrowser::get()->RetainObject(raw_derived_pointer_); +} + +TEST_F(NPObjectPointerTest, CanComparePointersForEqual) { + NPObjectPointer p1(raw_pointer_); + NPObjectPointer p2(raw_derived_pointer_); + EXPECT_TRUE(p1 == p1); + EXPECT_FALSE(p1 == p2); + EXPECT_FALSE(p2 == p1); + EXPECT_FALSE(p1 == NPObjectPointer()); +} + +TEST_F(NPObjectPointerTest, CanComparePointersForNotEqual) { + NPObjectPointer p1(raw_pointer_); + NPObjectPointer p2(raw_derived_pointer_); + EXPECT_FALSE(p1 != p1); + EXPECT_TRUE(p1 != p2); + EXPECT_TRUE(p2 != p1); + EXPECT_TRUE(p1 != NPObjectPointer()); +} + +TEST_F(NPObjectPointerTest, ArrowOperatorCanBeUsedToAccessNPObjectMembers) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("hello"); + + EXPECT_CALL(*raw_pointer_, HasProperty(name)).WillOnce(Return(true)); + + NPObjectPointer p(raw_pointer_); + EXPECT_TRUE(p->HasProperty(name)); +} + +TEST_F(NPObjectPointerTest, StarOperatorReturnsNPObjectReference) { + NPObjectPointer p(raw_pointer_); + EXPECT_EQ(raw_pointer_, &*p); +} + +TEST_F(NPObjectPointerTest, PointerCanBeConstructedFromReturnedNPObject) { + NPBrowser::get()->RetainObject(raw_pointer_); + EXPECT_EQ(2, raw_pointer_->referenceCount); + { + NPObjectPointer p( + NPObjectPointer::FromReturned(raw_pointer_)); + EXPECT_EQ(2, raw_pointer_->referenceCount); + } + EXPECT_EQ(1, raw_pointer_->referenceCount); +} + +TEST_F(NPObjectPointerTest, PointerCanBeConstructedFromReturnedNullNPObject) { + NPObjectPointer p( + NPObjectPointer::FromReturned(NULL)); + EXPECT_TRUE(NULL == p.Get()); +} + +TEST_F(NPObjectPointerTest, PointerCanBeReturnedAsARawNPObject) { + NPObjectPointer p(raw_pointer_); + EXPECT_EQ(raw_pointer_, p.ToReturned()); + + // Check reference count is incremented before return for caller. + EXPECT_EQ(3, raw_pointer_->referenceCount); + + NPBrowser::get()->ReleaseObject(raw_pointer_); +} + +TEST_F(NPObjectPointerTest, NULLPointerCanBeReturnedAsARawNPObject) { + NPObjectPointer p; + EXPECT_TRUE(NULL == p.ToReturned()); +} + +} // namespace gpu_plugin diff --git a/o3d/gpu_plugin/np_utils/np_plugin_object.h b/o3d/gpu_plugin/np_utils/np_plugin_object.h new file mode 100644 index 0000000..06e0136 --- /dev/null +++ b/o3d/gpu_plugin/np_utils/np_plugin_object.h @@ -0,0 +1,50 @@ +// Copyright (c) 2006-2008 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 O3D_GPU_PLUGIN_NP_UTILS_NP_PLUGIN_OBJECT_H_ +#define O3D_GPU_PLUGIN_NP_UTILS_NP_PLUGIN_OBJECT_H_ + +#include "o3d/gpu_plugin/np_utils/np_object_pointer.h" +#include "o3d/gpu_plugin/np_utils/np_headers.h" + +namespace gpu_plugin { + +// Interface for a plugin instance. The NPP plugin calls forwards to an instance +// of this interface. +class PluginObject { + public: + // Initialize this object. + virtual NPError New(NPMIMEType plugin_type, + int16 argc, + char* argn[], + char* argv[], + NPSavedData* saved) = 0; + + virtual NPError SetWindow(NPWindow* new_window) = 0; + + virtual int16 HandleEvent(NPEvent* event) = 0; + + // Uninitialize but do not deallocate the object. Release will be called to + // deallocate if Destroy succeeds. + virtual NPError Destroy(NPSavedData** saved) = 0; + + // Deallocate this object. This object is invalid after this returns. + virtual void Release() = 0; + + virtual NPObject* GetScriptableNPObject() = 0; + + protected: + PluginObject() { + } + + virtual ~PluginObject() { + } + + private: + DISALLOW_COPY_AND_ASSIGN(PluginObject); +}; + +} // namespace gpu_plugin + +#endif // O3D_GPU_PLUGIN_NP_UTILS_NP_PLUGIN_OBJECT_H_ diff --git a/o3d/gpu_plugin/np_utils/np_plugin_object_factory.cc b/o3d/gpu_plugin/np_utils/np_plugin_object_factory.cc new file mode 100644 index 0000000..96cb595 --- /dev/null +++ b/o3d/gpu_plugin/np_utils/np_plugin_object_factory.cc @@ -0,0 +1,30 @@ +// Copyright (c) 2006-2008 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. + +#include "o3d/gpu_plugin/gpu_plugin_object_factory.h" +#include "base/logging.h" + +namespace gpu_plugin { + +NPPluginObjectFactory* NPPluginObjectFactory::factory_; + +PluginObject* NPPluginObjectFactory::CreatePluginObject( + NPP npp, + NPMIMEType plugin_type) { + return NULL; +} + +NPPluginObjectFactory::NPPluginObjectFactory() { + // Make this the first factory in the linked list. + previous_factory_ = factory_; + factory_ = this; +} + +NPPluginObjectFactory::~NPPluginObjectFactory() { + // Remove this factory from the linked list. + DCHECK(factory_ == this); + factory_ = previous_factory_; +} + +} // namespace gpu_plugin diff --git a/o3d/gpu_plugin/np_utils/np_plugin_object_factory.h b/o3d/gpu_plugin/np_utils/np_plugin_object_factory.h new file mode 100644 index 0000000..4c8d61c --- /dev/null +++ b/o3d/gpu_plugin/np_utils/np_plugin_object_factory.h @@ -0,0 +1,37 @@ +// Copyright (c) 2006-2008 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 O3D_GPU_PLUGIN_NP_UTILS_NP_PLUGIN_OBJECT_FACTORY_H_ +#define O3D_GPU_PLUGIN_NP_UTILS_NP_PLUGIN_OBJECT_FACTORY_H_ + +#include "base/basictypes.h" +#include "o3d/gpu_plugin/np_utils/np_headers.h" + +namespace gpu_plugin { + +class PluginObject; + +// Mockable factory base class used to create instances of PluginObject based on +// plugin mime type. +class NPPluginObjectFactory { + public: + virtual PluginObject* CreatePluginObject(NPP npp, NPMIMEType plugin_type); + + static NPPluginObjectFactory* get() { + return factory_; + } + + protected: + NPPluginObjectFactory(); + virtual ~NPPluginObjectFactory(); + + private: + static NPPluginObjectFactory* factory_; + NPPluginObjectFactory* previous_factory_; + DISALLOW_COPY_AND_ASSIGN(NPPluginObjectFactory); +}; + +} // namespace gpu_plugin + +#endif // O3D_GPU_PLUGIN_NP_UTILS_NP_PLUGIN_OBJECT_FACTORY_H_ diff --git a/o3d/gpu_plugin/np_utils/np_plugin_object_factory_mock.h b/o3d/gpu_plugin/np_utils/np_plugin_object_factory_mock.h new file mode 100644 index 0000000..9a61537 --- /dev/null +++ b/o3d/gpu_plugin/np_utils/np_plugin_object_factory_mock.h @@ -0,0 +1,23 @@ +// Copyright (c) 2006-2008 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 O3D_GPU_PLUGIN_NP_UTILS_NP_PLUGIN_OBJECT_FACTORY_MOCK_H_ +#define O3D_GPU_PLUGIN_NP_UTILS_NP_PLUGIN_OBJECT_FACTORY_MOCK_H_ + +#include "o3d/gpu_plugin/np_utils/np_plugin_object_factory.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace gpu_plugin { + +// Mockable factory used to create instances of PluginObject based on plugin +// mime type. +class MockPluginObjectFactory : public NPPluginObjectFactory { + public: + MOCK_METHOD2(CreatePluginObject, PluginObject*(NPP, NPMIMEType)); +}; + +} // namespace gpu_plugin + +#endif // O3D_GPU_PLUGIN_NP_UTILS_NP_PLUGIN_OBJECT_FACTORY_MOCK_H_ diff --git a/o3d/gpu_plugin/np_utils/np_plugin_object_mock.h b/o3d/gpu_plugin/np_utils/np_plugin_object_mock.h new file mode 100644 index 0000000..fe1f407 --- /dev/null +++ b/o3d/gpu_plugin/np_utils/np_plugin_object_mock.h @@ -0,0 +1,26 @@ +// Copyright (c) 2006-2008 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 O3D_GPU_PLUGIN_NP_UTILS_NP_PLUGIN_OBJECT_MOCK_H_ +#define O3D_GPU_PLUGIN_NP_UTILS_NP_PLUGIN_OBJECT_MOCK_H_ + +#include "o3d/gpu_plugin/np_utils/np_plugin_object.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace gpu_plugin { + +class MockPluginObject : public PluginObject { + public: + MOCK_METHOD5(New, NPError(NPMIMEType, int16, char*[], char*[], NPSavedData*)); + MOCK_METHOD1(SetWindow, NPError(NPWindow*)); + MOCK_METHOD1(HandleEvent, int16(NPEvent*)); + MOCK_METHOD1(Destroy, NPError(NPSavedData**)); + MOCK_METHOD0(Release, void()); + MOCK_METHOD0(GetScriptableNPObject, NPObject*()); +}; + +} // namespace gpu_plugin + +#endif // O3D_GPU_PLUGIN_NP_UTILS_NP_PLUGIN_OBJECT_MOCK_H_ diff --git a/o3d/gpu_plugin/np_utils/np_utils.cc b/o3d/gpu_plugin/np_utils/np_utils.cc new file mode 100644 index 0000000..d1400e6 --- /dev/null +++ b/o3d/gpu_plugin/np_utils/np_utils.cc @@ -0,0 +1,170 @@ +// Copyright (c) 2006-2008 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. + +#include "o3d/gpu_plugin/np_utils/np_utils.h" + +namespace gpu_plugin { + +bool NPVariantToValue(bool* value, const NPVariant& variant) { + if (NPVARIANT_IS_BOOLEAN(variant)) { + *value = NPVARIANT_TO_BOOLEAN(variant); + return true; + } + + return false; +} + +bool NPVariantToValue(int32* value, const NPVariant& variant) { + if (NPVARIANT_IS_INT32(variant)) { + *value = NPVARIANT_TO_INT32(variant); + return true; + } + + return false; +} + +bool NPVariantToValue(float* value, const NPVariant& variant) { + if (NPVARIANT_IS_DOUBLE(variant)) { + *value = static_cast(NPVARIANT_TO_DOUBLE(variant)); + return true; + } else if (NPVARIANT_IS_INT32(variant)) { + *value = static_cast(NPVARIANT_TO_INT32(variant)); + return true; + } + + return false; +} + +bool NPVariantToValue(double* value, const NPVariant& variant) { + if (NPVARIANT_IS_DOUBLE(variant)) { + *value = NPVARIANT_TO_DOUBLE(variant); + return true; + } else if (NPVARIANT_IS_INT32(variant)) { + *value = NPVARIANT_TO_INT32(variant); + return true; + } + + return false; +} + +bool NPVariantToValue(std::string* value, const NPVariant& variant) { + if (NPVARIANT_IS_STRING(variant)) { + const NPString& str = NPVARIANT_TO_STRING(variant); + *value = std::string(str.UTF8Characters, str.UTF8Length); + return true; + } + + return false; +} + +void ValueToNPVariant(bool value, NPVariant* variant) { + BOOLEAN_TO_NPVARIANT(value, *variant); +} + +void ValueToNPVariant(int32 value, NPVariant* variant) { + INT32_TO_NPVARIANT(value, *variant); +} + +void ValueToNPVariant(float value, NPVariant* variant) { + DOUBLE_TO_NPVARIANT(value, *variant); +} + +void ValueToNPVariant(double value, NPVariant* variant) { + DOUBLE_TO_NPVARIANT(value, *variant); +} + +void ValueToNPVariant(const std::string& value, NPVariant* variant) { + NPUTF8* p = static_cast(NPBrowser::get()->MemAlloc(value.length())); + memcpy(p, value.c_str(), value.length()); + STRINGN_TO_NPVARIANT(p, value.length(), *variant); +} + +SmartNPVariant::SmartNPVariant() { + VOID_TO_NPVARIANT(*this); +} + +SmartNPVariant::SmartNPVariant(const SmartNPVariant& rhs) { + rhs.CopyTo(this); +} + +SmartNPVariant::SmartNPVariant(const NPVariant& rhs) { + static_cast(rhs).CopyTo(this); +} + +SmartNPVariant::~SmartNPVariant() { + Release(); +} + +SmartNPVariant& SmartNPVariant::operator=(const SmartNPVariant& rhs) { + Release(); + rhs.CopyTo(this); + return *this; +} + +SmartNPVariant& SmartNPVariant::operator=(const NPVariant& rhs) { + Release(); + static_cast(rhs).CopyTo(this); + return *this; +} + +bool SmartNPVariant::IsVoid() const { + return NPVARIANT_IS_VOID(*this); +} + +void SmartNPVariant::Release() { + NPBrowser::get()->ReleaseVariantValue(this); + VOID_TO_NPVARIANT(*this); +} + +void SmartNPVariant::Invalidate() { + if (NPVARIANT_IS_OBJECT(*this)) { + NULL_TO_NPVARIANT(*this); + } +} + +void SmartNPVariant::CopyTo(NPVariant* rhs) const { + if (NPVARIANT_IS_OBJECT(*this)) { + NPObject* object = NPVARIANT_TO_OBJECT(*this); + OBJECT_TO_NPVARIANT(object, *rhs); + NPBrowser::get()->RetainObject(object); + } else if (NPVARIANT_IS_STRING(*this)) { + NPUTF8* copy = static_cast(NPBrowser::get()->MemAlloc( + value.stringValue.UTF8Length)); + memcpy(copy, + value.stringValue.UTF8Characters, + value.stringValue.UTF8Length); + STRINGN_TO_NPVARIANT(copy, value.stringValue.UTF8Length, *rhs); + } else { + memcpy(rhs, this, sizeof(*rhs)); + } +} + +bool NPHasMethod(NPP npp, + const NPObjectPointer& object, + const NPUTF8* name) { + return NPBrowser::get()->HasMethod( + npp, + object.Get(), + NPBrowser::get()->GetStringIdentifier(name)); +} + +bool NPHasProperty(NPP npp, + const NPObjectPointer& object, + const NPUTF8* name) { + return NPBrowser::get()->HasProperty( + npp, + object.Get(), + NPBrowser::get()->GetStringIdentifier(name)); +} + +bool NPRemoveProperty(NPP npp, + const NPObjectPointer& object, + const NPUTF8* name) { + return NPBrowser::get()->RemoveProperty( + npp, + object.Get(), + NPBrowser::get()->GetStringIdentifier(name)); +} + +} // namespace gpu_plugin diff --git a/o3d/gpu_plugin/np_utils/np_utils.h b/o3d/gpu_plugin/np_utils/np_utils.h new file mode 100644 index 0000000..d5a27c5 --- /dev/null +++ b/o3d/gpu_plugin/np_utils/np_utils.h @@ -0,0 +1,271 @@ +// Copyright (c) 2006-2008 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 O3D_GPU_PLUGIN_NP_UTILS_NP_UTILS_H_ +#define O3D_GPU_PLUGIN_NP_UTILS_NP_UTILS_H_ + +#include + +#include "o3d/gpu_plugin/np_utils/np_browser.h" +#include "o3d/gpu_plugin/np_utils/np_class.h" +#include "o3d/gpu_plugin/np_utils/np_object_pointer.h" +#include "o3d/gpu_plugin/np_utils/np_headers.h" + +namespace gpu_plugin { + +// Convert NPVariant to C++ type. Returns whether the conversion was successful. +bool NPVariantToValue(bool* value, const NPVariant& variant); +bool NPVariantToValue(int32* value, const NPVariant& variant); +bool NPVariantToValue(float* value, const NPVariant& variant); +bool NPVariantToValue(double* value, const NPVariant& variant); +bool NPVariantToValue(std::string* value, const NPVariant& variant); + +template +bool NPVariantToValue(NPObjectPointer* value, + const NPVariant& variant) { + if (NPVARIANT_IS_NULL(variant)) { + *value = NPObjectPointer(); + return true; + } else if (NPVARIANT_IS_OBJECT(variant)) { + NPObject* object = NPVARIANT_TO_OBJECT(variant); + if (object->_class == NPGetClass()) { + *value = NPObjectPointer(static_cast( + NPVARIANT_TO_OBJECT(variant))); + return true; + } + } + + return false; +} + +// Specialization for NPObject does not check for mismatched NPClass. +template <> +inline bool NPVariantToValue(NPObjectPointer* value, + const NPVariant& variant) { + if (NPVARIANT_IS_NULL(variant)) { + *value = NPObjectPointer(); + return true; + } else if (NPVARIANT_IS_OBJECT(variant)) { + *value = NPObjectPointer(NPVARIANT_TO_OBJECT(variant)); + return true; + } + + return false; +} + +// Convert C++ type to NPVariant. +void ValueToNPVariant(bool value, NPVariant* variant); +void ValueToNPVariant(int32 value, NPVariant* variant); +void ValueToNPVariant(float value, NPVariant* variant); +void ValueToNPVariant(double value, NPVariant* variant); +void ValueToNPVariant(const std::string& value, NPVariant* variant); + +template +void ValueToNPVariant(const NPObjectPointer& value, + NPVariant* variant) { + if (value.Get()) { + NPBrowser::get()->RetainObject(value.Get()); + OBJECT_TO_NPVARIANT(value.Get(), *variant); + } else { + NULL_TO_NPVARIANT(*variant); + } +} + +// NPVariant that automatically manages lifetime of string and object variants. +class SmartNPVariant : public NPVariant { + public: + SmartNPVariant(); + SmartNPVariant(const SmartNPVariant& rhs); + explicit SmartNPVariant(const NPVariant& rhs); + + template + explicit SmartNPVariant(const T& v) { + ValueToNPVariant(v, this); + } + + ~SmartNPVariant(); + + SmartNPVariant& operator=(const SmartNPVariant& rhs); + SmartNPVariant& operator=(const NPVariant& rhs); + + template + bool GetValue(T* v) const { + return NPVariantToValue(v, *this); + } + + bool IsVoid() const; + + template + void SetValue(const T& v) { + Release(); + ValueToNPVariant(v, this); + } + + void CopyTo(NPVariant* target) const; + + // Sets the variant to void. + void Release(); + + // Called when an NPObject is invalidated to clear any references to other + // NPObjects. Does not release the object as it might no longer be valid. + void Invalidate(); +}; + +// These allow a method to be invoked with automatic conversion of C++ +// types to variants for arguments and return values. + +bool NPHasMethod(NPP npp, + const NPObjectPointer& object, + const NPUTF8* name); + +inline bool NPInvokeVoid(NPP npp, + const NPObjectPointer& object, + const NPUTF8* name) { + SmartNPVariant result; + return NPBrowser::get()->Invoke( + npp, + object.Get(), + NPBrowser::get()->GetStringIdentifier(name), + NULL, 0, + &result); +} + +template +bool NPInvoke(NPP npp, + const NPObjectPointer& object, + const NPUTF8* name, + R* r) { + SmartNPVariant result; + if (NPBrowser::get()->Invoke( + npp, + object.Get(), + NPBrowser::get()->GetStringIdentifier(name), + NULL, 0, + &result)) { + return result.GetValue(r); + } + return false; +} + +template +bool NPInvokeVoid(NPP npp, + const NPObjectPointer& object, + const NPUTF8* name, + P0 p0) { + SmartNPVariant args[1]; + args[0].SetValue(p0); + SmartNPVariant result; + return NPBrowser::get()->Invoke( + npp, + object.Get(), + NPBrowser::get()->GetStringIdentifier(name), + &args[0], 1, + &result); +} + +template +bool NPInvoke(NPP npp, + const NPObjectPointer& object, + const NPUTF8* name, + P0 p0, + R* r) { + SmartNPVariant args[1]; + args[0].SetValue(p0); + SmartNPVariant result; + if (NPBrowser::get()->Invoke( + npp, + object.Get(), + NPBrowser::get()->GetStringIdentifier(name), + &args[0], 1, + &result)) { + return result.GetValue(r); + } + return false; +} + +template +bool NPInvokeVoid(NPP npp, + const NPObjectPointer& object, + const NPUTF8* name, + P0 p0, P1 p1) { + SmartNPVariant args[2]; + args[0].SetValue(p0); + args[1].SetValue(p1); + SmartNPVariant result; + return NPBrowser::get()->Invoke( + npp, + object.Get(), + NPBrowser::get()->GetStringIdentifier(name), + &args[0], 2, + &result); +} + +template +bool NPInvoke(NPP npp, + const NPObjectPointer& object, + const NPUTF8* name, + P0 p0, P1 p1, + R* r) { + SmartNPVariant args[2]; + args[0].SetValue(p0); + args[1].SetValue(p1); + SmartNPVariant result; + if (NPBrowser::get()->Invoke( + npp, + object.Get(), + NPBrowser::get()->GetStringIdentifier(name), + &args[0], 2, + &result)) { + return result.GetValue(r); + } + return false; +} + +bool NPHasProperty(NPP npp, + const NPObjectPointer& object, + const NPUTF8* name); + +template +bool NPGetProperty(NPP npp, + const NPObjectPointer& object, + const NPUTF8* name, + T* value) { + SmartNPVariant result; + if (NPBrowser::get()->GetProperty(npp, + object.Get(), + NPBrowser::get()->GetStringIdentifier(name), + &result)) { + return result.GetValue(value); + } + return false; +} + +template +bool NPSetProperty(NPP npp, + const NPObjectPointer& object, + const NPUTF8* name, + const T& value) { + SmartNPVariant variant(value); + return NPBrowser::get()->SetProperty( + npp, + object.Get(), + NPBrowser::get()->GetStringIdentifier(name), + &variant); +} + +bool NPRemoveProperty(NPP npp, + const NPObjectPointer& object, + const NPUTF8* name); + +template +NPObjectPointer NPCreateObject(NPP npp) { + const NPClass* np_class = NPGetClass(); + NPObjectType* object = static_cast( + NPBrowser::get()->CreateObject(npp, np_class)); + return NPObjectPointer::FromReturned(object); +} + +} // namespace gpu_plugin + +#endif // O3D_GPU_PLUGIN_NP_UTILS_NP_UTILS_H_ diff --git a/o3d/gpu_plugin/np_utils/np_utils_unittest.cc b/o3d/gpu_plugin/np_utils/np_utils_unittest.cc new file mode 100644 index 0000000..d281c88 --- /dev/null +++ b/o3d/gpu_plugin/np_utils/np_utils_unittest.cc @@ -0,0 +1,424 @@ +// Copyright (c) 2006-2008 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. + +#include "o3d/gpu_plugin/np_utils/np_object_mock.h" +#include "o3d/gpu_plugin/np_utils/np_browser_stub.h" +#include "o3d/gpu_plugin/np_utils/np_utils.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::_; +using testing::DoAll; +using testing::MakeMatcher; +using testing::Matcher; +using testing::Pointee; +using testing::Return; +using testing::SetArgumentPointee; +using testing::StrictMock; + +namespace gpu_plugin { + +class NPUtilsTest : public testing::Test { + protected: + StubNPBrowser stub_browser_; + NPP_t npp_; + NPVariant variant_; +}; + +TEST_F(NPUtilsTest, TestBoolNPVariantToValue) { + bool v; + + BOOLEAN_TO_NPVARIANT(false, variant_); + EXPECT_TRUE(NPVariantToValue(&v, variant_)); + EXPECT_FALSE(v); + + BOOLEAN_TO_NPVARIANT(true, variant_); + EXPECT_TRUE(NPVariantToValue(&v, variant_)); + EXPECT_TRUE(v); + + INT32_TO_NPVARIANT(7, variant_); + EXPECT_FALSE(NPVariantToValue(&v, variant_)); +} + +TEST_F(NPUtilsTest, TestIntNPVariantToValue) { + INT32_TO_NPVARIANT(7, variant_); + + int v1; + EXPECT_TRUE(NPVariantToValue(&v1, variant_)); + EXPECT_EQ(7, v1); + + float v2; + EXPECT_TRUE(NPVariantToValue(&v2, variant_)); + EXPECT_EQ(7.0f, v2); + + double v3; + EXPECT_TRUE(NPVariantToValue(&v3, variant_)); + EXPECT_EQ(7.0, v3); + + BOOLEAN_TO_NPVARIANT(false, variant_); + EXPECT_FALSE(NPVariantToValue(&v1, variant_)); +} + +TEST_F(NPUtilsTest, TestFloatNPVariantToValue) { + float v; + + DOUBLE_TO_NPVARIANT(7.0, variant_); + EXPECT_TRUE(NPVariantToValue(&v, variant_)); + EXPECT_EQ(7.0f, v); + + BOOLEAN_TO_NPVARIANT(false, variant_); + EXPECT_FALSE(NPVariantToValue(&v, variant_)); +} + +TEST_F(NPUtilsTest, TestDoubleNPVariantToValue) { + double v; + + DOUBLE_TO_NPVARIANT(7.0, variant_); + EXPECT_TRUE(NPVariantToValue(&v, variant_)); + EXPECT_EQ(7.0, v); + + BOOLEAN_TO_NPVARIANT(false, variant_); + EXPECT_FALSE(NPVariantToValue(&v, variant_)); +} + +TEST_F(NPUtilsTest, TestStringNPVariantToValue) { + std::string v; + + STRINGZ_TO_NPVARIANT("hello", variant_); + EXPECT_TRUE(NPVariantToValue(&v, variant_)); + EXPECT_EQ(std::string("hello"), v); + + BOOLEAN_TO_NPVARIANT(false, variant_); + EXPECT_FALSE(NPVariantToValue(&v, variant_)); +} + +TEST_F(NPUtilsTest, TestObjectNPVariantToValue) { + NPObjectPointer object = + NPCreateObject >(NULL); + NPObjectPointer v; + + OBJECT_TO_NPVARIANT(object.Get(), variant_); + EXPECT_TRUE(NPVariantToValue(&v, variant_)); + EXPECT_EQ(object, v); + + BOOLEAN_TO_NPVARIANT(false, variant_); + EXPECT_FALSE(NPVariantToValue(&v, variant_)); +} + +TEST_F(NPUtilsTest, TestNullNPVariantToValue) { + NPObjectPointer v; + + NULL_TO_NPVARIANT(variant_); + EXPECT_TRUE(NPVariantToValue(&v, variant_)); + EXPECT_TRUE(NPObjectPointer() == v); + + BOOLEAN_TO_NPVARIANT(false, variant_); + EXPECT_FALSE(NPVariantToValue(&v, variant_)); +} + +TEST_F(NPUtilsTest, TestDerivedObjectNPVariantToValue) { + NPObjectPointer object = + NPCreateObject >(NULL); + NPObjectPointer > v; + + OBJECT_TO_NPVARIANT(object.Get(), variant_); + EXPECT_TRUE(NPVariantToValue(&v, variant_)); + EXPECT_EQ(object, v); +} + +TEST_F(NPUtilsTest, + TestDerivedObjectNPVariantToValueFailsIfValueHasDifferentType) { + NPObjectPointer object = + NPCreateObject >(NULL); + NPObjectPointer v; + + OBJECT_TO_NPVARIANT(object.Get(), variant_); + EXPECT_FALSE(NPVariantToValue(&v, variant_)); +} + +TEST_F(NPUtilsTest, TestBoolValueToNPVariant) { + ValueToNPVariant(true, &variant_); + EXPECT_TRUE(NPVARIANT_IS_BOOLEAN(variant_)); + EXPECT_TRUE(NPVARIANT_TO_BOOLEAN(variant_)); + + ValueToNPVariant(false, &variant_); + EXPECT_TRUE(NPVARIANT_IS_BOOLEAN(variant_)); + EXPECT_FALSE(NPVARIANT_TO_BOOLEAN(variant_)); +} + +TEST_F(NPUtilsTest, TestIntValueToNPVariant) { + ValueToNPVariant(7, &variant_); + EXPECT_TRUE(NPVARIANT_IS_INT32(variant_)); + EXPECT_EQ(7, NPVARIANT_TO_INT32(variant_)); +} + +TEST_F(NPUtilsTest, TestFloatValueToNPVariant) { + ValueToNPVariant(7.0f, &variant_); + EXPECT_TRUE(NPVARIANT_IS_DOUBLE(variant_)); + EXPECT_EQ(7.0, NPVARIANT_TO_DOUBLE(variant_)); +} + +TEST_F(NPUtilsTest, TestDoubleValueToNPVariant) { + ValueToNPVariant(7.0, &variant_); + EXPECT_TRUE(NPVARIANT_IS_DOUBLE(variant_)); + EXPECT_EQ(7.0, NPVARIANT_TO_DOUBLE(variant_)); +} + +TEST_F(NPUtilsTest, TestStringValueToNPVariant) { + ValueToNPVariant(std::string("hello"), &variant_); + EXPECT_TRUE(NPVARIANT_IS_STRING(variant_)); + EXPECT_EQ(std::string("hello"), + std::string(variant_.value.stringValue.UTF8Characters, + variant_.value.stringValue.UTF8Length)); +} + +TEST_F(NPUtilsTest, TestObjectValueToNPVariant) { + NPObjectPointer object = + NPCreateObject >(NULL); + + ValueToNPVariant(object, &variant_); + EXPECT_TRUE(NPVARIANT_IS_OBJECT(variant_)); + EXPECT_EQ(object.Get(), NPVARIANT_TO_OBJECT(variant_)); + + NPBrowser::get()->ReleaseVariantValue(&variant_); +} + +TEST_F(NPUtilsTest, TestNullValueToNPVariant) { + ValueToNPVariant(NPObjectPointer(), &variant_); + EXPECT_TRUE(NPVARIANT_IS_NULL(variant_)); +} + +TEST_F(NPUtilsTest, CanCopyObjectSmartVariant) { + NPObjectPointer object = + NPCreateObject >(NULL); + EXPECT_EQ(1, object->referenceCount); + { + SmartNPVariant v1(object); + EXPECT_EQ(2, object->referenceCount); + { + SmartNPVariant v2(v1); + EXPECT_EQ(3, object->referenceCount); + } + EXPECT_EQ(2, object->referenceCount); + } + EXPECT_EQ(1, object->referenceCount); +} + +TEST_F(NPUtilsTest, CanCopyStringSmartVariant) { + SmartNPVariant v1(std::string("hello")); + SmartNPVariant v2(v1); + std::string r; + EXPECT_TRUE(NPVariantToValue(&r, v2)); + EXPECT_EQ(std::string("hello"), r); + EXPECT_NE(v1.value.stringValue.UTF8Characters, + v2.value.stringValue.UTF8Characters); +} + +TEST_F(NPUtilsTest, CanReleaseSmartVariant) { + SmartNPVariant variant(std::string("hello")); + EXPECT_FALSE(variant.IsVoid()); + variant.Release(); + EXPECT_TRUE(variant.IsVoid()); +} + +template +class VariantMatcher : public testing::MatcherInterface { + public: + explicit VariantMatcher(const T& value) : value_(value) { + } + + virtual bool Matches(const NPVariant& variant) const { + T other_value; + return NPVariantToValue(&other_value, variant) && other_value == value_; + } + + virtual void DescribeTo(::std::ostream* os) const { + *os << "equals " << value_; + } + + virtual void DescribeNegationTo(::std::ostream* os) const { + *os << "does not equal " << value_; + } + + private: + T value_; +}; + +template +Matcher VariantMatches(const T& value) { + return MakeMatcher(new VariantMatcher(value)); +} + +TEST_F(NPUtilsTest, CanDetermineIfObjectHasMethod) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer object = + NPCreateObject >(NULL); + + EXPECT_CALL(*object, HasMethod(name)) + .WillOnce(Return(true)); + + EXPECT_TRUE(NPHasMethod(NULL, object, "foo")); +} + +TEST_F(NPUtilsTest, CanInvokeVoidMethodWithNativeTypes) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer object = + NPCreateObject >(NULL); + + VOID_TO_NPVARIANT(variant_); + + EXPECT_CALL(*object, Invoke(name, Pointee(VariantMatches(7)), 1, _)) + .WillOnce(DoAll(SetArgumentPointee<3>(variant_), + Return(true))); + + EXPECT_TRUE(NPInvokeVoid(NULL, object, "foo", 7)); +} + +TEST_F(NPUtilsTest, InvokeVoidMethodCanFail) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer object = + NPCreateObject >(NULL); + + VOID_TO_NPVARIANT(variant_); + + EXPECT_CALL(*object, Invoke(name, Pointee(VariantMatches(7)), 1, _)) + .WillOnce(DoAll(SetArgumentPointee<3>(variant_), + Return(false))); + + EXPECT_FALSE(NPInvokeVoid(NULL, object, "foo", 7)); +} + +TEST_F(NPUtilsTest, CanInvokeNonVoidMethodWithNativeTypes) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer object = + NPCreateObject >(NULL); + + DOUBLE_TO_NPVARIANT(1.5, variant_); + + EXPECT_CALL(*object, Invoke(name, Pointee(VariantMatches(7)), 1, _)) + .WillOnce(DoAll(SetArgumentPointee<3>(variant_), + Return(true))); + + double r; + EXPECT_TRUE(NPInvoke(NULL, object, "foo", 7, &r)); + EXPECT_EQ(1.5, r); +} + +TEST_F(NPUtilsTest, InvokeNonVoidMethodCanFail) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer object = + NPCreateObject >(NULL); + + DOUBLE_TO_NPVARIANT(1.5, variant_); + + EXPECT_CALL(*object, Invoke(name, Pointee(VariantMatches(7)), 1, _)) + .WillOnce(DoAll(SetArgumentPointee<3>(variant_), + Return(false))); + + double r; + EXPECT_FALSE(NPInvoke(NULL, object, "foo", 7, &r)); +} + +TEST_F(NPUtilsTest, InvokeNonVoidMethodFailsIfResultIsIncompatible) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer object = + NPCreateObject >(NULL); + + DOUBLE_TO_NPVARIANT(1.5, variant_); + + EXPECT_CALL(*object, Invoke(name, Pointee(VariantMatches(7)), 1, _)) + .WillOnce(DoAll(SetArgumentPointee<3>(variant_), + Return(true))); + + int r; + EXPECT_FALSE(NPInvoke(NULL, object, "foo", 7, &r)); +} + +TEST_F(NPUtilsTest, CanDetermineIfObjectHasProperty) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer object = + NPCreateObject >(NULL); + + EXPECT_CALL(*object, HasProperty(name)) + .WillOnce(Return(true)); + + EXPECT_TRUE(NPHasProperty(NULL, object, "foo")); +} + +TEST_F(NPUtilsTest, CanGetPropertyValue) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer object = + NPCreateObject >(NULL); + + DOUBLE_TO_NPVARIANT(1.5, variant_); + + EXPECT_CALL(*object, GetProperty(name, _)) + .WillOnce(DoAll(SetArgumentPointee<1>(variant_), + Return(true))); + + double r; + EXPECT_TRUE(NPGetProperty(NULL, object, "foo", &r)); +} + +TEST_F(NPUtilsTest, NPGetPropertyReportsFailureIfResultTypeIsDifferent) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer object = + NPCreateObject >(NULL); + + DOUBLE_TO_NPVARIANT(1.5, variant_); + + EXPECT_CALL(*object, GetProperty(name, _)) + .WillOnce(DoAll(SetArgumentPointee<1>(variant_), + Return(true))); + + bool r; + EXPECT_FALSE(NPGetProperty(NULL, object, "foo", &r)); +} + +TEST_F(NPUtilsTest, NPGetPropertyReportsFailureFromGetProperty) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer object = + NPCreateObject >(NULL); + + EXPECT_CALL(*object, GetProperty(name, _)) + .WillOnce(Return(false)); + + double r; + EXPECT_FALSE(NPGetProperty(NULL, object, "foo", &r)); +} + +TEST_F(NPUtilsTest, CanSetPropertyValue) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer object = + NPCreateObject >(NULL); + + EXPECT_CALL(*object, SetProperty(name, Pointee(VariantMatches(1.5)))) + .WillOnce(Return(true)); + + EXPECT_TRUE(NPSetProperty(NULL, object, "foo", 1.5)); +} + +TEST_F(NPUtilsTest, NPSetPropertyReportsFailureFromSetProperty) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer object = + NPCreateObject >(NULL); + + EXPECT_CALL(*object, SetProperty(name, Pointee(VariantMatches(1.5)))) + .WillOnce(Return(false)); + + EXPECT_FALSE(NPSetProperty(NULL, object, "foo", 1.5)); +} + +TEST_F(NPUtilsTest, CanRemovePropertyValue) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer object = + NPCreateObject >(NULL); + + EXPECT_CALL(*object, RemoveProperty(name)) + .WillOnce(Return(true)); + + EXPECT_TRUE(NPRemoveProperty(NULL, object, "foo")); +} + +} // namespace gpu_plugin diff --git a/o3d/gpu_plugin/np_utils/webkit_browser.h b/o3d/gpu_plugin/np_utils/webkit_browser.h new file mode 100644 index 0000000..e45e65f --- /dev/null +++ b/o3d/gpu_plugin/np_utils/webkit_browser.h @@ -0,0 +1,117 @@ +// Copyright (c) 2006-2008 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 O3D_GPU_PLUGIN_NP_UTILS_WEBKIT_BROWSER_H_ +#define O3D_GPU_PLUGIN_NP_UTILS_WEBKIT_BROWSER_H_ + +// TODO(apatrick): This does not belong in np_utils. np_utils should not be +// dependent on WebKit (and it isn't - that's why the member functions are +// inline). + +#include + +#include "o3d/gpu_plugin/np_utils/np_browser.h" +#include "WebKit/api/public/WebBindings.h" + +typedef struct _NPNetscapeFuncs NPNetscapeFuncs; +typedef struct _NPChromiumFuncs NPChromiumFuncs; + +namespace gpu_plugin { + +// This class implements NPBrowser for the WebKit WebBindings. +class WebKitBrowser : public NPBrowser { + public: + WebKitBrowser(): NPBrowser(NULL) { + } + + // Standard functions from NPNetscapeFuncs. + + virtual NPIdentifier GetStringIdentifier(const NPUTF8* name) { + return WebKit::WebBindings::getStringIdentifier(name); + } + + virtual void* MemAlloc(size_t size) { + return malloc(size); + } + + virtual void MemFree(void* p) { + free(p); + } + + virtual NPObject* CreateObject(NPP npp, const NPClass* cl) { + return WebKit::WebBindings::createObject(npp, const_cast(cl)); + } + + virtual NPObject* RetainObject(NPObject* object) { + return WebKit::WebBindings::retainObject(object); + } + + virtual void ReleaseObject(NPObject* object) { + WebKit::WebBindings::releaseObject(object); + } + + virtual void ReleaseVariantValue(NPVariant* variant) { + WebKit::WebBindings::releaseVariantValue(variant); + } + + virtual bool HasProperty(NPP npp, + NPObject* object, + NPIdentifier name) { + return WebKit::WebBindings::hasProperty(npp, object, name); + } + + virtual bool GetProperty(NPP npp, + NPObject* object, + NPIdentifier name, + NPVariant* result) { + return WebKit::WebBindings::getProperty(npp, object, name, result); + } + + virtual bool SetProperty(NPP npp, + NPObject* object, + NPIdentifier name, + const NPVariant* result) { + return WebKit::WebBindings::setProperty(npp, object, name, result); + } + + virtual bool RemoveProperty(NPP npp, + NPObject* object, + NPIdentifier name) { + return WebKit::WebBindings::removeProperty(npp, object, name); + } + + virtual bool HasMethod(NPP npp, + NPObject* object, + NPIdentifier name) { + return WebKit::WebBindings::hasMethod(npp, object, name); + } + + virtual bool Invoke(NPP npp, + NPObject* object, + NPIdentifier name, + const NPVariant* args, + uint32_t num_args, + NPVariant* result) { + return WebKit::WebBindings::invoke(npp, object, name, args, num_args, + result); + } + + virtual NPObject* GetWindowNPObject(NPP npp) { + NPObject* window; + if (NPERR_NO_ERROR == NPN_GetValue(npp, + NPNVWindowNPObject, + &window)) { + return window; + } else { + return NULL; + } + } + + private: + DISALLOW_COPY_AND_ASSIGN(WebKitBrowser); +}; + +} // namespace gpu_plugin + +#endif // O3D_GPU_PLUGIN_NP_UTILS_WEBKIT_BROWSER_H_ diff --git a/o3d/plugin/cross/o3d_glue.cc b/o3d/plugin/cross/o3d_glue.cc index 075ca5d..f2cfb4f 100644 --- a/o3d/plugin/cross/o3d_glue.cc +++ b/o3d/plugin/cross/o3d_glue.cc @@ -40,9 +40,9 @@ #include "core/cross/renderer.h" #include "core/cross/client_info.h" #include "core/cross/command_buffer/display_window_cb.h" -#include "gpu/np_utils/np_headers.h" -#include "gpu/np_utils/np_object_pointer.h" -#include "gpu/np_utils/np_utils.h" +#include "gpu_plugin/np_utils/np_headers.h" +#include "gpu_plugin/np_utils/np_object_pointer.h" +#include "gpu_plugin/np_utils/np_utils.h" #include "plugin/cross/o3d_glue.h" #include "plugin/cross/config.h" #include "plugin/cross/stream_manager.h" diff --git a/o3d/plugin/plugin.gyp b/o3d/plugin/plugin.gyp index c128c70..10cb1c4 100644 --- a/o3d/plugin/plugin.gyp +++ b/o3d/plugin/plugin.gyp @@ -50,7 +50,7 @@ '../../v8/tools/gyp/v8.gyp:v8', '../core/core.gyp:o3dCore', '../core/core.gyp:o3dCorePlatform', - '../gpu/gpu.gyp:np_utils', + '../gpu_plugin/gpu_plugin.gyp:np_utils', '../import/archive.gyp:o3dArchive', '../utils/utils.gyp:o3dUtils', '../../native_client/src/shared/imc/imc.gyp:google_nacl_imc', diff --git a/o3d/plugin/win/main_win.cc b/o3d/plugin/win/main_win.cc index 13cfc12..785e771 100644 --- a/o3d/plugin/win/main_win.cc +++ b/o3d/plugin/win/main_win.cc @@ -54,7 +54,7 @@ #if defined(RENDERER_CB) #include "core/cross/command_buffer/renderer_cb.h" #include "core/cross/command_buffer/display_window_cb.h" -#include "gpu/gpu_plugin/command_buffer.h" +#include "gpu_plugin/command_buffer.h" #endif using glue::_o3d::PluginObject; diff --git a/o3d/tests/common/win/testing_common.cc b/o3d/tests/common/win/testing_common.cc index ba7c402..5479719 100644 --- a/o3d/tests/common/win/testing_common.cc +++ b/o3d/tests/common/win/testing_common.cc @@ -53,8 +53,8 @@ #if defined(RENDERER_CB) #include "core/cross/command_buffer/renderer_cb.h" #include "core/cross/command_buffer/display_window_cb.h" -#include "gpu/gpu_plugin/command_buffer.h" -#include "gpu/np_utils/np_browser_stub.h" +#include "gpu_plugin/command_buffer.h" +#include "gpu_plugin/np_utils/np_browser_stub.h" #endif using o3d::DisplayWindowWindows; diff --git a/o3d/tests/tests.gyp b/o3d/tests/tests.gyp index 1942b35..27e48a6 100644 --- a/o3d/tests/tests.gyp +++ b/o3d/tests/tests.gyp @@ -105,16 +105,16 @@ ['renderer == "cb"', { 'dependencies': [ - '../gpu/gpu.gyp:np_utils', + '../gpu_plugin/gpu_plugin.gyp:np_utils', ] }, ], ['renderer == "cb" and cb_service != "remote"', { 'dependencies': [ - '../gpu/gpu.gyp:command_buffer_client_test', - '../gpu/gpu.gyp:command_buffer_common_test', - '../gpu/gpu.gyp:command_buffer_service_test', + '../command_buffer/command_buffer.gyp:command_buffer_client_test', + '../command_buffer/command_buffer.gyp:command_buffer_common_test', + '../command_buffer/command_buffer.gyp:command_buffer_service_test', ] }, ], -- cgit v1.1